Skip to content

Commit ad306d7

Browse files
committed
changed way to deal with rotation. Rot3D still allocates too much
1 parent 355b9ce commit ad306d7

File tree

2 files changed

+91
-56
lines changed

2 files changed

+91
-56
lines changed

src/Setup_geometry.jl

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ end
454454
# Internal function that rotates the coordinates
455455
function Rot3D!(X,Y,Z, StrikeAngle, DipAngle)
456456

457+
#=
457458
# rotation matrixes
458459
roty = [cosd(-DipAngle) 0 sind(-DipAngle) ; 0 1 0 ; -sind(-DipAngle) 0 cosd(-DipAngle)];
459460
rotz = [cosd(StrikeAngle) -sind(StrikeAngle) 0 ; sind(StrikeAngle) cosd(StrikeAngle) 0 ; 0 0 1]
@@ -466,10 +467,39 @@ function Rot3D!(X,Y,Z, StrikeAngle, DipAngle)
466467
Y[i] = CoordRot[2];
467468
Z[i] = CoordRot[3];
468469
end
470+
=#
471+
472+
# precompute trigonometric functions (expensive!)
473+
sindStrikeAngle, cosStrikeAngle = sincosd(StrikeAngle)
474+
sinDipAngle, cosDipAngle = sincosd(-DipAngle) # note the minus here to be consistent with the earlier version of the code
475+
for i in eachindex(X)
476+
X[i], Y[i], Z[i] = Rot3D(X[i], Y[i], Z[i], cosStrikeAngle, sindStrikeAngle, cosDipAngle, sinDipAngle)
477+
end
469478

470479
return nothing
471480
end
472481

482+
"""
483+
xrot, yrot, zrot = Rot3D(X::Number,Y::Number,Z::Number, cosStrikeAngle, sindStrikeAngle, cosDipAngle, sinDipAngle)
484+
485+
Perform rotation for a point in 3D space
486+
"""
487+
function Rot3D(X::Number,Y::Number,Z::Number, cosStrikeAngle, sindStrikeAngle, cosDipAngle, sinDipAngle)
488+
489+
# rotation matrixes
490+
#roty = [cosd(-DipAngle) 0 sind(-DipAngle) ; 0 1 0 ; -sind(-DipAngle) 0 cosd(-DipAngle)];
491+
roty = [cosDipAngle 0 sinDipAngle ; 0 1 0 ; -sinDipAngle 0 cosDipAngle]; # note that dip-angle is changed from before!
492+
rotz = [cosStrikeAngle -sindStrikeAngle 0 ; sindStrikeAngle cosStrikeAngle 0 ; 0 0 1]
493+
494+
CoordVec = [X, Y, Z]
495+
CoordRot = rotz*CoordVec;
496+
CoordRot = roty*CoordRot;
497+
498+
return CoordRot[1], CoordRot[2], CoordRot[3]
499+
end
500+
501+
502+
473503
"""
474504
makeVolcTopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64,
475505
base=0.0m, background=nothing)
@@ -1061,19 +1091,19 @@ Parameters
10611091
end
10621092

10631093
"""
1064-
Compute_ThermalStructure(Temp, X, Y, Z, s::McKenzie_subducting_slab)
1094+
Compute_ThermalStructure(Temp, X, Y, Z, Phase, s::McKenzie_subducting_slab)
10651095
10661096
Compute the temperature field of a `McKenzie_subducting_slab`. Uses the analytical solution
10671097
of McKenzie (1969) ["Speculations on the consequences and causes of plate motions"]. The functions assumes
10681098
that the bottom of the slab is the coordinate Z=0. Internally the function shifts the coordinate.
10691099
Parameters
10701100
=============================
10711101
Temp Temperature array
1072-
X X Array
1073-
Y Y Array
1074-
Z Z Array
1075-
Phase Phase array
1076-
s McKenzie_subducting_slab
1102+
- `X` X Array
1103+
- `Y` Y Array
1104+
- `Z` Z Array
1105+
- `Phase` Phase array
1106+
- `s` McKenzie_subducting_slab
10771107
10781108
"""
10791109
function Compute_ThermalStructure(Temp, X, Y, Z,Phase, s::McKenzie_subducting_slab)
@@ -1181,21 +1211,18 @@ function Compute_ThermalStructure(Temp, X, Y, Z, Phase, s::LinearWeightedTempera
11811211
end
11821212

11831213

1184-
abstract type Trench_slab end
1214+
abstract type AbstractTrenchSlab end
11851215

11861216
"""
11871217
Trench structure
1188-
[Dev Comments]: I wanted to leave some fields for future implementation. For example, if you take an arbitrary path
1189-
that can be projected to a linear segment, an user can discretize it, and can create an arbitrary trench geometry.
1190-
The type of bending can be further customize, but certain geometry can be tricky with the actual finding slab. In the future,
1191-
we can introduce structures that handle that and use multiple dispatch of the function finding slab to handle the most tricky geometries
1218+
1219+
Structure that defines the geometry of the trench and the slab.
11921220
11931221
Parameters
11941222
===
11951223
1196-
- `n_seg_xy` - Number of segment through which the trench strike is discretize (for now, is one by default)
1197-
- `A` - The first point of the trench | The coordinate will be transformed and rotated as a function of the
1198-
- `B` - The second point of the trench | slope of the segment, and w.r.t. to the point A.
1224+
- `Start` - Start of the trench (`x`,`y`) coordinates
1225+
- `End` - End of the trench (`x`,`y`) coordinates
11991226
- `n_seg` - The number of segment through which the slab is discretize along the dip
12001227
- `L0` - The length of the slab
12011228
- `D0` - The thickness of the slab
@@ -1210,26 +1237,29 @@ Parameters
12101237
- `type_bending` - is the type of bending angle of the slab [`:Linear`, `:Ribe`].
12111238
The angle of slab changes as a function of `l` (∈ [0,L0]). `l` is the actual distance along the slab length from
12121239
the trench.
1213-
In case of `:Linear` θ(l) = ((θ_max - 0.0)/(Lb-0))*l;
1214-
In case of `:Ribe` θ(l) = θ_max*l^2*((3*Lb-2*l))/(Lb^3) (ref*);
1215-
(ref*) Ribe 2010 [Bending mechanics and mode selection in free subduction: a thin-sheet analysis]
1240+
In case:
1241+
- `:Linear`
1242+
```math θ(l) = ((θ_max - 0.0)/(Lb-0))*l ```;
1243+
- `:Ribe`
1244+
```math θ(l) = θ_max*l^2*((3*Lb-2*l))/(Lb^3) ```;
1245+
which is taken from Ribe 2010 [Bending mechanics and mode selection in free subduction: a thin-sheet analysis]
1246+
12161247
For l>Lb, θ(l) = θ_max;
12171248
# [Dev] Potential development: using the elastic bending differential equation and numerically integrate
12181249
#- `WZ` - Thickness of the weakzone.
12191250
12201251
"""
1221-
@with_kw_noshow mutable struct Trench <: Trench_slab
1222-
n_seg_xy::Int64 = 1 # Number of segment of the trench plane view (for now, 1 segment)
1223-
A::Array{Float64} = (0.0,0.0) # Coordinate 1 {set of coordinates}
1224-
B::Array{Float64} = (0.0,1.0) # Coordinate 2 {set of coordinates}
1225-
n_seg::Int64 = 50 # definition segment
1226-
L0:: Float64 = 400 # length of the slab
1227-
D0:: Float64 = 100 # thickness of the slab
1228-
Lb:: Float64 = 200 # Length at which all the bending is happening (Lb<=L0)
1229-
θ_max::Float64 = 45 # max bending angle, (must be converted into radians)
1230-
direction::Float64 = 1.0 # Direction of the bending angle.
1231-
d_decoupling:: Float64 = 100 # decoupling depth of the slab
1232-
type_bending::Symbol = :Ribe # Mode Ribe | Linear | Customize
1252+
@with_kw_noshow mutable struct Trench{Nseg} <: AbstractTrenchSlab
1253+
Start::NTuple{Nseg,Float64} = (0.0,0.0) # Start (x,y) coordinates of trench (in mapview)
1254+
End::NTuple{Nseg,Float64} = (0.0,1.0) # End (x,y) coordinates of trench (in mapview)
1255+
n_seg::Int64 = 50 # number of segments in downdip direction
1256+
L0:: Float64 = 400.0 # length of the slab
1257+
D0:: Float64 = 100.0 # thickness of the slab
1258+
Lb:: Float64 = 200.0 # Length at which all the bending is happening (Lb<=L0)
1259+
θ_max::Float64 = 45.0 # max bending angle, (must be converted into radians)
1260+
direction::Float64 = 1.0 # Direction of the bending angle.
1261+
d_decoupling:: Float64 = 100 # decoupling depth of the slab
1262+
type_bending::Symbol = :Ribe # Mode Ribe | Linear | Customize
12331263
end
12341264

12351265
"""
@@ -1249,7 +1279,7 @@ Next, it compute the coordinates assuming that the trench is at 0.0, and assumin
12491279
"""
12501280
function compute_slab_surface(trench::Trench)
12511281

1252-
@unpack D0, L0, n_seg, Lb, θ_max, n_seg_xy, A, B, type_bending, direction = trench;
1282+
@unpack D0, L0, n_seg, Lb, θ_max, type_bending, direction = trench;
12531283

12541284
# Convert θ_max into radians
12551285
θ_max *= π / 180;
@@ -1325,36 +1355,37 @@ function compute_bending_angle(θ_max::Float64,Lb::Float64,l::Float64,type::Symb
13251355
return θ
13261356
end
13271357

1358+
#=
13281359
"""
13291360
transform_coordinate!(X,Y,Z,XT,YT,A,B,direction)
13301361
13311362
Transform the coordinate such that the new x axis (XT) is parallel to the segment A-B of the slab. The rotation is
13321363
anticlockwise. If θ_max is negative, it multiplies YT with the sign of the angle, changing the dip of the subduction.
13331364
It returns Bn -> which is the point B coordinate in the new transformed system.
13341365
"""
1335-
function transform_coordinate!(X,Y,Z,XT,YT,A,B,direction)
1366+
function transform_coordinate!(X,Y,Z,XT,YT,Start,End,direction)
13361367
13371368
# find the slope of AB points
1338-
s = (B[2]-A[2])/(B[1]-A[1])
1369+
s = (End[2]-Start[2])/(End[1]-Start[1])
13391370
13401371
angle_rot = -atand(s);
13411372
13421373
# Shift the origin
1343-
XT .= X .-A[1];
1344-
YT .= Y .-A[2];
1374+
XT .= X .- Start[1];
1375+
YT .= Y .- Start[2];
13451376
13461377
Bn = zeros(3);
13471378
1348-
Bn[1] = B[1]-A[1];
1379+
Bn[1] = End[1]-Start[1];
13491380
1350-
Bn[2] = B[2]-A[2];
1381+
Bn[2] = End[2]-Start[2];
13511382
13521383
Bn[3] = 0.0;
13531384
13541385
# Transform the coordinates
13551386
Rot3D!(XT,YT,Z, angle_rot, 0);
13561387
1357-
YT .= YT*direction;
1388+
YT .*= direction;
13581389
13591390
#Find Point B in the new coordinate system
13601391
roty = [cosd(-0) 0 sind(-0) ; 0 1 0 ; -sind(-0) 0 cosd(-0)];
@@ -1365,22 +1396,25 @@ function transform_coordinate!(X,Y,Z,XT,YT,A,B,direction)
13651396
13661397
return Bn
13671398
end
1399+
=#
13681400

13691401
"""
1370-
find_slab!(ls, d, X,Y,Z, θ_max, A, B, Top, Bottom, seg_slab, D0, L0)
1402+
find_slab!(ls, d, X,Y,Z, Start, End, Top, Bottom, seg_slab, D0, L0)
13711403
13721404
Function that finds the perpendicular distance to the top and bottom of the slab `d`, and the current length of the slab `l`.
13731405
1374-
13751406
"""
1376-
function find_slab!(ls, d, X,Y,Z, θ_max, A,B,Top,Bottom,seg_slab,D0,L0,direction)
1407+
function find_slab!(ls, d, X,Y,Z, Start, End,Top,Bottom,seg_slab,D0,L0,direction)
13771408

1378-
# Create the XT,YT
1379-
XT = zero(X);
1380-
YT = zero(Y);
1409+
# Perform rotation of 3D coordinates along the angle from Start -> End:
1410+
Xrot = X .- Start[1];
1411+
Yrot = Y .- Start[2];
1412+
StrikeAngle = -atand((End[2]-Start[2])/(End[1]-Start[1]))
1413+
Rot3D!(Xrot,Yrot,Z, StrikeAngle, 0.0)
13811414

1382-
# Function to transform the coordinate
1383-
xb = transform_coordinate!(X,Y,Z,XT,YT,A,B,direction);
1415+
xb = Rot3D(End[1]-Start[1],End[2]-Start[2], 0.0, cosd(StrikeAngle), sind(StrikeAngle), 1.0, 0.0)
1416+
1417+
#xb1 = transform_coordinate!(X,Y,Z,Xrot,Yrot,Start,End,direction);
13841418

13851419
# dl
13861420
dl = L0/seg_slab;
@@ -1409,10 +1443,10 @@ function find_slab!(ls, d, X,Y,Z, θ_max, A,B,Top,Bottom,seg_slab,D0,L0,directio
14091443
zmin = minimum(poly_z);
14101444
zmax = maximum(poly_z);
14111445

1412-
ind_s = findall(0.0.<= XT.<= xb[1] .&& ymin .<= YT .<= ymax .&& zmin .<= Z .<= zmax);
1446+
ind_s = findall(0.0.<= Xrot.<= xb[1] .&& ymin .<= Yrot .<= ymax .&& zmin .<= Z .<= zmax);
14131447

14141448
# Find the particles
1415-
yp = YT[ind_s];
1449+
yp = Yrot[ind_s];
14161450

14171451
zp = Z[ind_s];
14181452

@@ -1442,7 +1476,7 @@ function find_slab!(ls, d, X,Y,Z, θ_max, A,B,Top,Bottom,seg_slab,D0,L0,directio
14421476

14431477
for ip = 1:particle_n
14441478

1445-
point_ = [YT[ind_seg[ip]],Z[ind_seg[ip]]];
1479+
point_ = [Yrot[ind_seg[ip]],Z[ind_seg[ip]]];
14461480

14471481
d[ind_seg[ip]] = ScatteredInterpolation.evaluate(itp1,point_)[1];
14481482
ls[ind_seg[ip]] = ScatteredInterpolation.evaluate(itp2,point_)[1];
@@ -1459,10 +1493,10 @@ end
14591493
Internal routine which finds distance perpendicular (`d`) and along (`ls`) the slab, as specified in `trench`.
14601494
"""
14611495
function find_slab_distance!(ls, d, trench, Top, Bottom, X,Y,Z)
1462-
@unpack D0, L0, n_seg, Lb, θ_max, n_seg_xy, A, B, type_bending, direction = trench;
1496+
@unpack D0, L0, n_seg, Start, End, direction = trench;
14631497

14641498
# Finds the distance to the slab
1465-
GeophysicalModelGenerator.find_slab!(ls, d, X,Y,Z, θ_max,A,B,Top,Bottom,n_seg,D0,L0,direction);
1499+
GeophysicalModelGenerator.find_slab!(ls, d, X,Y,Z, Start,End, Top,Bottom,n_seg,D0,L0,direction);
14661500

14671501
return nothing
14681502
end
@@ -1532,7 +1566,7 @@ function addSlab!(Phase, Temp, Grid::AbstractGeneralGrid, trench::Trench;
15321566
Temp[ind] = Compute_ThermalStructure(Temp[ind], ls[ind], Y[ind], d[ind], Phase[ind],T);
15331567
end
15341568

1535-
# Set the phase. Different routines are available for that - see below.
1569+
# Set the phase
15361570
Phase[ind] = Compute_Phase(Phase[ind], Temp[ind], ls[ind], Y[ind], d[ind], phase)
15371571

15381572
# Place holder of the weak zone: it is simply using the find slab routine, and cutting it at d_decoupling.

test/test_setup_geometry.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ X,Y,Z = XYZGrid(x, y, z);
224224
Phase = ones(Int32,size(Cart));
225225
Temp = fill(1350.0,size(Cart));
226226

227-
t1 = Trench(n_seg_xy=1, A = [400.0,400.0],B = [800.0,800.0],θ_max = 45.0, direction = 1.0, n_seg = 50, L0 = 600.0, D0 = 80.0, Lb = 500.0,d_decoupling = 100.0, type_bending =:Ribe)
227+
t1 = Trench(Start = (400.0,400.0), End = (800.0,800.0),θ_max = 45, direction = 1.0, n_seg = 50, L0 = 600.0, D0 = 80.0, Lb = 500.0,d_decoupling = 100.0, type_bending =:Ribe)
228228
@test t1.θ_max == 45.0
229229
@test t1.D0 == 80.0
230230
@test t1.L0 == 600.0
@@ -235,26 +235,27 @@ TsHC = HalfspaceCoolingTemp(Tsurface=20.0, Tmantle=1350, Age=30, Adiabat=0.4)
235235
temp = TsHC;
236236

237237
addSlab!(Phase,Temp,Cart, t1, phase=phase, T = TsHC)
238+
@test sum(Temp) 2.7987343685251493e9
238239

239240
Data_Final = CartData(X,Y,Z,(Phase=Phase,Temp=Temp))
240-
241+
#Write_Paraview(Data_Final, "Data_Final");
241242

242243

243244
Phase = ones(Int32,size(Cart));
244245
Temp = fill(1350.0,size(Cart));
245246
TsMK = McKenzie_subducting_slab(Tsurface = 20.0, Tmantle = 1350.0, v_cm_yr = 4.0, Adiabat = 0.0)
246247
temp = TsMK
247-
t1 = Trench(n_seg_xy=1, A = [400.0,400.0],B = [800.0,800.0],θ_max = 90.0, direction = 1.0, n_seg = 50, L0 = 600.0, D0 = 80.0, Lb = 500.0,d_decoupling = 100.0, type_bending =:Ribe)
248248

249249

250250
Phase = ones(Int32,size(Cart));
251251
Temp = fill(1350.0,size(Cart));
252252
TsHC = HalfspaceCoolingTemp(Tsurface=20.0, Tmantle=1350, Age=120, Adiabat=0.4)
253253
TsMK = McKenzie_subducting_slab(Tsurface = 20.0, Tmantle = 1350.0, v_cm_yr = 4.0, Adiabat = 0.0)
254254
T_slab = LinearWeightedTemperature(crit_dist=600, F1=TsHC, F2=TsMK);
255-
t1 = Trench(n_seg_xy=1, A = [400.0,400.0],B = [800.0,800.0],θ_max = 90.0, direction = 1.0, n_seg = 50, L0 = 600.0, D0 = 80.0, Lb = 500.0,d_decoupling = 100.0, type_bending =:Ribe)
255+
phase = LithosphericPhases(Layers=[5 7 88], Phases = [2 3 4], Tlab=nothing)
256+
t1 = Trench(Start = (400.0,400.0), End = (800.0,800.0),θ_max = 90.0, direction = 1.0, n_seg = 50, L0 = 600.0, D0 = 80.0, Lb = 500.0,d_decoupling = 100.0, type_bending =:Ribe)
256257

257258
addSlab!(Phase,Temp,Cart, t1, phase=phase, T = TsHC)
258-
259+
@test sum(Temp) 2.7836771215872355e9
259260

260261
Data_Final = CartData(X,Y,Z,(Phase=Phase,Temp=Temp))

0 commit comments

Comments
 (0)