Skip to content

Commit e915540

Browse files
authored
Merge pull request #73 from TatjanaWeiler/main
Add Polygon structure in pseudo3D
2 parents b3d982c + 9ad2943 commit e915540

File tree

6 files changed

+221
-9
lines changed

6 files changed

+221
-9
lines changed

docs/make.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,17 @@ makedocs(;
101101
"16 - Create movies" => "man/tutorial_time_Seismicity.md",
102102
"17 - Fault Density Map" => "man/Tutorial_FaultDensity.md",
103103
"18 - Alpine data integration" => "man/Tutorial_AlpineData.md",
104-
"19 - Jura tutorial" => "man/Tutorial_Jura.md"
104+
"19 - Jura tutorial" => "man/Tutorial_Jura.md",
105+
"20 - Build geometry from polygons" => "man/tutorial_Polygon_structures.md"
105106
],
106107
"User Guide" => Any[
107108
"Installation" => "man/installation.md",
108109
"Data Structures" => "man/datastructures.md",
109110
"Data Import" => "man/dataimport.md",
110111
"Projection" => "man/projection.md",
111-
"Surfaces" => "man/surfaces.md",
112112
"Paraview output" => "man/paraview_output.md",
113113
"Paraview collection" => "man/paraview_collection.md",
114+
"Surfaces" => "man/surfaces.md",
114115
"Tools" => "man/tools.md",
115116
"Visualisation" => "man/visualise.md",
116117
"Gravity code" => "man/gravity_code.md",
72.3 KB
Loading
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Adding complex geometries to a model setup including sedimentary basins, lithospheric thinning and an accretionary prism
2+
3+
4+
## Goal
5+
6+
This tutorial visualizes simplified geological as it is done here for a passive margin where lithospheric thinning, sedimentary basin and accretionary prism occur. The simplification is based on a polygon structure for a pseudo-3D model. While the structure can have a random shape in the `x`- and `z`-direction, in the `y`-direction only the extent is variable.
7+
8+
## Steps
9+
10+
#### 1. Set up your simplified background model
11+
Before adding specific geological features, a general simplified model setup is necessary. The construction is made by using the `addBox!` function. For the model the discontinuities are in 15, 45, 145, and 945 km depth.
12+
13+
```julia
14+
using GeophysicalModelGenerator
15+
16+
# number of cells in every direction
17+
nx = 100
18+
ny = 100
19+
nz = 200
20+
21+
# define domain size
22+
x = LinRange(0.0,800.0,nx)
23+
y = LinRange(0.0,800.0,ny)
24+
z = LinRange(-660,50,nz)
25+
Cart = CartData(XYZGrid(x, y, z))
26+
27+
# initialize phase and temperature matrix
28+
Phase = ones(Int32,size(X))
29+
Temp = ones(Float64,size(X))*1350
30+
31+
# add different phases: crust->2, Mantle Lithosphere->3 Mantle->1
32+
AddBox!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(-800.0,0.0), phase = LithosphericPhases(Layers=[15 30 100 800], Phases=[2 3 1 5], Tlab=1300 ), T=LinearTemp(Ttop=20, Tbot=1600))
33+
34+
# add air phase 0
35+
AddBox!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(0.0,50.0), phase = ConstantPhase(0), T=ConstantTemp(20.0))
36+
```
37+
38+
39+
#### 2. Add polygon structure
40+
To include the geological structures of a passive margin into the model, we use polygons for depths of up to 150 km. In the example, the sediment basin shows a more trapezoidal (2D in `x`-/`z`-direction) shape, while the thinning of the plate has a more triangular (2D in `x`-/`z`-direction). More complex structures can be build using arbitrarily sized polygons in `x`- and `z`-direction, wheraes in the `y`-direction only the length can be varied (specified by two values). The `x`- and `z`-values of the points need to be in the same order for selecting the correct point (P1(1/3), P2(2/2) --> xlim(1,2), ylim(3,2)).
41+
42+
43+
```julia
44+
# xlim: x-coordinates of the points, same ordering as zlim
45+
# zlim: z-coordinates of the points, same ordering as xlim
46+
# ylim: limits the object within the two ylim values
47+
# unlimited number of points possible to create the polygon
48+
49+
# add sediment basin
50+
addPolygon!(Phase, Temp, Cart; xlim=[0.0,0.0, 160.0, 200.0],ylim=[100.0,300.0], zlim=[0.0,-10.0,-20.0,0.0], phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30));
51+
52+
# add thinning of the continental crust attached to the slab and its thickness
53+
addPolygon!(Phase, Temp, Cart; xlim=[0.0, 200.0, 0.0],ylim=[500.0,800.0], zlim=[-100.0,-150.0,-150.0], phase = ConstantPhase(5), T=LinearTemp(Ttop=1000, Tbot=1100));
54+
55+
# add accretionary prism
56+
addPolygon!(Phase, Temp, Cart; xlim=[800.0, 600.0, 800.0],ylim=[100.0,800.0], zlim=[0.0,0.0,-60.0], phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30));
57+
```
58+
59+
#### 3. Export final model setup to a paraview file
60+
For visualisation and comparison to actual measured data, the mode setup is saved to a paraview file.
61+
62+
```julia
63+
# # Save data to paraview:
64+
Data_Final = CartData(X,Y,Z,(Phase=Phase,Temp=Temp));
65+
Write_Paraview(Data_Final, "Sedimentary_basin");
66+
```
67+
68+
After importing and looking at the file to paraview, some unresolved areas might be visible as they are visible in this model. That is due to the resolution and shape of the polygon. To reduce those artefacts an increase in resolution or a change of the polygon angle might help.
69+
70+
![Tutorial_Polygon_structures](../assets/img/Tutorial_Polygon_structures.png)
71+
72+
If you want to run the entire example, you can find the .jl code [here](https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/tutorial/Tutorial_polygon_geometry.jl)

src/Setup_geometry.jl

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Base: show
1111
# These are routines that help to create input geometries, such as slabs with a given angle
1212
#
1313

14-
export AddBox!, AddSphere!, AddEllipsoid!, AddCylinder!, AddLayer!, addSlab!, addStripes!,
14+
export AddBox!, AddSphere!, AddEllipsoid!, AddCylinder!, AddLayer!, addPolygon!, addSlab!, addStripes!,
1515
makeVolcTopo,
1616
ConstantTemp, LinearTemp, HalfspaceCoolingTemp, SpreadingRateTemp, LithosphericTemp,
1717
ConstantPhase, LithosphericPhases,
@@ -571,6 +571,81 @@ function Rot3D!(X,Y,Z, StrikeAngle, DipAngle)
571571
return nothing
572572
end
573573

574+
575+
576+
"""
577+
addPolygon!(Phase, Temp, Grid::AbstractGeneralGrid; xlim::Vector(), ylim=Vector(2), zlim=Vector(), phase = ConstantPhase(1), T=nothing )
578+
579+
Adds a polygon with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models
580+
581+
Parameters
582+
====
583+
- `Phase` - Phase array (consistent with Grid)
584+
- `Temp` - Temperature array (consistent with Grid)
585+
- `Grid` - Grid structure (usually obtained with ReadLaMEM_InputFile)
586+
- `xlim` - `x`-coordinate of the polygon points, same ordering as zlim, number of points unlimited
587+
- `ylim` - `y`-coordinate, limitation in length possible (two values (start and stop))
588+
- `zlim` - `z`-coordinate of the polygon points, same ordering as xlim, number of points unlimited
589+
- `phase` - specifies the phase of the box. See `ConstantPhase()`
590+
- `T` - specifies the temperature of the box. See `ConstantTemp()`,`LinearTemp()`,`HalfspaceCoolingTemp()`,`SpreadingRateTemp()`
591+
592+
Example
593+
========
594+
595+
Polygon with constant phase and temperature:
596+
597+
```julia
598+
julia> Grid = ReadLaMEM_InputFile("test_files/SaltModels.dat")
599+
LaMEM Grid:
600+
nel : (32, 32, 32)
601+
marker/cell : (3, 3, 3)
602+
markers : (96, 96, 96)
603+
x ϵ [-3.0 : 3.0]
604+
y ϵ [-2.0 : 2.0]
605+
z ϵ [-2.0 : 0.0]
606+
julia> Phases = zeros(Int32, size(Grid.X));
607+
julia> Temp = zeros(Float64, size(Grid.X));
608+
julia> addPolygon!(Phase, Temp, Cart; xlim=(0.0,0.0, 1.6, 2.0),ylim=(0.0,0.8), zlim=(0.0,-1.0,-2.0,0.0), phase = ConstantPhase(8), T=ConstantTemp(30))
609+
julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
610+
julia> Write_Paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
611+
1-element Vector{String}:
612+
"LaMEM_ModelSetup.vts"
613+
```
614+
615+
"""
616+
function addPolygon!(Phase, Temp, Grid::AbstractGeneralGrid; # required input
617+
xlim::Vector=[], ylim::Vector=[], zlim::Vector=[], # limits of the box
618+
phase = ConstantPhase(1), # Sets the phase number(s) in the box
619+
T=nothing ) # Sets the thermal structure (various functions are available)
620+
621+
# Retrieve 3D data arrays for the grid
622+
X,Y,Z = coordinate_grids(Grid)
623+
624+
ind = zeros(Bool,size(X))
625+
ind_slice = zeros(Bool,size(X[:,1,:]))
626+
627+
# find points within the polygon, only in 2D
628+
for i = 1:size(Y)[2]
629+
if Y[1,i,1] >= ylim[1] && Y[1,i,1]<=ylim[2]
630+
inPolygon!(ind_slice, xlim,zlim, X[:,i,:], Z[:,i,:])
631+
ind[:,i,:] = ind_slice
632+
else
633+
ind[:,i,:] = zeros(size(X[:,1,:]))
634+
end
635+
end
636+
637+
638+
# Compute thermal structure accordingly. See routines below for different options
639+
if T != nothing
640+
Temp[ind] = Compute_ThermalStructure(Temp[ind], X[ind], Y[ind], Z[ind], Phase[ind], T)
641+
end
642+
643+
# Set the phase. Different routines are available for that - see below.
644+
Phase[ind] = Compute_Phase(Phase[ind], Temp[ind], X[ind], Y[ind], Z[ind], phase)
645+
646+
return nothing
647+
end
648+
574649
"""
575650
xrot, yrot, zrot = Rot3D(X::Number,Y::Number,Z::Number, cosStrikeAngle, sindStrikeAngle, cosDipAngle, sinDipAngle)
576651
@@ -823,7 +898,6 @@ function Compute_ThermalStructure(Temp, X, Y, Z, Phase, s::SpreadingRateTemp)
823898
SecYear = 3600*24*365
824899
dz = Z[end]-Z[1];
825900

826-
827901
MantleAdiabaticT = Tmantle .+ Adiabat*abs.(Z); # Adiabatic temperature of mantle
828902

829903
if MORside=="left"
@@ -1162,7 +1236,6 @@ end
11621236
Compute_Phase(Phase, Temp, Grid::LaMEM_grid, s::LithosphericPhases) = Compute_Phase(Phase, Temp, Grid.X, Grid.Y, Grid.Z, s::LithosphericPhases, Ztop=maximum(Grid.coord_z))
11631237

11641238

1165-
11661239
"""
11671240
McKenzie_subducting_slab
11681241
@@ -1193,15 +1266,16 @@ end
11931266
Compute the temperature field of a `McKenzie_subducting_slab`. Uses the analytical solution
11941267
of McKenzie (1969) ["Speculations on the consequences and causes of plate motions"]. The functions assumes
11951268
that the bottom of the slab is the coordinate Z=0. Internally the function shifts the coordinate.
1269+
11961270
Parameters
1271+
11971272
=============================
11981273
Temp Temperature array
11991274
- `X` X Array
12001275
- `Y` Y Array
12011276
- `Z` Z Array
12021277
- `Phase` Phase array
12031278
- `s` McKenzie_subducting_slab
1204-
12051279
"""
12061280
function Compute_ThermalStructure(Temp, X, Y, Z,Phase, s::McKenzie_subducting_slab)
12071281
@unpack Tsurface, Tmantle, Adiabat, v_cm_yr, κ, it = s
@@ -1661,5 +1735,4 @@ function addSlab!(Phase, Temp, Grid::AbstractGeneralGrid, trench::Trench;
16611735
end
16621736

16631737
return nothing
1664-
end
1665-
1738+
end

test/test_setup_geometry.jl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ AddBox!(Phases,Temp,Grid, xlim=(2,4), zlim=(-15,-10), phase=ConstantPhase(3), Di
1414
AddEllipsoid!(Phases,Temp,Grid, cen=(4,15,-17), axes=(1,2,3), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(2), T=ConstantTemp(600))
1515
@test sum(Temp[1,1,:]) 14850.0
1616

17+
18+
1719
# CartData
1820
X,Y,Z = XYZGrid(1.0:1:10.0, 11.0:1:20.0, -20:1:-10);
1921
Data = zeros(size(X));
@@ -213,6 +215,26 @@ AddBox!(Phase, Temp, Cart; xlim=(0.0,600.0),ylim=(0.0,600.0), zlim=(-80.0, 0.0),
213215

214216
Data_Final = AddField(Cart,"Temp",Temp)
215217

218+
219+
# test polygon structure
220+
221+
x = LinRange(0.0,1200.0,64);
222+
y = LinRange(0.0,1200.0,64);
223+
z = LinRange(-660,50,64);
224+
Cart = CartData(XYZGrid(x, y, z));
225+
226+
# initialize phase and temperature matrix
227+
Phase = ones(Int32,(length(x),length(y),length(z)));
228+
Temp = ones(Float64,(length(x),length(y),length(z)))*1350;
229+
230+
AddBox!(Phase, Temp, Cart; xlim=(0.0,600.0),ylim=(0.0,600.0), zlim=(-80.0, 0.0), phase = ConstantPhase(5), T=T=ConstantTemp(120.0));
231+
232+
# add accretionary prism
233+
addPolygon!(Phase, Temp, Cart; xlim=[500.0, 200.0, 500.0],ylim=[100.0,400.0], zlim=[0.0,0.0,-60.0], phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30))
234+
235+
@test maximum(Phase) == 8
236+
@test minimum(Temp) == 21.40845070422536
237+
216238
# Test the Bending slab geometry
217239

218240
# Create CartGrid struct
@@ -329,4 +351,3 @@ Phases[ind] .= 0;
329351
#Grid2D = CartData(Grid2D.x.val,Grid2D.y.val,Grid2D.z.val, (;Phases, Temp))
330352
#Write_Paraview(Grid2D,"Grid2D_SubductionCurvedOverriding");
331353

332-
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using GeophysicalModelGenerator
2+
3+
4+
# number of cells in every direction
5+
nx = 100
6+
ny = 100
7+
nz = 200
8+
9+
# define domain size
10+
x = LinRange(0.0,800.0,nx)
11+
y = LinRange(0.0,800.0,ny)
12+
z = LinRange(-660,50,nz)
13+
X,Y,Z = XYZGrid(x, y, z);
14+
Cart = CartData(X,Y,Z, (Data=Z,))
15+
16+
# initialize phase and temperature matrix
17+
Phase = ones(Int32,size(X))
18+
Temp = ones(Float64,size(X))*1350
19+
20+
# add different phases: crust->2, Mantle Lithosphere->3 Mantle->1
21+
AddBox!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(-800.0,0.0), phase = LithosphericPhases(Layers=[15 30 100 800], Phases=[2 3 1 5], Tlab=1300 ), T=LinearTemp(Ttop=20, Tbot=1600) )#T=HalfspaceCoolingTemp(Tsurface=20.0, Tmantle=1350, Age=120, Adiabat=0.4)
22+
23+
24+
# xlim: x-coordinates of the points, same ordering as zlim
25+
# zlim: z-coordinates of the points, same ordering as xlim
26+
# ylim: limits the object within the two ylim values
27+
# unlimited number of points possible to create the polygon
28+
# add sediment basin # depending on the resolution and angle if it the edge is visible in paraview
29+
addPolygon!(Phase, Temp, Cart; xlim=[0.0,0.0, 160.0, 200.0],ylim=[100.0,300.0], zlim=[0.0,-10.0,-20.0,0.0], phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30))
30+
31+
# add thinning of the continental crust attached to the slab and its thickness
32+
addPolygon!(Phase, Temp, Cart; xlim=[0.0, 200.0, 0.0],ylim=[500.0,800.0], zlim=[-100.0,-150.0,-150.0], phase = ConstantPhase(5), T=LinearTemp(Ttop=1000, Tbot=1100))
33+
34+
# add accretionary prism
35+
addPolygon!(Phase, Temp, Cart; xlim=[800.0, 600.0, 800.0],ylim=[100.0,800.0], zlim=[0.0,0.0,-60.0], phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30))
36+
37+
38+
# add air phase 0
39+
AddBox!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(0.0,50.0), phase = ConstantPhase(0), T=ConstantTemp(20.0))
40+
41+
# # Save data to paraview:
42+
Data_Final = CartData(X,Y,Z,(Phase=Phase,Temp=Temp))
43+
Write_Paraview(Data_Final, "Sedimentary_basin")
44+
45+

0 commit comments

Comments
 (0)