Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Polygon structure in pseudo3D #73

Merged
merged 26 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e35424c
Add Polygon structure
TatjanaWeiler Feb 29, 2024
d69e6e6
Merge branch 'main' into pr/73
boriskaus Mar 2, 2024
ce4a3f5
fix typos; change name to addPolygon
boriskaus Mar 2, 2024
acc2136
Add Polygon structure -- added files
TatjanaWeiler Mar 4, 2024
7e66f8d
Merge branch 'main' of https://github.com/TatjanaWeiler/GeophysicalMo…
TatjanaWeiler Mar 4, 2024
dd50004
Create Setup_geometry.jl
TatjanaWeiler Mar 4, 2024
a580ea8
Update Setup_geometry.jl
TatjanaWeiler Mar 4, 2024
c93b36c
Merge branch 'main' into main
boriskaus Mar 4, 2024
a91df89
Poly_tutorial
TatjanaWeiler Mar 4, 2024
c747e9f
Merge branch 'main' of https://github.com/TatjanaWeiler/GeophysicalMo…
TatjanaWeiler Mar 4, 2024
4dfe524
Merge remote-tracking branch 'upstream/main'
TatjanaWeiler Mar 8, 2024
04cc8a8
Merge branch 'main' into main
boriskaus Mar 8, 2024
dc372e4
Polygon function compatible with new inPolygon
TatjanaWeiler Mar 11, 2024
d5dd2e1
Polygon again
TatjanaWeiler Mar 11, 2024
de5f329
Merge branch 'main' into main
boriskaus Mar 11, 2024
b0d5107
Merge branch 'main' into main
boriskaus Mar 11, 2024
f67f9cf
Update make.jl
boriskaus Mar 11, 2024
99b495c
Update make.jl
boriskaus Mar 11, 2024
937bbd2
Update make.jl
boriskaus Mar 11, 2024
428fb96
Update tutorial_Polygon_structures.md
boriskaus Mar 11, 2024
8aa10f1
Update Setup_geometry.jl
boriskaus Mar 11, 2024
6530a9f
Additional test polygon
TatjanaWeiler Mar 12, 2024
7a94ab9
Merge branch 'main' of https://github.com/TatjanaWeiler/GeophysicalMo…
TatjanaWeiler Mar 12, 2024
32adc3c
Test polygon
TatjanaWeiler Mar 13, 2024
edad91d
Test polygon_3
TatjanaWeiler Mar 13, 2024
9ad2943
Merge branch 'main' into main
boriskaus Mar 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,17 @@ makedocs(;
"16 - Create movies" => "man/tutorial_time_Seismicity.md",
"17 - Fault Density Map" => "man/Tutorial_FaultDensity.md",
"18 - Alpine data integration" => "man/Tutorial_AlpineData.md",
"19 - Jura tutorial" => "man/Tutorial_Jura.md"
"19 - Jura tutorial" => "man/Tutorial_Jura.md",
"20 - Build geometry from polygons" => "man/tutorial_Polygon_structures.md"
],
"User Guide" => Any[
"Installation" => "man/installation.md",
"Data Structures" => "man/datastructures.md",
"Data Import" => "man/dataimport.md",
"Projection" => "man/projection.md",
"Surfaces" => "man/surfaces.md",
"Paraview output" => "man/paraview_output.md",
"Paraview collection" => "man/paraview_collection.md",
"Surfaces" => "man/surfaces.md",
"Tools" => "man/tools.md",
"Visualisation" => "man/visualise.md",
"Gravity code" => "man/gravity_code.md",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 72 additions & 0 deletions docs/src/man/tutorial_Polygon_structures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Adding complex geometries to a model setup including sedimentary basins, lithospheric thinning and an accretionary prism


## Goal

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.

## Steps

#### 1. Set up your simplified background model
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.

```julia
using GeophysicalModelGenerator

# number of cells in every direction
nx = 100
ny = 100
nz = 200

# define domain size
x = LinRange(0.0,800.0,nx)
y = LinRange(0.0,800.0,ny)
z = LinRange(-660,50,nz)
Cart = CartData(XYZGrid(x, y, z))

# initialize phase and temperature matrix
Phase = ones(Int32,size(X))
Temp = ones(Float64,size(X))*1350

# add different phases: crust->2, Mantle Lithosphere->3 Mantle->1
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))

# add air phase 0
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))
```


#### 2. Add polygon structure
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)).


```julia
# xlim: x-coordinates of the points, same ordering as zlim
# zlim: z-coordinates of the points, same ordering as xlim
# ylim: limits the object within the two ylim values
# unlimited number of points possible to create the polygon

# add sediment basin
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));

# add thinning of the continental crust attached to the slab and its thickness
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));

# add accretionary prism
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));
```

#### 3. Export final model setup to a paraview file
For visualisation and comparison to actual measured data, the mode setup is saved to a paraview file.

```julia
# # Save data to paraview:
Data_Final = CartData(X,Y,Z,(Phase=Phase,Temp=Temp));
Write_Paraview(Data_Final, "Sedimentary_basin");
```

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.

![Tutorial_Polygon_structures](../assets/img/Tutorial_Polygon_structures.png)

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)
85 changes: 79 additions & 6 deletions src/Setup_geometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Base: show
# These are routines that help to create input geometries, such as slabs with a given angle
#

export AddBox!, AddSphere!, AddEllipsoid!, AddCylinder!, AddLayer!, addSlab!, addStripes!,
export AddBox!, AddSphere!, AddEllipsoid!, AddCylinder!, AddLayer!, addPolygon!, addSlab!, addStripes!,
makeVolcTopo,
ConstantTemp, LinearTemp, HalfspaceCoolingTemp, SpreadingRateTemp, LithosphericTemp,
ConstantPhase, LithosphericPhases,
Expand Down Expand Up @@ -571,6 +571,81 @@ function Rot3D!(X,Y,Z, StrikeAngle, DipAngle)
return nothing
end



"""
addPolygon!(Phase, Temp, Grid::AbstractGeneralGrid; xlim::Vector(), ylim=Vector(2), zlim=Vector(), phase = ConstantPhase(1), T=nothing )

Adds a polygon with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models

Parameters
====
- `Phase` - Phase array (consistent with Grid)
- `Temp` - Temperature array (consistent with Grid)
- `Grid` - Grid structure (usually obtained with ReadLaMEM_InputFile)
- `xlim` - `x`-coordinate of the polygon points, same ordering as zlim, number of points unlimited
- `ylim` - `y`-coordinate, limitation in length possible (two values (start and stop))
- `zlim` - `z`-coordinate of the polygon points, same ordering as xlim, number of points unlimited
- `phase` - specifies the phase of the box. See `ConstantPhase()`
- `T` - specifies the temperature of the box. See `ConstantTemp()`,`LinearTemp()`,`HalfspaceCoolingTemp()`,`SpreadingRateTemp()`

Example
========

Polygon with constant phase and temperature:

```julia
julia> Grid = ReadLaMEM_InputFile("test_files/SaltModels.dat")
LaMEM Grid:
nel : (32, 32, 32)
marker/cell : (3, 3, 3)
markers : (96, 96, 96)
x ϵ [-3.0 : 3.0]
y ϵ [-2.0 : 2.0]
z ϵ [-2.0 : 0.0]
julia> Phases = zeros(Int32, size(Grid.X));
julia> Temp = zeros(Float64, size(Grid.X));
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))
julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
julia> Write_Paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
1-element Vector{String}:
"LaMEM_ModelSetup.vts"
```

"""
function addPolygon!(Phase, Temp, Grid::AbstractGeneralGrid; # required input
xlim::Vector=[], ylim::Vector=[], zlim::Vector=[], # limits of the box
phase = ConstantPhase(1), # Sets the phase number(s) in the box
T=nothing ) # Sets the thermal structure (various functions are available)

# Retrieve 3D data arrays for the grid
X,Y,Z = coordinate_grids(Grid)

ind = zeros(Bool,size(X))
ind_slice = zeros(Bool,size(X[:,1,:]))

# find points within the polygon, only in 2D
for i = 1:size(Y)[2]
if Y[1,i,1] >= ylim[1] && Y[1,i,1]<=ylim[2]
inPolygon!(ind_slice, xlim,zlim, X[:,i,:], Z[:,i,:])
ind[:,i,:] = ind_slice
else
ind[:,i,:] = zeros(size(X[:,1,:]))
end
end


# Compute thermal structure accordingly. See routines below for different options
if T != nothing
Temp[ind] = Compute_ThermalStructure(Temp[ind], X[ind], Y[ind], Z[ind], Phase[ind], T)
end

# Set the phase. Different routines are available for that - see below.
Phase[ind] = Compute_Phase(Phase[ind], Temp[ind], X[ind], Y[ind], Z[ind], phase)

return nothing
end

"""
xrot, yrot, zrot = Rot3D(X::Number,Y::Number,Z::Number, cosStrikeAngle, sindStrikeAngle, cosDipAngle, sinDipAngle)

Expand Down Expand Up @@ -823,7 +898,6 @@ function Compute_ThermalStructure(Temp, X, Y, Z, Phase, s::SpreadingRateTemp)
SecYear = 3600*24*365
dz = Z[end]-Z[1];


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

if MORside=="left"
Expand Down Expand Up @@ -1162,7 +1236,6 @@ end
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))



"""
McKenzie_subducting_slab

Expand Down Expand Up @@ -1193,15 +1266,16 @@ end
Compute the temperature field of a `McKenzie_subducting_slab`. Uses the analytical solution
of McKenzie (1969) ["Speculations on the consequences and causes of plate motions"]. The functions assumes
that the bottom of the slab is the coordinate Z=0. Internally the function shifts the coordinate.

Parameters

=============================
Temp Temperature array
- `X` X Array
- `Y` Y Array
- `Z` Z Array
- `Phase` Phase array
- `s` McKenzie_subducting_slab

"""
function Compute_ThermalStructure(Temp, X, Y, Z,Phase, s::McKenzie_subducting_slab)
@unpack Tsurface, Tmantle, Adiabat, v_cm_yr, κ, it = s
Expand Down Expand Up @@ -1661,5 +1735,4 @@ function addSlab!(Phase, Temp, Grid::AbstractGeneralGrid, trench::Trench;
end

return nothing
end

end
23 changes: 22 additions & 1 deletion test/test_setup_geometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ AddBox!(Phases,Temp,Grid, xlim=(2,4), zlim=(-15,-10), phase=ConstantPhase(3), Di
AddEllipsoid!(Phases,Temp,Grid, cen=(4,15,-17), axes=(1,2,3), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(2), T=ConstantTemp(600))
@test sum(Temp[1,1,:]) ≈ 14850.0



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

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


# test polygon structure

x = LinRange(0.0,1200.0,64);
y = LinRange(0.0,1200.0,64);
z = LinRange(-660,50,64);
Cart = CartData(XYZGrid(x, y, z));

# initialize phase and temperature matrix
Phase = ones(Int32,(length(x),length(y),length(z)));
Temp = ones(Float64,(length(x),length(y),length(z)))*1350;

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));

# add accretionary prism
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))

@test maximum(Phase) == 8
@test minimum(Temp) == 21.40845070422536

# Test the Bending slab geometry

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


45 changes: 45 additions & 0 deletions tutorials/Tutorial_polygon_geometry.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using GeophysicalModelGenerator


# number of cells in every direction
nx = 100
ny = 100
nz = 200

# define domain size
x = LinRange(0.0,800.0,nx)
y = LinRange(0.0,800.0,ny)
z = LinRange(-660,50,nz)
X,Y,Z = XYZGrid(x, y, z);
Cart = CartData(X,Y,Z, (Data=Z,))

# initialize phase and temperature matrix
Phase = ones(Int32,size(X))
Temp = ones(Float64,size(X))*1350

# add different phases: crust->2, Mantle Lithosphere->3 Mantle->1
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)


# xlim: x-coordinates of the points, same ordering as zlim
# zlim: z-coordinates of the points, same ordering as xlim
# ylim: limits the object within the two ylim values
# unlimited number of points possible to create the polygon
# add sediment basin # depending on the resolution and angle if it the edge is visible in paraview
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))

# add thinning of the continental crust attached to the slab and its thickness
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))

# add accretionary prism
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))


# add air phase 0
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))

# # Save data to paraview:
Data_Final = CartData(X,Y,Z,(Phase=Phase,Temp=Temp))
Write_Paraview(Data_Final, "Sedimentary_basin")


Loading