-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,328 @@ | ||
push!(LOAD_PATH, "..") | ||
|
||
@static if ENV["JULIA_JUSTRELAX_BACKEND"] === "AMDGPU" | ||
using AMDGPU | ||
elseif ENV["JULIA_JUSTRELAX_BACKEND"] === "CUDA" | ||
using CUDA | ||
end | ||
|
||
using Test, Suppressor | ||
using GeoParams | ||
using JustRelax, JustRelax.JustRelax2D | ||
using ParallelStencil, ParallelStencil.FiniteDifferences2D | ||
|
||
const backend_JR = @static if ENV["JULIA_JUSTRELAX_BACKEND"] === "AMDGPU" | ||
@init_parallel_stencil(AMDGPU, Float64, 2) | ||
AMDGPUBackend | ||
elseif ENV["JULIA_JUSTRELAX_BACKEND"] === "CUDA" | ||
@init_parallel_stencil(CUDA, Float64, 2) | ||
CUDABackend | ||
else | ||
@init_parallel_stencil(Threads, Float64, 2) | ||
CPUBackend | ||
end | ||
|
||
using JustPIC, JustPIC._2D | ||
# Threads is the default backend, | ||
# to run on a CUDA GPU load CUDA.jl (i.e. "using CUDA") at the beginning of the script, | ||
# and to run on an AMD GPU load AMDGPU.jl (i.e. "using AMDGPU") at the beginning of the script. | ||
const backend = @static if ENV["JULIA_JUSTRELAX_BACKEND"] === "AMDGPU" | ||
JustPIC.AMDGPUBackend | ||
elseif ENV["JULIA_JUSTRELAX_BACKEND"] === "CUDA" | ||
CUDABackend | ||
else | ||
JustPIC.CPUBackend | ||
end | ||
|
||
|
||
# Load script dependencies | ||
using Printf, Statistics, LinearAlgebra, CellArrays, StaticArrays | ||
|
||
|
||
# ----------------------------------------------------------------------------------------- | ||
## SET OF HELPER FUNCTIONS PARTICULAR FOR THIS SCRIPT -------------------------------- | ||
function copyinn_x!(A, B) | ||
@parallel function f_x(A, B) | ||
@all(A) = @inn_x(B) | ||
return nothing | ||
end | ||
|
||
@parallel f_x(A, B) | ||
end | ||
|
||
import ParallelStencil.INDICES | ||
const idx_j = INDICES[2] | ||
macro all_j(A) | ||
return esc(:($A[$idx_j])) | ||
end | ||
|
||
@parallel function init_P!(P, ρg, z) | ||
@all(P) = abs(@all(ρg) * @all_j(z)) * <(@all_j(z), 0.0) | ||
return nothing | ||
end | ||
|
||
function init_phases!(phases, particles, xc_anomaly, yc_anomaly, r_anomaly, sticky_air,top, bottom) | ||
ni = size(phases) | ||
|
||
@parallel_indices (i, j) function init_phases!( | ||
phases, px, py, index, xc_anomaly, yc_anomaly, r_anomaly, sticky_air, top, bottom | ||
) | ||
@inbounds for ip in cellaxes(phases) | ||
# quick escape | ||
@index(index[ip, i, j]) == 0 && continue | ||
|
||
x = @index px[ip, i, j] | ||
y = -(@index py[ip, i, j]) - sticky_air | ||
if top ≤ y ≤ bottom | ||
@index phases[ip, i, j] = 1.0 # crust | ||
end | ||
|
||
# thermal anomaly - circular | ||
if ((x - xc_anomaly)^2 + (y + yc_anomaly)^2 ≤ r_anomaly^2) | ||
@index phases[ip, i, j] = 2.0 | ||
end | ||
|
||
if y < top | ||
@index phases[ip, i, j] = 3.0 | ||
end | ||
end | ||
return nothing | ||
end | ||
|
||
@parallel (@idx ni) init_phases!( | ||
phases, | ||
particles.coords..., | ||
particles.index, | ||
xc_anomaly, | ||
yc_anomaly, | ||
r_anomaly, | ||
sticky_air, | ||
top, | ||
bottom, | ||
) | ||
end | ||
|
||
# Initial thermal profile | ||
@parallel_indices (i, j) function init_T!(T, y, sticky_air, top, bottom, dTdz, offset) | ||
depth = -y[j] - sticky_air | ||
|
||
if depth < top | ||
T[i + 1, j] = offset | ||
|
||
elseif top ≤ (depth) < bottom | ||
dTdZ = dTdz | ||
offset = offset | ||
T[i + 1, j] = (depth) * dTdZ + offset | ||
|
||
end | ||
|
||
return nothing | ||
end | ||
|
||
function circular_perturbation!(T, δT, xc_anomaly, yc_anomaly, r_anomaly, xvi, sticky_air) | ||
@parallel_indices (i, j) function _circular_perturbation!( | ||
T, δT, xc_anomaly, yc_anomaly, r_anomaly, x, y, sticky_air | ||
) | ||
depth = -y[j] - sticky_air | ||
@inbounds if ((x[i] - xc_anomaly)^2 + (depth[j] + yc_anomaly)^2 ≤ r_anomaly^2) | ||
# T[i + 1, j] *= δT / 100 + 1 | ||
T[i + 1, j] = δT | ||
end | ||
return nothing | ||
end | ||
|
||
nx, ny = size(T) | ||
|
||
@parallel (1:(nx - 2), 1:ny) _circular_perturbation!( | ||
T, δT, xc_anomaly, yc_anomaly, r_anomaly, xvi..., sticky_air | ||
) | ||
end | ||
|
||
function init_rheology(CharDim;) | ||
# plasticity setup | ||
do_DP = true # do_DP=false: Von Mises, do_DP=true: Drucker-Prager (friction angle) | ||
η_reg = 1.0e18Pa * s # regularisation "viscosity" for Drucker-Prager | ||
Coh = 10.0MPa # yield stress. If do_DP=true, τ_y stand for the cohesion: c*cos(ϕ) | ||
ϕ = 30.0 * do_DP # friction angle | ||
G0 = 6.0e11Pa # elastic shear modulus | ||
G_magma = 6.0e11Pa # elastic shear modulus perturbation | ||
|
||
pl = DruckerPrager_regularised(; C=Coh, ϕ=ϕ, η_vp=η_reg, Ψ=0.0) # plasticity | ||
el = SetConstantElasticity(; G=G0, ν=0.5) # elastic spring | ||
el_magma = SetConstantElasticity(; G=G_magma, ν=0.5) # elastic spring | ||
|
||
creep_rock = LinearViscous(; η=1e23 * Pa * s) | ||
creep_magma = LinearViscous(; η=1e18 * Pa * s) | ||
creep_air = LinearViscous(; η=1e18 * Pa * s) | ||
|
||
g = 9.81m/s^2 | ||
rheology = ( | ||
#Name="UpperCrust" | ||
SetMaterialParams(; | ||
Phase = 1, | ||
Density = ConstantDensity(; ρ=2650kg / m^3), | ||
HeatCapacity = ConstantHeatCapacity(; Cp=1050J / kg / K), | ||
Conductivity = ConstantConductivity(; k=3.0Watt / K / m), | ||
LatentHeat = ConstantLatentHeat(; Q_L=350e3J / kg), | ||
ShearHeat = ConstantShearheating(1.0NoUnits), | ||
CompositeRheology = CompositeRheology((creep_rock, el, pl)), | ||
Melting = MeltingParam_Caricchi(), | ||
Gravity = ConstantGravity(; g=g), | ||
Elasticity = el, | ||
CharDim = CharDim, | ||
), | ||
|
||
#Name="Magma" | ||
SetMaterialParams(; | ||
Phase = 1, | ||
Density = ConstantDensity(; ρ=2650kg / m^3), | ||
HeatCapacity = ConstantHeatCapacity(; Cp=1050J / kg / K), | ||
Conductivity = ConstantConductivity(; k=1.5Watt / K / m), | ||
LatentHeat = ConstantLatentHeat(; Q_L=350e3J / kg), | ||
ShearHeat = ConstantShearheating(0.0NoUnits), | ||
CompositeRheology = CompositeRheology((creep_magma, el_magma)), | ||
Melting = MeltingParam_Caricchi(), | ||
Gravity = ConstantGravity(; g=g), | ||
Elasticity = el_magma, | ||
CharDim = CharDim, | ||
), | ||
|
||
#Name="Sticky Air" | ||
SetMaterialParams(; | ||
Phase = 1, | ||
Density = ConstantDensity(ρ=1kg/m^3,), | ||
HeatCapacity = ConstantHeatCapacity(; Cp=1000J / kg / K), | ||
Conductivity = ConstantConductivity(; k=15Watt / K / m), | ||
LatentHeat = ConstantLatentHeat(; Q_L=0.0J / kg), | ||
ShearHeat = ConstantShearheating(0.0NoUnits), | ||
CompositeRheology = CompositeRheology((creep_air,)), | ||
Gravity = ConstantGravity(; g=g), | ||
CharDim = CharDim, | ||
), | ||
) | ||
|
||
end | ||
|
||
|
||
function main2D(igg; nx=32, ny=32) | ||
|
||
# Characteristic lengths | ||
CharDim = GEO_units(;length=12.5km, viscosity=1e21, temperature = 1e3C) | ||
|
||
#-------JustRelax parameters------------------------------------------------------------- | ||
# Domain setup for JustRelax | ||
sticky_air = nondimensionalize(1.5km, CharDim) # thickness of the sticky air layer | ||
ly = nondimensionalize(12.5km,CharDim) + sticky_air # domain length in y-direction | ||
lx = nondimensionalize(15.5km, CharDim) # domain length in x-direction | ||
li = lx, ly # domain length in x- and y-direction | ||
ni = nx, ny # number of grid points in x- and y-direction | ||
di = @. li / ni # grid step in x- and y-direction | ||
origin = nondimensionalize(0.0km,CharDim), -ly # origin coordinates of the domain | ||
grid = Geometry(ni, li; origin=origin) | ||
εbg = nondimensionalize(0.0 / s,CharDim) # background strain rate | ||
(; xci, xvi) = grid # nodes at the center and vertices of the cells | ||
#--------------------------------------------------------------------------------------- | ||
|
||
# Physical Parameters | ||
rheology = init_rheology(CharDim; ) | ||
cutoff_visc = nondimensionalize((1e16Pa*s, 1e24Pa*s),CharDim) | ||
κ = (4 / (rheology[1].HeatCapacity[1].Cp * rheology[1].Density[1].ρ)) | ||
dt = dt_diff = (0.5 * min(di...)^2 / κ / 2.01) # diffusive CFL timestep limiter | ||
|
||
# Initialize particles ------------------------------- | ||
nxcell, max_xcell, min_xcell = 20, 40, 15 | ||
particles = init_particles(backend, nxcell, max_xcell, min_xcell, xvi...) | ||
subgrid_arrays = SubgridDiffusionCellArrays(particles) | ||
# velocity grids | ||
grid_vx, grid_vy = velocity_grids(xci, xvi, di) | ||
# temperature | ||
pT, pPhases = init_cell_arrays(particles, Val(2)) | ||
particle_args = (pT, pPhases) | ||
|
||
# Circular temperature anomaly ----------------------- | ||
x_anomaly = lx * 0.5 | ||
y_anomaly = nondimensionalize(-5km,CharDim) # origin of the small thermal anomaly | ||
r_anomaly = nondimensionalize(1.5km, CharDim) # radius of perturbation | ||
anomaly = nondimensionalize((750 + 273)K, CharDim) # thermal perturbation (in K) | ||
init_phases!(pPhases, particles, x_anomaly, y_anomaly, r_anomaly, sticky_air, nondimensionalize(0.0km,CharDim), nondimensionalize(20km,CharDim)) | ||
phase_ratios = PhaseRatios(backend, length(rheology), ni) | ||
update_phase_ratios!(phase_ratios, particles, xci, xvi, pPhases) | ||
|
||
# Initialisation of thermal profile | ||
thermal = ThermalArrays(backend_JR, ni) # initialise thermal arrays and boundary conditions | ||
thermal_bc = TemperatureBoundaryConditions(; | ||
no_flux = (left=true, right=true, top=false, bot=false), | ||
) | ||
@parallel (@idx ni .+ 1) init_T!( | ||
thermal.T, xvi[2], | ||
sticky_air, | ||
nondimensionalize(0e0km,CharDim), | ||
nondimensionalize(15km,CharDim), | ||
nondimensionalize((723 - 273)K,CharDim) / nondimensionalize(15km,CharDim), | ||
nondimensionalize(273K,CharDim) | ||
) | ||
circular_perturbation!( | ||
thermal.T, anomaly, x_anomaly, y_anomaly, r_anomaly, xvi, sticky_air | ||
) | ||
thermal_bcs!(thermal, thermal_bc) | ||
temperature2center!(thermal) | ||
|
||
# STOKES --------------------------------------------- | ||
# Allocate arrays needed for every Stokes problem | ||
stokes = StokesArrays(backend_JR, ni) # initialise stokes arrays with the defined regime | ||
pt_stokes = PTStokesCoeffs(li, di; ϵ = 1e-4, CFL = 1 / √2.1) | ||
# ---------------------------------------------------- | ||
|
||
args = (; T=thermal.Tc, P=stokes.P, dt=dt) | ||
pt_thermal = PTThermalCoeffs( | ||
backend_JR, rheology, phase_ratios, args, dt, ni, di, li; ϵ=1e-5, CFL=0.8 / √2.1 | ||
) | ||
|
||
# Pure shear far-field boundary conditions | ||
stokes.V.Vx .= PTArray(backend_JR)([ | ||
εbg * (x - lx * 0.5) / (lx / 2) / 2 for x in xvi[1], _ in 1:(ny + 2) | ||
]) | ||
stokes.V.Vy .= PTArray(backend_JR)([ | ||
(abs(y) - sticky_air) * εbg * (abs(y) > sticky_air) for _ in 1:(nx + 2), y in xvi[2] | ||
]) | ||
|
||
flow_bcs = VelocityBoundaryConditions(; | ||
free_slip = (left=true, right=true, top=true, bot=true), | ||
free_surface = true, | ||
) | ||
flow_bcs!(stokes, flow_bcs) | ||
|
||
compute_viscosity!(stokes, phase_ratios, args, rheology, cutoff_visc) | ||
|
||
ϕ = @zeros(ni...) | ||
|
||
# Buoyancy force | ||
ρg = @zeros(ni...), @zeros(ni...) # ρg[1] is the buoyancy force in the x direction, ρg[2] is the buoyancy force in the y direction | ||
for _ in 1:5 | ||
compute_ρg!(ρg[2], phase_ratios, rheology, (T=thermal.Tc, P=stokes.P)) | ||
@parallel init_P!(stokes.P, ρg[2], xci[2]) | ||
compute_melt_fraction!( | ||
ϕ, phase_ratios, rheology, (T=thermal.Tc, P=stokes.P) | ||
) | ||
end | ||
|
||
return ϕ, stokes, thermal | ||
end | ||
|
||
@testset "thermal stresses" begin | ||
# @suppress begin | ||
nx, ny = 32, 32 # number of cells | ||
igg = if !(JustRelax.MPI.Initialized()) # initialize (or not) MPI grid | ||
IGG(init_global_grid(nx, ny, 1; init_MPI= true)...) | ||
else | ||
igg | ||
end | ||
|
||
ϕ, stokes, thermal = main2D(igg; nx=32, ny=32) | ||
|
||
nx_T, ny_T = size(thermal.T) | ||
@test Array(thermal.T)[nx_T >>> 1 + 1, ny_T >>> 1 + 1] ≈ 0.8035 rtol = 1e-2 | ||
@test Array(ϕ)[nx_T >>> 1 + 1, ny_T >>> 1 + 1] ≈ 0.10152 rtol = 1e-1 | ||
|
||
# end | ||
end |