diff --git a/Project.toml b/Project.toml index 11c3129..a292274 100644 --- a/Project.toml +++ b/Project.toml @@ -4,15 +4,9 @@ authors = ["Stefan Schmalholz, Ludovic Raess and contributors"] version = "0.2.0" [deps] -BSON = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MAT = "23992714-dd62-5051-b70f-ba57cb901cac" -ParallelRandomFields = "5519cec6-2252-4828-b89b-d1114f8bfbc2" ParallelStencil = "94395366-693c-11ea-3b26-d9b7aac5d958" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -ReferenceTests = "324d217c-45ce-50fc-942e-d289b448e8cf" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/README.md b/README.md index 03a922d..6151f8c 100644 --- a/README.md +++ b/README.md @@ -3,27 +3,21 @@ [![Build Status](https://github.com/PTsolvers/PseudoTransientHMC.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/PTsolvers/PseudoTransientHMC.jl/actions/workflows/CI.yml?query=branch%3Amain) [![DOI](https://zenodo.org/badge/299357364.svg)](https://zenodo.org/badge/latestdoi/299357364) -This repository contains Pseudo-Transient (PT) routines resolving chemical reactions coupled to fluid flow in viscously defroming solid pourous matrix, so-called Hydro-Mechanical-Chemical (HMC) coupling. Example of such multi-physical processes relate to, e.g, the brucite-periclase reactions [(Schmalholz et al., 2020)](https://doi.org/10.1029/2020GC009351) and could explain the formation of olivine veins by dehydration of ductile serpentinite ([Schmalholz et al., 2023 - submitted](), [Schmalholz et al., 2022](https://doi.org/10.1002/essoar.10512291.2)). -Pseudo-Transient approach relies in using physics-inspired transient terms within differential equations in order to iteratively converge to an accurate solution. The PT HMC routines are written using the [Julia programming language](https://julialang.org) and build upon the high-performance [ParallelStencil.jl](https://github.com/omlins/ParallelStencil.jl) package to enable for optimal execution on graphical processing units (GPUs) and multi-threaded CPUs. +This repository contains Pseudo-Transient (PT) routines resolving chemical reactions coupled to fluid flow in viscously defroming solid pourous matrix, so-called Hydro-Mechanical-Chemical (HMC) coupling. Example of such multi-physical processes to understand, e.g, the formation of olivine veins by dehydration of ductile serpentinite ([Schmalholz et al., 2023 - submitted](), [Schmalholz et al., 2022](https://doi.org/10.1002/essoar.10512291.2)), or the brucite-periclase reactions [(Schmalholz et al., 2020)](https://doi.org/10.1029/2020GC009351). -## Content -* [Script list](#script-list) -* [Usage](#usage) -* [Output](#output) -* [References](#references) +![Serpentinite dehydration and olivine vein formation during ductile shearing](docs/viz_dehy.png) +> Serpentinite dehydration and olivine vein formation during ductile shearing -## Script list -The scripts are located in two distinct folders. The folders contain the Julia (and early Matlab) routines and the `.mat` file with the corresponding thermodynamic data to be loaded as look-up tables. - -- The [scripts_2020](scripts_2020) folder relates to the [(Schmalholz et al., 2020)](https://doi.org/10.1029/2020GC009351) study. The "analytical" [`PT_HMC_bru_analytical.jl`](scripts_2020/PT_HMC_bru_analytical.jl) script includes a paramtetrisation of the solid and fluid densities and composition as function of fluid pressure to circumvent costly interpolation operations. - -- The [scripts_2022](scripts_2022) folder contains the routines for the [(Schmalholz et al., 2022)](https://doi.org/10.1002/essoar.10512291.2) "preprint" study. The main scipt is [`PT_HMC_atg.jl`](scripts_2022/PT_HMC_atg.jl). _The "rand" version implements resolving HMC coupling given a random initial porosity distribution._ +Pseudo-Transient approach relies in using physics-motivated transient terms within differential equations in order to iteratively converge to an accurate solution. The PT HMC routines are written using the [Julia programming language](https://julialang.org) and build upon the high-performance [ParallelStencil.jl](https://github.com/omlins/ParallelStencil.jl) package to enable for optimal execution on graphics processing units (GPUs) and multi-threaded CPUs. -- The [scripts_2023](scripts_2023) folder contains the routines for the [(Schmalholz et al., _submitted_)]() study. The main scipt is [`DeHy.jl`](scripts_2023/DeHy.jl). +## Script list +The Julia scripts are located in the [scripts](scripts) folder which contains the routines for the [(Schmalholz et al., _submitted_)]() study. +- The main script is [`DeHy.jl`](scripts/DeHy.jl); +- The visualisation script is [`vizme_DeHy.jl`](scripts/vizme_DeHy.jl). ## Usage -If not stated otherwise, all the routines are written in Julia and can be executed from the [Julia REPL], or from the terminal for improved performance. Output is produced using the [Julia Plots package]. +All the routines are written in Julia and can be executed from the [Julia REPL], or from the terminal for improved performance. Output is produced using [Makie.jl] (using the `CairoMakie` backend). The either multi-threaded CPU or GPU backend can be selected by adding the appropriate flag to the `USE_GPU` constant, modifying either the default behaviour in the top-most lines of the codes ```julia @@ -46,40 +40,27 @@ julia> ] (PseudoTransientHMC) pkg> activate . -(PseudoTransientHMC) pkg> add https://github.com/luraess/ParallelRandomFields.jl - (PseudoTransientHMC) pkg> instantiate ``` 3. Run the script ```julia-repl -julia> include("PT_HMC_atg.jl") +julia> include("DeHy.jl") ``` ### Example running the routine from the terminal -1. Launch the Julia executable using the project's dependencies `--project`, disabling array bound checking for enhanced performance `--check-bounds=no`, and using optimization level 3 `-O3`. +Launch the Julia executable using the project's dependencies `--project`: ```sh -julia --project --check-bounds=no -O3 PT_HMC_atg.jl +julia --project DeHy.jl ``` -Additional startup flag infos can be found [here](https://docs.julialang.org/en/v1/manual/getting-started/#man-getting-started) - -## Output -The output of running the [`PT_HMC_bru_analytical.jl`](scripts_2020/PT_HMC_bru_analytical.jl) script on an Nvidia TitanXp GPU with `nx=1023, ny=1023`: - -![PT-HMC code predicting brucite-periclase reaction](docs/PT_HMC_bru_1023x1023.png) - -The output of running the [`PT_HMC_atg.jl`](scripts_2022/PT_HMC_atg.jl) script on an Nvidia Tesla V100 GPU with `nx=1023, ny=1023` (to be updated): - -![PT-HMC code predicting olivine vein formation](docs/PT_HMC_atg_1023x1023.png) - ## References -[Schmalholz, S. M., Moulas, E., Plümper, O., Myasnikov, A. V., & Podladchikov, Y. Y. (2020). 2D hydro‐mechanical‐chemical modeling of (De)hydration reactions in deforming heterogeneous rock: The periclase‐brucite model reaction. Geochemistry, Geophysics, Geosystems, 21, 2020GC009351. https://doi.org/10.1029/2020GC009351](https://doi.org/10.1029/2020GC009351) +Schmalholz, S. M., Moulas, E., Plümper, O., Myasnikov, A. V., & Podladchikov, Y. Y. (2020). **2D hydro‐mechanical‐chemical modeling of (De)hydration reactions in deforming heterogeneous rock: The periclase‐brucite model reaction**. Geochemistry, Geophysics, Geosystems, 21, 2020GC009351. [https://doi.org/10.1029/2020GC009351](https://doi.org/10.1029/2020GC009351) -[Schmalholz, S. M., Moulas, E., Räss, L., & Müntener, O. (2022). Shear-driven formation of olivine veins by dehydration of ductile serpentinite: a numerical study with implications for transient weakening. ESS Open Archive. https://doi.org/10.1002/essoar.10512291.2](https://doi.org/10.1002/essoar.10512291.2) +Schmalholz, S. M., Moulas, E., Räss, L., & Müntener, O. (2022). **Shear-driven formation of olivine veins by dehydration of ductile serpentinite: a numerical study with implications for transient weakening.** ESS Open Archive. [https://doi.org/10.1002/essoar.10512291.2](https://doi.org/10.1002/essoar.10512291.2) -[Schmalholz, S. M., Moulas, E., Räss, L., & Müntener, O. (submitted). Shear-driven formation of olivine veins by dehydration of ductile serpentinite: a numerical study with implications for porosity production and transient weakening. _Submitted to JGR_]() +Schmalholz, S. M., Moulas, E., Räss, L., & Müntener, O. (submitted). **Shear-driven formation of olivine veins by dehydration of ductile serpentinite: a numerical study with implications for porosity production and transient weakening.** [_Submitted to JGR_]() [CUDA.jl]: https://github.com/JuliaGPU/CUDA.jl -[Julia Plots package]: https://github.com/JuliaPlots/Plots.jl +[Makie.jl]: https://docs.makie.org/stable/ [Julia REPL]: https://docs.julialang.org/en/v1/stdlib/REPL/ diff --git a/docs/PT_HMC_atg_1023x1023.png b/docs/PT_HMC_atg_1023x1023.png deleted file mode 100644 index eee4158..0000000 Binary files a/docs/PT_HMC_atg_1023x1023.png and /dev/null differ diff --git a/docs/PT_HMC_bru_1023x1023.png b/docs/PT_HMC_bru_1023x1023.png deleted file mode 100644 index 33e600c..0000000 Binary files a/docs/PT_HMC_bru_1023x1023.png and /dev/null differ diff --git a/docs/viz_dehy.png b/docs/viz_dehy.png new file mode 100644 index 0000000..a775f84 Binary files /dev/null and b/docs/viz_dehy.png differ diff --git a/scripts/DeHy.jl b/scripts/DeHy.jl new file mode 100644 index 0000000..65803bd --- /dev/null +++ b/scripts/DeHy.jl @@ -0,0 +1,548 @@ +# Hydro-mechanical-chemical 2D model for olivine vein formation by dehydration of serpentinite +const run_test = haskey(ENV, "RUN_TEST") ? parse(Bool, ENV["RUN_TEST"]) : false +const USE_GPU = haskey(ENV, "USE_GPU" ) ? parse(Bool, ENV["USE_GPU"] ) : false +const GPU_ID = haskey(ENV, "GPU_ID" ) ? parse(Int, ENV["GPU_ID"] ) : 0 +using ParallelStencil +using ParallelStencil.FiniteDifferences2D +@static if USE_GPU + @init_parallel_stencil(CUDA, Float64, 2, inbounds=true) + CUDA.device!(GPU_ID) # select GPU +else + @init_parallel_stencil(Threads, Float64, 2, inbounds=true) +end +using Printf, Statistics, LinearAlgebra, MAT + +import ParallelStencil: INDICES +ix,iy = INDICES[1], INDICES[2] +ixi,iyi = :($ix+1), :($iy+1) + +"Average in x and y dimension" +@views av(A) = 0.25 * (A[1:end-1, 1:end-1] .+ A[2:end, 1:end-1] .+ A[1:end-1, 2:end] .+ A[2:end, 2:end]) +"Average in x dimension" +@views av_xa(A) = 0.5 * (A[1:end-1, :] .+ A[2:end, :]) +"Average in y dimension" +@views av_ya(A) = 0.5 * (A[:, 1:end-1] .+ A[:, 2:end]) + +@views function swell2h!(B, A, ndim) + B .= B .* 0.0 + if ndim == 1 + B[2:end-1, :] .= (A[2:end, :] .+ A[1:end-1, :]) ./ 2.0 + B[1, :] .= 1.5 * A[1, :] .- 0.5 * A[2, :] + B[end, :] .= 1.5 * A[end, :] .- 0.5 * A[end-1, :] + elseif ndim == 2 + B[:, 2:end-1] .= (A[:, 2:end] .+ A[:, 1:end-1]) ./ 2.0 + B[:, 1] .= 1.5 * A[:, 1] .- 0.5 * A[:, 2] + B[:, end] .= 1.5 * A[:, end] .- 0.5 * A[:, end-1] + end + return B +end + +@parallel_indices (ix, iy) function swell2_x!(B, A) + if (ix <= size(B, 1) && iy <= size(B, 2)) B[ix, iy] = 0.0 end + if (2 <= ix <= size(B, 1) - 1 && iy <= size(B, 2)) B[ix, iy] = 0.5 * (A[ix, iy] + A[ix-1, iy]) end + if (ix == 1 && iy <= size(B, 2)) B[ix, iy] = 1.5 * A[ix, iy] - 0.5 * A[ix+1, iy] end + if (ix == size(B, 1) && iy <= size(B, 2)) B[ix, iy] = 1.5 * A[ix-1, iy] - 0.5 * A[ix-2, iy] end + return +end + +@parallel_indices (ix, iy) function swell2_y!(B, A) + if (ix <= size(B, 1) && iy <= size(B, 2) ) B[ix, iy] = 0.0 end + if (ix <= size(B, 1) && 2 <= iy <= size(B, 2) - 1) B[ix, iy] = 0.5 * (A[ix, iy] + A[ix, iy-1]) end + if (ix <= size(B, 1) && iy == 1 ) B[ix, iy] = 1.5 * A[ix, iy] - 0.5 * A[ix, iy+1] end + if (ix <= size(B, 1) && iy == size(B, 2) ) B[ix, iy] = 1.5 * A[ix, iy-1] - 0.5 * A[ix, iy-2] end + return +end + +@parallel function cum_mult2!(A1, A2, B1, B2) + @all(A1) = @all(A1) * @all(B1) + @all(A2) = @all(A2) * @all(B2) + return +end + +@parallel function laplace!(A, TmpX, TmpY, dx, dy) + @all(A) = @d_xa(TmpX) / dx + @d_ya(TmpY) / dy + return +end + +@parallel_indices (iy) function bc_x!(A) + A[1 , iy] = A[2 , iy] + A[end, iy] = A[end-1, iy] + return +end + +@parallel_indices (ix) function bc_y!(A) + A[ix, 1 ] = A[ix, 2 ] + A[ix, end] = A[ix, end-1] + return +end + +@parallel function compute_1_ini!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η, Rho_s_amb, X_s_amb) + @all(Rho_s_old) = @all(Rho_s) + @all(Rho_f_old) = @all(Rho_f) + @all(X_s_old) = @all(X_s) + @all(Pf_old) = @all(Pf) + @all(Rho_X_old) = @all(Rho_s_old) * @all(X_s_old) + @all(Phi_old) = @all(Phi) + @all(Ptot_old) = @all(Ptot) + @all(Phi_old) = 1.0 - (@all(Rho_s_amb) * @all(X_s_amb)) * (1.0 - ϕ_ini) / @all(Rho_X_old) + @all(Phi) = @all(Phi_old) + @all(Rho_t_old) = @all(Rho_f_old) * @all(Phi_old) + @all(Rho_s_old) * (1.0 - @all(Phi_old)) + @all(Eta) = η_m * exp(-ϕ_exp * (@all(Phi) / ϕ_ini - @all(Phi) / @all(Phi))) + @all(Lam) = λ_η*@all(Eta) + return +end + +@parallel function compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η) + @all(Rho_s_old) = @all(Rho_s) + @all(Rho_f_old) = @all(Rho_f) + @all(X_s_old) = @all(X_s) + @all(Pf_old) = @all(Pf) + @all(Rho_X_old) = @all(Rho_s_old) * @all(X_s_old) + @all(Phi_old) = @all(Phi) + @all(Ptot_old) = @all(Ptot) + @all(Rho_t_old) = @all(Rho_f_old) * @all(Phi_old) + @all(Rho_s_old) * (1.0 - @all(Phi_old)) + @all(Eta) = η_m * exp(-ϕ_exp * (@all(Phi) / ϕ_ini - @all(Phi) / @all(Phi))) + @all(Lam) = λ_η*@all(Eta) + return +end + +@parallel_indices (ix,iy) function compute_2!(Rho_t, para_cx, para_cy, Rho_f, Phi, Rho_s, k_ηf, n_p) + if (ix <= size(Rho_t, 1) && iy <= size(Rho_t, 2)) Rho_t[ix, iy] = Rho_f[ix, iy] * Phi[ix, iy] + Rho_s[ix, iy] * (1.0 - Phi[ix, iy]) end + if (ix <= size(para_cx, 1) && iy <= size(para_cx, 2)) para_cx[ix, iy] = 0.5 * (Rho_f[ix, iy] * k_ηf * Phi[ix, iy]^n_p + Rho_f[ix+1, iy] * k_ηf * Phi[ix+1, iy]^n_p) end + if (ix <= size(para_cy, 1) && iy <= size(para_cy, 2)) para_cy[ix, iy] = 0.5 * (Rho_f[ix, iy] * k_ηf * Phi[ix, iy]^n_p + Rho_f[ix, iy+1] * k_ηf * Phi[ix, iy+1]^n_p) end + return +end + +@parallel function compute_3!(q_f_X, q_f_Y, para_cx, para_cy, Pf, dx, dy) + @all(q_f_X) = -@all(para_cx) * @d_xa(Pf) / dx + @all(q_f_Y) = -@all(para_cy) * @d_ya(Pf) / dy + return +end + +@parallel function compute_4!(∇q_f, Res_Pf, Rho_f, Rho_s_eq, X_s_eq, q_f_X, q_f_Y, Rho_t, Rho_t_old, ∇V_ρ_t, Pf, SlopeA, rho_f_maxA, ρ_0, p_reactA, rho_s_difA, rho_s_up, rho_s_minA, x_difA, x_minA, dtp, dx, dy) + @all(∇q_f) = @d_xi(q_f_X) / dx + @d_yi(q_f_Y) / dy + @all(Res_Pf) = -@all(∇q_f) - (@inn(Rho_t) - @inn(Rho_t_old)) / dtp - @inn(∇V_ρ_t) + @all(Rho_f) = (rho_f_maxA * log(@all(Pf) + 1.0)^(1.0 / 3.5)) / ρ_0 + @all(Rho_s_eq) = (-tanh(6e2 * (@all(Pf) - p_reactA)) * (rho_s_difA / 2.0 + rho_s_up / 3.0) + (rho_s_difA / 2.0 - rho_s_up / 3.0) + rho_s_minA + @all(SlopeA)) / ρ_0 + @all(X_s_eq) = -tanh(6e2 * (@all(Pf) - p_reactA)) * x_difA / 2.0 + x_difA / 2.0 + x_minA + return +end + +@parallel function compute_5!(X_s, Rho_s, X_s_old, X_s_eq, Rho_s_old, Rho_s_eq, dtp, kin_time) + @all(X_s) = @all(X_s_old) + dtp*(@all(X_s_eq) - @all(X_s) )/kin_time + @all(Rho_s) = @all(Rho_s_old) + dtp*(@all(Rho_s_eq) - @all(Rho_s))/kin_time + return +end + +@parallel function compute_6!(dPfdτ, Pf, Rho_X_ϕ, Res_Phi, Phi, Res_Pf, Rho_s, X_s, Phi_old, Rho_X_old, ∇V_ρ_X, dampPf, dt_Pf, dtp) + @all(dPfdτ) = dampPf * @all(dPfdτ) + @all(Res_Pf) + @inn(Pf) = @inn(Pf) + dt_Pf * @all(dPfdτ) + @all(Rho_X_ϕ) = (1.0 - @all(Phi)) * @all(Rho_s) * @all(X_s) + @all(Res_Phi) = (@all(Rho_X_ϕ) - (1.0 - @all(Phi_old)) * @all(Rho_X_old)) / dtp + @all(∇V_ρ_X) + @inn(Phi) = @inn(Phi) + dtp * @inn(Res_Phi) + return +end + +macro limit_min(A, min_val) esc(:(max($A[$ix, $iy], $min_val))) end +@parallel function compute_7!(Eta, Lam, ∇V, ε_xx, ε_yy, ε_xy, Ptot, Vx, Vy, Phi, Ptot_old, Pf, Pf_old, dt_Pt, η_m, ϕ_exp, ϕ_ini, λ_η, dtp, K_d, η_min, α, dx, dy) + @all(Eta) = η_m * exp(-ϕ_exp * (@all(Phi) / ϕ_ini - @all(Phi) / @all(Phi))) + @all(Eta) = @limit_min(Eta, η_min) + @all(Lam) = λ_η * @all(Eta) + @all(∇V) = @d_xa(Vx) / dx + @d_ya(Vy) / dy + @all(ε_xx) = @d_xa(Vx) / dx - 1.0 / 3.0 * @all(∇V) + @all(ε_yy) = @d_ya(Vy) / dy - 1.0 / 3.0 * @all(∇V) + @all(ε_xy) = 0.5 * (@d_yi(Vx) / dy + @d_xi(Vy) / dx) + @all(Ptot) = @all(Ptot) - dt_Pt * (@all(Ptot) - (@all(Ptot_old) - dtp * (K_d * @all(∇V) - α * ((@all(Pf) - @all(Pf_old)) / dtp) - K_d * @all(Pf) / ((1.0 - @all(Phi)) * @all(Lam)))) / (1.0 + dtp * K_d / ((1.0 - @all(Phi)) * @all(Lam)))) + return +end + +@parallel function compute_8!(τ_xx, τ_yy, τ_xy, Eta, ε_xx, ε_yy, ε_xy) + @all(τ_xx) = 2.0 * @all(Eta) * @all(ε_xx) + @all(τ_yy) = 2.0 * @all(Eta) * @all(ε_yy) + @all(τ_xy) = 2.0 * @av(Eta) * @all(ε_xy) + return +end + +@parallel function compute_plast_1!(τII, LamP, τ_xx, τ_yy, τ_xyn, σ_y) + @all(τII) = sqrt(0.5 * (@all(τ_xx) * @all(τ_xx) + @all(τ_yy) * @all(τ_yy)) + @all(τ_xyn) * @all(τ_xyn)) + @all(LamP) = max(0.0, (1.0 - σ_y / @all(τII))) + return +end + +@parallel function compute_plast_2!(τ_xx, τ_yy, τ_xy, LamP) + @all(τ_xx) = (1.0 - @all(LamP)) * @all(τ_xx) + @all(τ_yy) = (1.0 - @all(LamP)) * @all(τ_yy) + @all(τ_xy) = (1.0 - @av(LamP)) * @all(τ_xy) + return +end + +@parallel function compute_plast_3!(τII, LamP2, τ_xx, τ_yy, τ_xyn, LamP) + @all(τII) = sqrt(0.5 * (@all(τ_xx) * @all(τ_xx) + @all(τ_yy) * @all(τ_yy)) + @all(τ_xyn) * @all(τ_xyn)) + @all(LamP2) = @all(LamP2) + @all(LamP) + return +end + +@parallel function compute_9!(Res_Vx, Res_Vy, τ_xx, τ_yy, Ptot, τ_xy, dx, dy) + @all(Res_Vx) = -@d_xi(Ptot) / dx + @d_xi(τ_xx) / dx + @d_ya(τ_xy) / dy + @all(Res_Vy) = -@d_yi(Ptot) / dy + @d_yi(τ_yy) / dy + @d_xa(τ_xy) / dx + return +end + +@parallel function compute_10!(dVxdτ, dVydτ, Vx, Vy, Res_Vx, Res_Vy, dampV, dt_Stokes) + @all(dVxdτ) = @all(dVxdτ) * dampV + @all(Res_Vx) + @all(dVydτ) = @all(dVydτ) * dampV + @all(Res_Vy) + @inn(Vx) = @inn(Vx) + dt_Stokes * @all(dVxdτ) + @inn(Vy) = @inn(Vy) + dt_Stokes * @all(dVydτ) + return +end + +@parallel function postprocess!(dRhoT_dt, dRhosPhi_dt, dRhofPhi_dt, dRhoXPhi_dt, dPf_dt, dPt_dt, dPhi_dt, dRhos_dt, Rho_s, Rho_f, X_s, Phi, Rho_s_old, Rho_f_old, Rho_X_old, Phi_old, Rho_t, Rho_t_old, Pf, Pf_old, Ptot, Ptot_old, dtp) + @all(dRhoT_dt) = (@all(Rho_t) - @all(Rho_t_old)) / dtp# + @all(dRhosPhi_dt) = (@all(Rho_s) * (1.0 - @all(Phi)) - @all(Rho_s_old) * (1.0 - @all(Phi_old))) / dtp + @all(dRhofPhi_dt) = (@all(Rho_f) * @all(Phi) - @all(Rho_f_old) * @all(Phi_old)) / dtp + @all(dRhoXPhi_dt) = (@all(Rho_s) * @all(X_s) * (1 - @all(Phi)) - @all(Rho_X_old) * (1 - @all(Phi_old))) / dtp + @all(dPf_dt) = (@all(Pf) - @all(Pf_old)) / dtp + @all(dPt_dt) = (@all(Ptot) - @all(Ptot_old)) / dtp + @all(dPhi_dt) = (@all(Phi) - @all(Phi_old)) / dtp + @all(dRhos_dt) = (@all(Rho_s) - @all(Rho_s_old)) / dtp + return +end + +@views function PT_HMC(; nx=511, ny=511, do_save=false, run_test=false) + runid = "dehy" + do_Pf_pert = false + do_restart = false + nsave = 500 + irestart = 1000 # Step to restart from if do_reatart + # read in mat file + vars = matread( string(@__DIR__, "/LOOK_UP_atg.mat") ) + Rho_s_LU = get(vars, "Rho_s", 1) + Rho_f_LU = get(vars, "Rho_f", 1) + X_LU = get(vars, "X_s_vec_Si", 1) + P_LU = get(vars, "P_vec", 1) * 1e8 + # Independent parameters + rad = 1.0 # Radius of initial P-perturbation [m] + η_m = 1.0 # Viscosity scale [Pa s] + P_ini = 1.0 # Initial ambient pressure [Pa] + ρ_0 = 3000.0 # Density scale [kg/m^3] + # Nondimensional parameters + elli_fac = 2.0 # Use 1 for circle + angle = 45.0 # Counterclockwise angle of long axis with respect to vertical direction + ϕ_ini = 2e-2 # Initial porosity + ϕ_amp = 12 # Amplitude of porosity perturbation + ϕ_exp = 1 / 2.5 # Parameter controlling viscosity-porosity relation + lx_rad = 40.0 # LAMBDA_1 in equation (15) in the manuscript; Model height divided by inclusion radius; + lc_rad2 = 40 # LAMBDA_2 in equation (15) in the manuscript; Lc_rad2 = k_etaf*eta_mat/radius^2; []; Ratio of hydraulic fluid extraction to compaction extraction + λ_η = 2.0 # LAMBDA_3 in equation (15) in the manuscript; lam_eta = lambda / eta_mat; []; Ratio of bulk to shear viscosity + Da = 0.0784 * 1.5 # LAMBDA_4 + n_v = 3.0 # Exponent in viscosity - porosity relation + n_p = 3.0 # Exponent in permeablity - porosity relation (Kozeny-Carman) + ly_lx = 1.0 # Model height divided by model width + Pini_Pappl = P_ini / 12.75e8 # Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table + σ_y = 10 * 135.0 * Pini_Pappl * 1e6 # yield stress + P_pert = 60 * Pini_Pappl * 1e6 + # Dependant parameters + K_s = 1e11 * Pini_Pappl # Solid elastic bulk modulus + k_ηf = lc_rad2 * rad^2 / η_m # Permeability divided by fluid viscosity; [m^2/(Pa s)] + lx = lx_rad * rad # Model width [m] + ly = ly_lx * lx # Model height [m] + P_LU = P_LU * Pini_Pappl # Transform look-up table stress to PT stress scale + K_d = K_s / 2.0 # Elastic bulk modulus, drained + α = 1.0 - K_d / K_s # Biot-Willis coefficient + ε_bg = Da * P_ini / η_m # 1.0 / τ_deform + # Characteristic time scales + τ_f_dif_ϕ = rad^2 / (k_ηf * ϕ_ini^n_p * K_s) + τ_relax = η_m / K_s + τ_kinetic = 0.0025 * τ_f_dif_ϕ + # Numerics + dtp = 4e-6 * τ_f_dif_ϕ # Time step physical + nt = 2001 + tol = 1e-6 # Tolerance for pseudo-transient iterations + cfl = 1 / 16.1 # CFL parameter for PT-Stokes solution + damping = 1 + Re_Pf = 80π + Re_V = 80π + r = 1.5 + time_tot = 2001 * dtp # Total time of simulation + itmax = 5e6 + nout = 1e3 + nsm = 40 # number of porosity smoothing steps - explicit diffusion + η_min = 1e-8 + kin_time = 1e1 * τ_f_dif_ϕ + kin_time_final = τ_kinetic + Kin_time_vec = [1e25 * τ_f_dif_ϕ; range(kin_time, stop=kin_time_final, length=26); kin_time_final * ones(Int(round(time_tot / dtp)))] + # Configuration of grid, matrices and numerical parameters + dx, dy = lx / (nx - 1), ly / (ny - 1) # Grid spacing + xc, yc = -lx/2:dx:lx/2, -ly/2:dy:ly/2 # Coordinate vector + xv, yv = -lx/2-dx/2:dx:lx/2+dx/2, -ly/2-dy/2:dy:ly/2+dy/2 # Horizontal vector for Vx which is one more than basic grid + (Xc2, Yc2) = ([x for x=xc, y=yc], [y for x=xc, y=yc]) + (_, Yc2vx) = ([x for x=xv, y=yc], [y for x=xv, y=yc]) + (_, Yc2vy) = ([x for x=xc, y=yv], [y for x=xc, y=yv]) + rad_a = rad + rad_b = rad_a * elli_fac + X_rot = Xc2 * cosd(angle) + Yc2 * sind(angle) + Y_rot = -Xc2 * sind(angle) + Yc2 * cosd(angle) + X_elli = rad_a .* cos.(0:0.01:2*pi) .* cosd(angle) .+ rad_b .* sin.(0:0.01:2*pi) .* sind(angle) + Y_elli = -rad_a .* cos.(0:0.01:2*pi) .* sind(angle) .+ rad_b .* sin.(0:0.01:2*pi) .* cosd(angle) + # Analytical fit of look-up table + p_minA, p_maxA = minimum(P_LU), maximum(P_LU) + rho_s_up = 50.0 + # Pore pressure perturbation + Pf = P_ini * ones(nx, ny) + Pf_amb = P_ini * ones(nx, ny) + if do_Pf_pert + Pf[sqrt.((X_rot .- 0.0) .^ 2 ./ rad_a .^ 2 .+ (Y_rot .+ 0.0) .^ 2 ./ rad_b .^ 2).<1.0] .= P_ini - P_pert # Porosity perturbation + for _ = 1:nsm # Smooting of perturbation + Pf[2:end-1, :] .= Pf[2:end-1, :] .+ 0.4 .* (Pf[3:end, :] .- 2.0 .* Pf[2:end-1, :] .+ Pf[1:end-2, :]) + Pf[:, 2:end-1] .= Pf[:, 2:end-1] .+ 0.4 .* (Pf[:, 3:end] .- 2.0 .* Pf[:, 2:end-1] .+ Pf[:, 1:end-2]) + end + end + Pf = Data.Array(Pf) + Pf_amb = Data.Array(Pf_amb) + # Preprocess + SlopeA = (Pf .- p_minA) / p_maxA * rho_s_up + rho_s_max = Rho_s_LU[1] + rho_s_minA = minimum(Rho_s_LU) + rho_s_difA = rho_s_max - rho_s_minA + p_reactA = 12.65 * 1e8 * Pini_Pappl + rho_f_maxA = maximum(Rho_f_LU) # Parameters for fluid density + x_max = maximum(X_LU) # Parameters for mass fraction + x_minA = minimum(X_LU) + x_difA = x_max - x_minA + # Density, compressibility and gamma from concentration and pressure from thermodynamic data base + Rho_f = Data.Array((rho_f_maxA .* log.(Pf .+ 1.0) .^ (1.0 / 3.5)) / ρ_0) + Rho_s = Data.Array((-tanh.(6e2 * (Pf .- p_reactA)) * (rho_s_difA / 2.0 .+ rho_s_up / 3.0) .+ (rho_s_difA / 2.0 .- rho_s_up / 3.0) .+ rho_s_minA .+ SlopeA) / ρ_0) + X_s = Data.Array( -tanh.(6e2 * (Pf .- p_reactA)) * x_difA / 2.0 .+ x_difA / 2.0 .+ x_minA) + Rho_s_amb = Data.Array((-tanh.(6e2 * (Pf_amb .- p_reactA)) * (rho_s_difA / 2.0 .+ rho_s_up / 3.0) .+ (rho_s_difA / 2.0 .- rho_s_up / 3.0) .+ rho_s_minA .+ SlopeA) / ρ_0) + X_s_amb = Data.Array( -tanh.(6e2 * (Pf_amb .- p_reactA)) * x_difA / 2.0 .+ x_difA / 2.0 .+ x_minA) + SlopeA = Data.Array(SlopeA) + # Initialize ALL arrays in Julia + Ptot = @zeros(nx , ny ) + ∇V = @zeros(nx , ny ) + ∇V_ρ_X = @zeros(nx , ny ) + ∇V_ρ_t = @zeros(nx , ny ) + τ_xx = @zeros(nx , ny ) + τ_yy = @zeros(nx , ny ) + τ_xy = @zeros(nx-1, ny-1) + τ_xyn = @zeros(nx , ny ) + Res_Vx = @zeros(nx-1, ny-2) + Res_Vy = @zeros(nx-2, ny-1) + dVxdτ = @zeros(nx-1, ny-2) + dVydτ = @zeros(nx-2, ny-1) + Rho_s_eq = @zeros(nx , ny ) + X_s_eq = @zeros(nx , ny ) + Rho_s_old = @zeros(nx , ny ) + Rho_f_old = @zeros(nx , ny ) + X_s_old = @zeros(nx , ny ) + Rho_X_old = @zeros(nx , ny ) + Phi_old = @zeros(nx , ny ) + Ptot_old = @zeros(nx , ny ) + Pf_old = @zeros(nx , ny ) + Rho_t_old = @zeros(nx , ny ) + Rho_t = @zeros(nx , ny ) + para_cx = @zeros(nx-1, ny ) + para_cy = @zeros(nx , ny-1) + q_f_X = @zeros(nx-1, ny ) + q_f_Y = @zeros(nx , ny-1) + ∇q_f = @zeros(nx-2, ny-2) + Res_Pf = @zeros(nx-2, ny-2) + dPfdτ = @zeros(nx-2, ny-2) + Rho_X_ϕ = @zeros(nx , ny ) + Res_Phi = @zeros(nx , ny ) + ε_xx = @zeros(nx , ny ) + ε_yy = @zeros(nx , ny ) + ε_xy = @zeros(nx-1, ny-1) + τII = @zeros(nx , ny ) + LamP = @zeros(nx , ny ) + LamP2 = @zeros(nx , ny ) + # Arrays for post-processing + dRhoT_dt = @zeros(nx , ny ) + dRhosPhi_dt = @zeros(nx , ny ) + dRhofPhi_dt = @zeros(nx , ny ) + dRhoXPhi_dt = @zeros(nx , ny ) + dPf_dt = @zeros(nx , ny ) + dPt_dt = @zeros(nx , ny ) + dPhi_dt = @zeros(nx , ny ) + dRhos_dt = @zeros(nx , ny ) + # Tmp arrays for swell2 + TmpX = @zeros(nx+1, ny ) + TmpY = @zeros(nx , ny+1) + TmpS1 = @zeros(nx , ny-1) + # Initialisation + Phi_ini = ϕ_ini * ones(nx, ny) + Pert = Data.Array((ϕ_amp .* Phi_ini .- Phi_ini) .* exp.(.-(X_rot ./ rad_a) .^ 2 .- (Y_rot ./ rad_b) .^ 2)) + Phi_ini = Data.Array(Phi_ini) + Phi = Phi_ini .+ Pert + if do_Pf_pert + Phi_ini = ϕ_ini * ones(nx, ny) + Phi = copy(Phi_ini) + end + Eta = η_m * @ones(nx, ny) # Shear viscosity, alternative init: # @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) + Lam = λ_η * @ones(nx, ny) # Bulk viscosity, alternative init: # @all(Lam) = λ_η*@all(Eta) + Vx = ε_bg * Data.Array(Yc2vx) # Simple shear, shearing in x + Vy = 0.0 * Data.Array(Yc2vy) # Simple shear, zero velocity in y + Pf = Data.Array(Pf) + Ptot .= Pf + # Parameters for time loop and pseudo-transient iterations + max_dxdy2 = max(dx, dy) .^ 2 + timeP = 0.0 # Initial time + it = 0 # Integer count for iteration loop + itp = 0 # Integer count for time loop + Time_vec = [] + ρ_i_Pf = cfl * Re_Pf / nx + ρ_i_V = cfl * Re_V / nx + dampPf = damping .* (1.0 .- ρ_i_Pf) + dampV = damping .* (1.0 .- ρ_i_V) + do_save && (dirname = "output_$(runid)_$(nx)x$(ny)"; !ispath(dirname) && mkdir(dirname)) + # time loop + while timeP < time_tot && itp < nt + if do_restart + restart_file = joinpath(@__DIR__, dirname, "dehy_") * @sprintf("%04d", irestart) * ".mat" + vars_restart = matread(restart_file) + Ptot .= Data.Array( get(vars_restart, "Ptot", 1) ) + Pf .= Data.Array( get(vars_restart, "Pf", 1) ) + X_s .= Data.Array( get(vars_restart, "X_s", 1) ) + Phi .= Data.Array( get(vars_restart, "Phi", 1) ) + Phi_ini .= Data.Array( get(vars_restart, "Phi_ini", 1) ) + Rho_s .= Data.Array( get(vars_restart, "Rho_s", 1) ) + Rho_f .= Data.Array( get(vars_restart, "Rho_f", 1) ) + Vx .= Data.Array( get(vars_restart, "Vx", 1) ) + Vy .= Data.Array( get(vars_restart, "Vy", 1) ) + LamP2 .= Data.Array( get(vars_restart, "LamP2", 1) ) + Rho_s_old .= Data.Array( get(vars_restart, "Rho_s_old", 1) ) + Rho_f_old .= Data.Array( get(vars_restart, "Rho_f_old", 1) ) + X_s_old .= Data.Array( get(vars_restart, "X_s_old", 1) ) + Rho_X_old .= Data.Array( get(vars_restart, "Rho_X_old", 1) ) + Phi_old .= Data.Array( get(vars_restart, "Phi_old", 1) ) + Ptot_old .= Data.Array( get(vars_restart, "Ptot_old", 1) ) + Pf_old .= Data.Array( get(vars_restart, "Pf_old", 1) ) + Rho_t_old .= Data.Array( get(vars_restart, "Rho_t_old", 1) ) + Time_vec = get(vars_restart, "Time_vec", 1) + itp = get(vars_restart, "itp", 1) + timeP = get(vars_restart, "timeP", 1) + it = get(vars_restart, "it", 1) + it_tstep = get(vars_restart, "it_tstep", 1) + end + err_M = 2*tol; itp += 1 + timeP += dtp; push!(Time_vec, timeP) + if do_Pf_pert + # Necessary only of Pf-perturbation is applied + (itp == 1) && @parallel compute_1_ini!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η, Rho_s_amb, X_s_amb) + (itp > 1) && @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η) + else + @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η) + end + kin_time = Kin_time_vec[itp] + # PT loop + it_tstep = 0; err_evo1 = []; err_evo2 = []; err_pl = [] + dt_Stokes, dt_Pf = cfl * max_dxdy2, cfl * max_dxdy2 + dt_Pt = maximum(Eta) / (lx / dx) + while err_M > tol && it_tstep < itmax + it += 1; it_tstep += 1 + if it_tstep % 500 == 0 || it_tstep == 1 + max_Eta = maximum(Eta) + dt_Stokes = cfl * max_dxdy2 / max_Eta * (2 - ρ_i_V) / 1.5 # Pseudo time step for Stokes + dt_Pf = cfl * max_dxdy2 / maximum(k_ηf .* Phi .^ n_p * (4.0 * K_s) / 5.0) # Pseudo time step for fluid pressure + dt_Pt = r * Re_V * max_Eta * dx / lx + end + # Fluid pressure evolution + @parallel compute_2!(Rho_t, para_cx, para_cy, Rho_f, Phi, Rho_s, k_ηf, n_p) + @parallel compute_3!(q_f_X, q_f_Y, para_cx, para_cy, Pf, dx, dy) + @parallel compute_4!(∇q_f, Res_Pf, Rho_f, Rho_s_eq, X_s_eq, q_f_X, q_f_Y, Rho_t, Rho_t_old, ∇V_ρ_t, Pf, SlopeA, rho_f_maxA, ρ_0, p_reactA, rho_s_difA, rho_s_up, rho_s_minA, x_difA, x_minA, dtp, dx, dy) + if (itp > 1) @parallel compute_5!(X_s, Rho_s, X_s_old, X_s_eq, Rho_s_old, Rho_s_eq, dtp, kin_time) end + # Porosity evolution + @parallel compute_6!(dPfdτ, Pf, Rho_X_ϕ, Res_Phi, Phi, Res_Pf, Rho_s, X_s, Phi_old, Rho_X_old, ∇V_ρ_X, dampPf, dt_Pf, dtp) + @parallel (1:size(Pf, 1)) bc_y!(Pf) + @parallel (1:size(Pf, 2)) bc_x!(Pf) + # Stokes + @parallel swell2_x!(TmpX, Rho_X_ϕ) + @parallel swell2_y!(TmpY, Rho_X_ϕ) + @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) + @parallel laplace!(∇V_ρ_X, TmpX, TmpY, dx, dy) + @parallel swell2_x!(TmpX, Rho_t) + @parallel swell2_y!(TmpY, Rho_t) + @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) + @parallel laplace!(∇V_ρ_t, TmpX, TmpY, dx, dy) + @parallel compute_7!(Eta, Lam, ∇V, ε_xx, ε_yy, ε_xy, Ptot, Vx, Vy, Phi, Ptot_old, Pf, Pf_old, dt_Pt, η_m, ϕ_exp, ϕ_ini, λ_η, dtp, K_d, η_min, α, dx, dy) + @parallel compute_8!(τ_xx, τ_yy, τ_xy, Eta, ε_xx, ε_yy, ε_xy) + @parallel swell2_x!(TmpS1, τ_xy) + @parallel swell2_y!(τ_xyn, TmpS1) + # Plastic starts + @parallel compute_plast_1!(τII, LamP, τ_xx, τ_yy, τ_xyn, σ_y) + @parallel compute_plast_2!(τ_xx, τ_yy, τ_xy, LamP) + @parallel swell2_x!(TmpS1, τ_xy) + @parallel swell2_y!(τ_xyn, TmpS1) + @parallel compute_plast_3!(τII, LamP2, τ_xx, τ_yy, τ_xyn, LamP) + # Plastic ends + @parallel compute_9!(Res_Vx, Res_Vy, τ_xx, τ_yy, Ptot, τ_xy, dx, dy) + @parallel compute_10!(dVxdτ, dVydτ, Vx, Vy, Res_Vx, Res_Vy, dampV, dt_Stokes) + if it_tstep % nout == 0 && it_tstep > 250 + err_R_Mx = maximum(abs.(Res_Vx)) # Error horizontal force balance + err_R_My = maximum(abs.(Res_Vy)) # Error vertical force balance + err_R_Pf = maximum(abs.(Res_Pf[2:end-1, 2:end-1])) # Error total mass conservation + err_R_Phi = maximum(abs.(Res_Phi[2:end-1, 2:end-1])) # Error MgO mass conservation + err_M = maximum([err_R_Pf, err_R_Mx, err_R_My, err_R_Phi]) # Error total + if isnan(err_M) error("NoNs - stopping simulation.") end + err_evo1 = push!(err_evo1, it_tstep); err_evo2 = push!(err_evo2, err_M) + err_pl = push!(err_pl, maximum(τII) / σ_y - 1.0) + @printf("iter = %d, error = %1.3e \n", it_tstep, err_M) + end + end # end PT loop + println("it = $(itp), time = $(round(timeP, sigdigits=3)) (time_tot = $(round(time_tot, sigdigits=3)))") + if do_save && (itp % nsave == 0 || itp == 1) + @parallel postprocess!(dRhoT_dt, dRhosPhi_dt, dRhofPhi_dt, dRhoXPhi_dt, dPf_dt, dPt_dt, dPhi_dt, dRhos_dt, Rho_s, Rho_f, X_s, Phi, Rho_s_old, Rho_f_old, Rho_X_old, Phi_old, Rho_t, Rho_t_old, Pf, Pf_old, Ptot, Ptot_old, dtp) + matwrite(joinpath(@__DIR__, dirname, "dehy_") * @sprintf("%04d", itp) * ".mat", + Dict("Ptot" => Array(Ptot), + "Pf" => Array(Pf), + "divV" => Array(∇V), + "X_s" => Array(X_s), + "Rho_s" => Array(Rho_s), + "Phi" => Array(Phi), + "Phi_ini" => Array(Phi_ini), + "Rho_f" => Array(Rho_f), + "TauII" => Array(τII), + "Eta" => Array(Eta), + "Tauxx" => Array(τ_xx), + "Tauyy" => Array(τ_yy), + "Tauxy" => Array(τ_xy), + "Vx" => Array(Vx), + "Vy" => Array(Vy), + "Ellipse_x" => Array(X_elli), + "Ellipse_y" => Array(Y_elli), + "Time_vec" => Array(Time_vec), + "LamP2" => Array(LamP2), + "Rho_s_old" => Array(Rho_s_old), + "Rho_f_old" => Array(Rho_f_old), + "X_s_old" => Array(X_s_old), + "Rho_X_old" => Array(Rho_X_old), + "Phi_old" => Array(Phi_old), + "Ptot_old" => Array(Ptot_old), + "Pf_old" => Array(Pf_old), + "Rho_t_old" => Array(Rho_t_old), + "Lam" => Array(Lam), + "dRhoT_dt" => Array(dRhoT_dt), + "dRhosPhi_dt" => Array(dRhosPhi_dt), + "dRhofPhi_dt" => Array(dRhofPhi_dt), + "dRhoXPhi_dt" => Array(dRhoXPhi_dt), + "dPf_dt" => Array(dPf_dt), + "dPt_dt" => Array(dPt_dt), + "dPhi_dt" => Array(dPhi_dt), + "dRhos_dt" => Array(dRhos_dt), + "Res_pf" => Array(Res_Pf), + "div_qf" => Array(∇q_f), + "div_rhoTvs" => Array(∇V_ρ_t), + "div_rhoXvs" => Array(∇V_ρ_X), + "Ch_ti_fluid_dif_phi" => τ_f_dif_ϕ, "Ch_ti_kinetic" => τ_kinetic, "Ch_ti_relaxation" => τ_relax, + "itp" => itp, "timeP" => timeP, "it" => it, "it_tstep" => it_tstep, + "xc" => Array(xc), "yc"=> Array(yc)); compress = true) + end + (run_test && itp==1) && break + end + return (run_test ? (xc, yc, Pf, Phi) : nothing) +end + +@static if !run_test + PT_HMC(; nx=959, ny=959, do_save=true, run_test) +else + xc, yc, Pf, Phi = PT_HMC(; do_save=false, run_test) +end \ No newline at end of file diff --git a/scripts_2022/LOOK_UP_atg.mat b/scripts/LOOK_UP_atg.mat similarity index 94% rename from scripts_2022/LOOK_UP_atg.mat rename to scripts/LOOK_UP_atg.mat index 721c25d..77eea02 100644 Binary files a/scripts_2022/LOOK_UP_atg.mat and b/scripts/LOOK_UP_atg.mat differ diff --git a/scripts/vizme_DeHy.jl b/scripts/vizme_DeHy.jl new file mode 100644 index 0000000..fc2c48f --- /dev/null +++ b/scripts/vizme_DeHy.jl @@ -0,0 +1,62 @@ +using CairoMakie +using MAT +using Printf + +@views avx(A) = 0.5 * (A[1:end-1, :] + A[2:end, :]) +@views avy(A) = 0.5 * (A[:, 1:end-1] + A[:, 2:end]) + +fnum = (1, 500, 1000, 2000) # user input - which steps to save + +label = ("a)", "b)", "c)", "d)") +fig = Figure(resolution=(1000,400), fontsize=20) +axs = Array{Any}(undef, 4) + +for il in eachindex(fnum) + nsave = @sprintf("%04d", fnum[il]) + vars = matread("dehy_$(nsave).mat") + Chi = get(vars, "Ch_ti_fluid_dif_phi", missing) + xc = get(vars, "xc", missing) + yc = get(vars, "yc", missing) + timeP = get(vars, "timeP", missing) + # Scales + rho_0 = 3000 # Density scale [kg/m^3] + Pi_Pa = 1 / 12.75e8 # Stress scale [1/Pa] + t_char = Chi # Characteristc time + nx = length(xc) + st = 20 + rng = 1:st:nx + # read vars + Pf = get(vars, "Pf", missing) + Phi = get(vars, "Phi", missing) + Rho_s = get(vars, "Rho_s", missing) + Vx = get(vars, "Vx", missing) + Vy = get(vars, "Vy", missing) + Vx, Vy = avx(Vx), avy(Vy) + + axs[il] = Axis(fig[1,il][1,1]; aspect=DataAspect(), xlabel="x/r", width = 250, height = 250) + + plt = ( p1 = heatmap!(axs[il], xc, yc, Rho_s * rho_0 ; colorrange = (2550, 3150), colormap=Reverse(:lapaz)), + p2 = contour!(axs[il], xc, yc, Pf / Pi_Pa / 1e8, levels=[12.7, 12.7], color = :black), + p3 = contour!(axs[il], xc, yc, Phi , levels=[0.15, 0.15], color = :magenta), + p4 = arrows!(axs[il], xc[rng], yc[rng], Vx[rng, rng], Vy[rng,rng]; lengthscale=2.0, arrowsize=9, color=:gray), + ) + + axs[il].title = "$(label[il]) time/tc = $(@sprintf("%1.4f", timeP/t_char))" + limits!(axs[il], -7, 7, -7, 7) + + (il > 1) && hideydecorations!(axs[il], grid=false) + axs[1].ylabel = "y/r" + + subgrid = GridLayout(fig[1, 4][1, 2], tellheight = false) + Label(subgrid[1, 1], "ρₛ [kg⋅m⁻¹]") + Colorbar(subgrid[2, 1], plt.p1; halign=:left) + + e1, e2 = LineElement(color = :black, linestyle = nothing), LineElement(color = :magenta, linestyle = nothing) + Legend(fig[1, 1], [e1, e2], ["p_f = 12.7 kbar", "ϕ = 0.15"], + halign = :right, valign = :top, margin = (7, 7, 7, 7), labelsize = 14) +end + +resize_to_layout!(fig) +display(fig) + +# save("viz_dehy.png", fig) \ No newline at end of file diff --git a/scripts_2020/HMC_Public.m b/scripts_2020/HMC_Public.m deleted file mode 100644 index c8738ce..0000000 --- a/scripts_2020/HMC_Public.m +++ /dev/null @@ -1,342 +0,0 @@ -function [ ] = HMC_PT_DIV(); -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% PSEUDO-TRANSIENT FINITE DIFFERENCE CODE FOR HYDRO-MECHANICAL-CHEMICAL SIMULATION OF BRUCITE-PERICLASE REACTIONS -% Stefan Schmalholz, May 2020 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -clear all, close all, clc -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% IMPORT DATA for DENSITIES AND MASS FRACTION OF MgO IN SOLID for T = 800 C -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -load LOOK_UP_HMC_Pub -RHO_s_LU = Rho_s_07; % Precalculated solid density as function of fluid pressure -Rho_f_LU = Rho_f; % Precalculated fluid density as function of fluid pressure -X_LU = X_s_vec; % Precalculated mass fraction of MgO as function of fluid pressure -P_LU = P_vec*1e8; % Corresponding fluid pressure array; converted to Pa -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% NUMERICAL MODEL -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% === INPUT INPUT INPUT =================================================== -% Independent parameters -radius = 1; % Radius of initial P-perturbation [m] -eta_mat = 1; % Viscosity scale [Pa s] -P_ini = 1; % Initial ambient pressure [Pa] -rho_0 = 3000; % Density scale [kg/m^3] -% Nondimensional parameters -ellipse_factor = 3.0; % Use 1 for circle -angle = 30; % Counterclockwise angle of long axis with respect to vertical direction -phi_ini = 2e-3; % Initial porosity -eta_incl_fac = 1e-3; % Factor, how much solid SHEAR viscosity of inclusion is larger (factor>1) or smaller than surrounding -lambda_incl_fac = 1; % Factor, how much solid BULK viscosity of inclusion is larger (factor>1) or smaller than surrounding -n_exp = 3; % Stress exponent of matrix; n=1 means linear viscous -% ------------------------------------------------------------------------- -lam_eta = 1e0; % lam_eta = lambda / eta_mat; []; Ratio of bulk to shear viscosity -Lc_rad2 = 1e8; % Lc_rad2 = k_etaf*eta_mat/radius^2; []; Ratio of hydraulic fluid extraction to compaction extraction -Da = 0.0024; % Da = eb*eta_mat/P_ini; []; Ratio of viscous stress to initial stress -sig_yield = 0.024; % Stress_ref / P_ini; []; Reference stress used for power-law viscous flow law -Lx_rad = 10; % Model width divided by inclusion radius -Ly_Lx = 1; % Model height divided by model width -Pini_Pappl = P_ini/8.5e8; % Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table -% Dependant parameters -beta_eff = 1e-2/P_ini; % Effective compressibility used only to determine PT time step [1/Pa] -k_etaf = Lc_rad2*radius^2/eta_mat; % Permeability divided by fluid viscosity; [m^2/(Pa s)] -P_pert = 0.2*P_ini; % Pressure perturbation [Pa] -lambda = lam_eta*eta_mat; % Bulk viscosity [Pa s] -eb = Da*P_ini/eta_mat; % Background strain rate in matrix [1/s] -stress_ref = sig_yield *P_ini; % Stress reference for power-law viscosity -Lx = Lx_rad*radius; % Model width [m] -Ly = Ly_Lx*Lx; % Model height [m] -P_LU = P_LU*Pini_Pappl; % Transform look-up table stress to PT stress scale -% Numerical resolution -nx = 101; % Numerical resolution width -ny = nx; % Numerical resolution height -tol = 10^(-5); % Tolerance for pseudo-transient iterations -cfl = 1/16.1; % CFL parameter for PT-Stokes solution -dtp = 2e0*radius^2/(k_etaf/beta_eff); % Time step physical -time_tot = 1*dtp; % Total time of simulation -% === INPUT INPUT INPUT =================================================== -% Configuration of grid, matrices and numerical parameters -dx = Lx/(nx-1); % Grid spacing -dy = Ly/(ny-1); % Grid spacing -X1d = [-Lx/2:dx:Lx/2]; % Coordinate vector -Y1d = [-Ly/2:dy:Ly/2]; % Coordinate vector -[X2D, Y2D ] = ndgrid(X1d, Y1d); % Mesh coordinates -Pf = P_ini*ones(nx, ny); % Initial ambient fluid pressure -Ptot = Pf; % Initial total pressure -rad_a = radius; -rad_b = rad_a*ellipse_factor; -X_ROT = X2D*cosd(angle)+Y2D*sind(angle); -Y_ROT = -X2D*sind(angle)+Y2D*cosd(angle); -Pf(sqrt(X_ROT.^2./rad_a^2+Y_ROT.^2./rad_b^2)<1) = P_ini-P_pert; % Fluid pressure petubation -X_Ellipse = rad_a*cos([0:0.01:2*pi])*cosd(angle)+rad_b*sin([0:0.01:2*pi])*sind(angle); -Y_Ellipse = -rad_a*cos([0:0.01:2*pi])*sind(angle)+rad_b*sin([0:0.01:2*pi])*cosd(angle); -ELLIPSE_XY = [-X_Ellipse; Y_Ellipse]; -for smo=1:3 % Smooting of perturbation - Ii = [2:nx-1]; - Pf(Ii,:) = Pf(Ii,:) + 0.4*(Pf(Ii+1,:)-2*Pf(Ii,:)+Pf(Ii-1,:)); - Pf(:,Ii) = Pf(:,Ii) + 0.4*(Pf(:,Ii+1)-2*Pf(:,Ii)+Pf(:,Ii-1)); -end -Pf_inip = Pf; -% Density, compressibility and gamma from concentration and pressure from thermodynamic data base -RHO_S = interp1(P_LU(:,1),RHO_s_LU ,Pf, 'linear') /rho_0; -RHO_F = interp1(P_LU(:,1),Rho_f_LU ,Pf, 'linear') /rho_0; -X_S = interp1(P_LU(:,1),X_LU ,Pf, 'linear') ; -RHO_S_ini = interp1(P_LU(:,1),RHO_s_LU ,P_ini*ones(nx, ny), 'linear') /rho_0; -X_S_ini = interp1(P_LU(:,1),X_LU ,P_ini*ones(nx, ny), 'linear') ; -% Initialize required matrices (or arrays) -PHI_INI = phi_ini*ones(nx, ny); -PHI = PHI_INI; -K_DARCY = k_etaf*ones(nx, ny); -DIVV = zeros(nx, ny); -DIVV_RHO_X = zeros(nx, ny); -DIVV_RHO_T = zeros(nx, ny); -TAUXX = zeros(nx, ny); % Deviatoric stress -TAUYY = zeros(nx, ny); % Deviatoric stress -TAUXY = zeros(nx-1,ny-1); % Deviatoric stress -% Centered coordinates needed for staggered grid for solid velocities -X1d_vx = [X1d(1)-dx/2,( X1d(1:end-1) + X1d(2:end) )/2,X1d(end)+dx/2]; % Horizontal vector for Vx which is one more than basic grid -Y1d_vy = [Y1d(1)-dy/2,( Y1d(1:end-1) + Y1d(2:end) )/2,Y1d(end)+dy/2]; % Verical vector for Vy which is one more than basic grid -[X2D_vx,Y2D_vx] = ndgrid(X1d_vx, Y1d); -[X2D_vy,Y2D_vy] = ndgrid(X1d, Y1d_vy); -VX = -eb*X2D_vx; % Pure shear, shortening in x -VY = eb*Y2D_vy; % Pure shear, extension in y -% Parameters for time loop and pseudo-transient iterations -time = 0; % Initial time -it = 0; % Integer count for iteration loop -itp = 0; % Integer count for time loop -save_count = 0; -Time_vec = [0]; -% === TIME LOOP === -while time < time_tot - err_M = 1e10; % Error at beginning of each PT interation - itp = itp + 1; - time = time + dtp; - Time_vec = [Time_vec time]; - RHO_S_old = RHO_S; - RHO_F_old = RHO_F; - X_S_old = X_S; - RHO_X_old = RHO_S_old.*X_S_old; - PHI_old = PHI; - Ptot_old = Ptot; - if itp==1 - RHO_X_INI = RHO_S_ini.*X_S_ini; - PHI_old = 1 - (RHO_X_INI).*(1-phi_ini)./RHO_X_old; - PHI_ini = PHI_old; - PHI = PHI_old; - end - RHO_T_old = RHO_F_old.*PHI_old + RHO_S_old.*(1-PHI_old); - Ind_incl = find(PHI>(max(PHI(:))+min(PHI(:)))/2); - ETA_MAT = eta_mat*ones(nx, ny); % Ambient viscosity - ETA_MAT(Ind_incl) = eta_mat*eta_incl_fac; % Inclusion viscosity - ETA_PL = ETA_MAT; - ETA = ETA_MAT; - LAMBDA = lambda*ones(nx, ny); % Viscosity - LAMBDA(Ind_incl) = lambda*lambda_incl_fac; % Fluid pressure petubation - % === PSEUDO-TIME LOOP === - it_tstep = 0; - itmax = 3e4; - while err_M > tol & it_tstep1 - ETA_PL_old_ptit = ETA_PL; % Previous PT viscosity - ETA_PL = ETA_MAT.*(TII/stress_ref).^(1-n_exp); - relax = 0.5; - ETA_PL(TII250 - err_Mx = max(abs(dt_Stokes*RES_VX(:)))/max(abs(VX(:))); % Error horizontal velocitiy - err_My = max(abs(dt_Stokes*RES_VY(:)))/max(abs(VY(:))); % Error vertical velocity - err_Pf = max(abs(dt_Pf*RES_Pf(:)))/max(abs(Pf(:))); % Error fluid pressure - err_Phi = max(abs(dtp*RES_PHI(:))); % Error porosity - err_M = max([err_Pf, err_Mx, err_My, err_Phi]); % Error total - % === PLOT ERROR EVOLUTION === - if mod(it_tstep,2e3)==1 | it_tstep==251 - plot(it,log10(err_Mx),'ko'),hold on;plot(it,log10(err_My),'rd');plot(it,log10(err_Pf),'ks');plot(it,log10(err_Phi),'b+'); - plot([0 it+200],[log10(tol) log10(tol)],'-r','linewidth',2) - legend('Error Vx','Error Vy','Error Pf','Error \phi','Tolerance','Location','Northwest'); grid on;xlabel('Total iterations');ylabel('log_{10} Error') - drawnow - end - end - % === END PSEUDO-TIME LOOP === - end - -end - -% ========================================================================= -% === VISUALIZATION ======================================================= -% ========================================================================= -figure(2) -ax = [-5 5 -5 5]; -sp = 5; -colormap(jet) -% Parameters for scaling results for specific values of parameters -Length_model_m = radius; -Time_model_sec = radius^2/(k_etaf/beta_eff); -Length_phys_meter = 0.01; -Time_phys_sec = 0.01^2/(1e-19/1e-3/(1e-2/8.5e8)); -Vel_phys_m_s = (Length_phys_meter/Length_model_m) / (Time_phys_sec/Time_model_sec); - -subplot('position',[0.1 0.72 0.25 0.25]) -pcolor(X2D,Y2D,Pf/Pini_Pappl/1e8); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--k','linewidth',1) -title('A) p_f [kbar]') -axis equal; axis(ax) -ylabel('Height / radius [ ]') - -subplot('position',[0.36 0.72 0.25 0.25]) -pcolor(X2D,Y2D,Ptot/Pini_Pappl/1e8); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['B) p [kbar]']) -axis equal; axis(ax) - -subplot('position',[0.62 0.72 0.25 0.25]) -pcolor(X2D,Y2D,DIVV*Time_model_sec/Time_phys_sec); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['C) \nabla(v_s) [1/s]']) -axis equal; axis(ax) - -Length_model_m = radius; -Time_model_sec = radius^2/(k_etaf/beta_eff); -Length_phys_meter = 0.01; -Time_phys_sec = 0.01^2/(1e-19/1e-3/(1e-2/8.5e8)); -Vel_phys_m_s = (Length_phys_meter/Length_model_m) / (Time_phys_sec/Time_model_sec); - -subplot('position',[0.1 0.4 0.25 0.25]) -pcolor(X2D,Y2D,sqrt(VX_f.^2+VY_f.^2)*Vel_phys_m_s); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['D) [ (v_x^f)^2 + (v_y^f)^2 ]^{1/2} [m/s]']) -ylabel('Height / radius [ ]') -axis equal; axis(ax) - -subplot('position',[0.36 0.4 0.25 0.25]) -VX_C = (VX(1:end-1,:)+VX(2:end,:))/2; -VY_C = (VY(:,1:end-1)+VY(:,2:end))/2; -pcolor(X2D,Y2D,sqrt(VX_C.^2+VY_C.^2)*Vel_phys_m_s); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['E) [ (v_x^s)^2 + (v_y^s)^2 ]^{1/2} [m/s]']) -axis equal; axis(ax) - -subplot('position',[0.62 0.4 0.25 0.25]) -pcolor(X2D,Y2D,sqrt(VX_f_Ptot.^2+VY_f_Ptot.^2)*Vel_phys_m_s); -col=colorbar; shading interp;hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['F) [ (v_x^f^p)^2 + (v_y^f^p)^2 ]^{1/2} [m/s]']) -axis equal; axis(ax) - -X2D_C = ( X2D( 1:end-1,:) + X2D( 2:end,:) )/2; -X2D_C = ( X2D_C(:,1:end-1) + X2D_C(:,2:end) )/2; -Y2D_C = ( Y2D( 1:end-1,:) + Y2D( 2:end,:) )/2; -Y2D_C = ( Y2D_C(:,1:end-1) + Y2D_C(:,2:end) )/2; - -subplot('position',[0.1 0.08 0.25 0.25]) -pcolor(X2D_C,Y2D_C,TAUXY/Pini_Pappl/1e6); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['G) \tau_{xy} [MPa]']) -axis equal; axis(ax) -ylabel('Height / radius [ ]') -xlabel('Width / radius [ ]'); - -subplot('position',[0.36 0.08 0.25 0.25]) -pcolor(X2D,Y2D,TII/Pini_Pappl/1e6); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -axis equal -axis(ax) -title(['H) \tau_{II} [MPa]']) -xlabel('Width / radius [ ]'); %ylabel('Height / radius [ ]') - -subplot('position',[0.62 0.08 0.25 0.25]) -caxis([-0.1 0.05]) -pcolor(X2D,Y2D,ETA*1e20); -col=colorbar; shading interp;hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['I) \eta^s [Pas]']) -axis equal; axis(ax) -xlabel('Width / radius [ ]'); %ylabel('Height / radius [ ]') - -set(gcf,'position',[524.2000 79.8000 986.4000 698.4000]) - -% ========================================================================= -% === ADDITIONAL FUNCTION -% ========================================================================= -function [B] = swell2(A,ndim); -% Logic: assume 3 points x1 x2 x3 and that the "extended" array is xe -% we have 2 equations (assuming linear extrapolations) -% 1: xe1 + xe2 = 2*x1 -% 2: xe2 = (x1+x2)/2 -%Substitute the second into the first and solve for xe1 gives -% xe1 + x1/2 + x2/2 = (4/2)*x1 -> xe1 = 3/2*x1 -1/2*x2 -if ndim == 1 - B = zeros(size(A,1)+1,size(A,2)); - % B(2:end-1,:) = ava2(A,ndim); - B(2:end-1,:) = (A(2:end,:) + A(1:end-1,:))/2; - B(1, :) = 1.5*A(1,:) -0.5*A(2,:); - B(end,:) = 1.5*A(end,:) -0.5*A(end-1,:); -elseif ndim ==2 - B = zeros(size(A,1),size(A,2)+1); - % B(:,2:end-1) = ava2(A,ndim); - B(:,2:end-1) = (A(:,2:end) + A(:,1:end-1))/2; - B(:,1 ) = 1.5*A(:,1) -0.5*A(:,2); - B(:,end) = 1.5*A(:,end) -0.5*A(:,end-1); -end -return; diff --git a/scripts_2020/HMC_Public_analytical.m b/scripts_2020/HMC_Public_analytical.m deleted file mode 100644 index 54c22e4..0000000 --- a/scripts_2020/HMC_Public_analytical.m +++ /dev/null @@ -1,369 +0,0 @@ -function [ ] = HMC_PT_DIV(); -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% PSEUDO-TRANSIENT FINITE DIFFERENCE CODE FOR HYDRO-MECHANICAL-CHEMICAL SIMULATION OF BRUCITE-PERICLASE REACTIONS -% Stefan Schmalholz, July 2020 -% Input parameters are explained by comments in the same line. -% Mentioned equation numbers, figure numbers or parameters refer to the -% corresponding manuscript of Schmalholz et al., submitted to G-Cubed -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -clear all, close all, clc -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% IMPORT DATA for DENSITIES AND MASS FRACTION OF MgO IN SOLID for T = 800 C -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -load LOOK_UP_HMC_Pub -RHO_s_LU = Rho_s_07; % Precalculated solid density as function of fluid pressure -Rho_f_LU = Rho_f; % Precalculated fluid density as function of fluid pressure -X_LU = X_s_vec; % Precalculated mass fraction of MgO as function of fluid pressure -P_LU = P_vec*1e8; % Corresponding fluid pressure array; converted to Pa -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% NUMERICAL MODEL -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% === INPUT INPUT INPUT =================================================== -% Independent parameters -radius = 1; % Radius of initial P-perturbation [m] -eta_mat = 1; % Viscosity scale [Pa s] -P_ini = 1; % Initial ambient pressure [Pa] -rho_0 = 3000; % Density scale [kg/m^3] -% Nondimensional parameters -ellipse_factor = 3.0; % Use 1 for circle -angle = 30; % Counterclockwise angle of long axis with respect to vertical direction -phi_ini = 2e-3; % Initial porosity -eta_incl_fac = 1e-3; % Factor, how much solid SHEAR viscosity of inclusion is larger (factor>1) or smaller than surrounding -lambda_incl_fac = 1; % Factor, how much solid BULK viscosity of inclusion is larger (factor>1) or smaller than surrounding -n_exp = 3; % Stress exponent of matrix; n=1 means linear viscous -% ------------------------------------------------------------------------- -Lx_rad = 10; % LAMBDA_1 in equation (15) in the manuscript; Model width divided by inclusion radius; -Lc_rad2 = 1e8; % LAMBDA_2 in equation (15) in the manuscript; Lc_rad2 = k_etaf*eta_mat/radius^2; []; Ratio of hydraulic fluid extraction to compaction extraction -lam_eta = 1e0; % LAMBDA_3 in equation (15) in the manuscript; lam_eta = lambda / eta_mat; []; Ratio of bulk to shear viscosity -Da = 0.0024; % LAMBDA_4 in equation (15) in the manuscript; Da = eb*eta_mat/P_ini; []; Ratio of viscous stress to initial stress -sig_yield = 0.024; % LAMBDA_5 in equation (15) in the manuscript; Stress_ref / P_ini; []; Reference stress used for power-law viscous flow law -Ly_Lx = 1; % Model height divided by model width -Pini_Pappl = P_ini/8.5e8; % Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table -% Dependant parameters -beta_eff = 1e-2/P_ini; % Effective compressibility used only to determine PT time step [1/Pa] -k_etaf = Lc_rad2*radius^2/eta_mat; % Permeability divided by fluid viscosity; [m^2/(Pa s)] -P_pert = 0.2*P_ini; % Pressure perturbation [Pa] -lambda = lam_eta*eta_mat; % Bulk viscosity [Pa s] -eb = Da*P_ini/eta_mat; % Background strain rate in matrix [1/s] -stress_ref = sig_yield *P_ini; % Stress reference for power-law viscosity -Lx = Lx_rad*radius; % Model width [m] -Ly = Ly_Lx*Lx; % Model height [m] -P_LU = P_LU*Pini_Pappl; % Transform look-up table stress to PT stress scale -% Numerical resolution -nx = 101; % Numerical resolution width -ny = nx; % Numerical resolution height -tol = 10^(-5); % Tolerance for pseudo-transient iterations -cfl = 1/16.1; % CFL parameter for PT-Stokes solution -dtp = 2e0*radius^2/(k_etaf/beta_eff); % Time step physical -time_tot = 1*dtp; % Total time of simulation -% === INPUT INPUT INPUT =================================================== -% Configuration of grid, matrices and numerical parameters -dx = Lx/(nx-1); % Grid spacing -dy = Ly/(ny-1); % Grid spacing -X1d = [-Lx/2:dx:Lx/2]; % Coordinate vector -Y1d = [-Ly/2:dy:Ly/2]; % Coordinate vector -[X2D, Y2D ] = ndgrid(X1d, Y1d); % Mesh coordinates -Pf = P_ini*ones(nx, ny); % Initial ambient fluid pressure -Ptot = Pf; % Initial total pressure -rad_a = radius; -rad_b = rad_a*ellipse_factor; -X_ROT = X2D*cosd(angle)+Y2D*sind(angle); -Y_ROT = -X2D*sind(angle)+Y2D*cosd(angle); -Pf(sqrt(X_ROT.^2./rad_a^2+Y_ROT.^2./rad_b^2)<1) = P_ini-P_pert; % Fluid pressure petubation -X_Ellipse = rad_a*cos([0:0.01:2*pi])*cosd(angle)+rad_b*sin([0:0.01:2*pi])*sind(angle); -Y_Ellipse = -rad_a*cos([0:0.01:2*pi])*sind(angle)+rad_b*sin([0:0.01:2*pi])*cosd(angle); -ELLIPSE_XY = [-X_Ellipse; Y_Ellipse]; -for smo=1:2 % Smooting of initial perturbation - Ii = [2:nx-1]; - Pf(Ii,:) = Pf(Ii,:) + 0.4*(Pf(Ii+1,:)-2*Pf(Ii,:)+Pf(Ii-1,:)); - Pf(:,Ii) = Pf(:,Ii) + 0.4*(Pf(:,Ii+1)-2*Pf(:,Ii)+Pf(:,Ii-1)); -end -Pf_inip = Pf; - -% ANALYTICAL FIT OF LOOK-UP TABLE -p_min_ana = min(P_LU); -p_max_ana = max(P_LU); -rho_s_up = 100; -slope_ana = (Pf-p_min_ana)./p_max_ana*rho_s_up; -slope_ini_ana = (P_ini*ones(nx, ny)-p_min_ana)./p_max_ana*rho_s_up; -rho_s_max = RHO_s_LU(1) ;%max(RHO_s_LU); -rho_s_min_ana = min(RHO_s_LU); -rho_s_dif_ana = rho_s_max-rho_s_min_ana; -p_reaction_ana = 7.85*1e8*Pini_Pappl; -rho_f_min_ana = min(Rho_f_LU); -fac_ana = 6e3; -x_max = max(X_LU); -x_min_ana = min(X_LU); -x_dif_ana = x_max-x_min_ana; -% ANALYTICAL FIT OF LOOK-UP TABLE - -% Density, compressibility and gamma from concentration and pressure from thermodynamic data base -% RHO_S = interp1(P_LU(:,1),RHO_s_LU ,Pf, 'linear') /rho_0; -% RHO_F = interp1(P_LU(:,1),Rho_f_LU ,Pf, 'linear') /rho_0; -% X_S = interp1(P_LU(:,1),X_LU ,Pf, 'linear') ; -% RHO_S_ini = interp1(P_LU(:,1),RHO_s_LU ,P_ini*ones(nx, ny), 'linear') /rho_0; -% X_S_ini = interp1(P_LU(:,1),X_LU ,P_ini*ones(nx, ny), 'linear') ; -RHO_S = (-tanh( 5e2*(Pf-p_reaction_ana) ) *rho_s_dif_ana/2 + rho_s_dif_ana/2 + rho_s_min_ana + slope_ana ) /rho_0; -RHO_F = (rho_f_min_ana-fac_ana*p_min_ana.^(1/20) + fac_ana*(Pf).^(1/20)) /rho_0; -X_S = -tanh( 5e2*(Pf-p_reaction_ana) ) *x_dif_ana/2 + x_dif_ana/2 + x_min_ana; -RHO_S_ini = (-tanh( 5e2*(P_ini*ones(nx, ny)-p_reaction_ana) ) *rho_s_dif_ana/2 + rho_s_dif_ana/2 + rho_s_min_ana + slope_ini_ana ) /rho_0; -X_S_ini = -tanh( 5e2*(P_ini*ones(nx, ny)-p_reaction_ana) ) *x_dif_ana/2 + x_dif_ana/2 + x_min_ana; -% Initialize required matrices (or arrays) -PHI_INI = phi_ini*ones(nx, ny); -PHI = PHI_INI; -K_DARCY = k_etaf*ones(nx, ny); -DIVV = zeros(nx, ny); -DIVV_RHO_X = zeros(nx, ny); -DIVV_RHO_T = zeros(nx, ny); -TAUXX = zeros(nx, ny); % Deviatoric stress -TAUYY = zeros(nx, ny); % Deviatoric stress -TAUXY = zeros(nx-1,ny-1); % Deviatoric stress -% Centered coordinates needed for staggered grid for solid velocities -X1d_vx = [X1d(1)-dx/2,( X1d(1:end-1) + X1d(2:end) )/2,X1d(end)+dx/2]; % Horizontal vector for Vx which is one more than basic grid -Y1d_vy = [Y1d(1)-dy/2,( Y1d(1:end-1) + Y1d(2:end) )/2,Y1d(end)+dy/2]; % Verical vector for Vy which is one more than basic grid -[X2D_vx,Y2D_vx] = ndgrid(X1d_vx, Y1d); -[X2D_vy,Y2D_vy] = ndgrid(X1d, Y1d_vy); -VX = -eb*X2D_vx; % Pure shear, shortening in x -VY = eb*Y2D_vy; % Pure shear, extension in y -% Parameters for time loop and pseudo-transient iterations -time = 0; % Initial time -it = 0; % Integer count for iteration loop -itp = 0; % Integer count for time loop -save_count = 0; -Time_vec = [0]; -% === TIME LOOP === -while time < time_tot - err_M = 1e10; % Error at beginning of each PT interation - itp = itp + 1; - time = time + dtp; - Time_vec = [Time_vec time]; - RHO_S_old = RHO_S; - RHO_F_old = RHO_F; - X_S_old = X_S; - RHO_X_old = RHO_S_old.*X_S_old; - PHI_old = PHI; - Ptot_old = Ptot; - if itp==1 - RHO_X_INI = RHO_S_ini.*X_S_ini; - PHI_old = 1 - (RHO_X_INI).*(1-phi_ini)./RHO_X_old; - PHI_ini = PHI_old; - PHI = PHI_old; - end - RHO_T_old = RHO_F_old.*PHI_old + RHO_S_old.*(1-PHI_old); - Ind_incl = find(PHI>(max(PHI(:))+min(PHI(:)))/2); - ETA_MAT = eta_mat*ones(nx, ny); % Ambient viscosity - ETA_MAT(Ind_incl) = eta_mat*eta_incl_fac; % Inclusion viscosity - ETA_PL = ETA_MAT; - ETA = ETA_MAT; - LAMBDA = lambda*ones(nx, ny); % Viscosity - LAMBDA(Ind_incl) = lambda*lambda_incl_fac; % Fluid pressure petubation - % === PSEUDO-TIME ITERATION LOOP === - it_tstep = 0; - itmax = 3e4; - while err_M > tol & it_tstep1 - ETA_PL_old_ptit = ETA_PL; % Previous PT viscosity - ETA_PL = ETA_MAT.*(TII/stress_ref).^(1-n_exp); - relax = 0.5; - ETA_PL(TII250 - err_Mx = max(abs(dt_Stokes*RES_VX(:)))/max(abs(VX(:))); % Error horizontal velocitiy - err_My = max(abs(dt_Stokes*RES_VY(:)))/max(abs(VY(:))); % Error vertical velocity - err_Pf = max(abs(dt_Pf*RES_Pf(:)))/max(abs(Pf(:))); % Error fluid pressure - err_Phi = max(abs(dtp*RES_PHI(:))); % Error porosity - err_M = max([err_Pf, err_Mx, err_My, err_Phi]); % Error total - % === PLOT ERROR EVOLUTION === - if mod(it_tstep,2e3)==1 | it_tstep==251 - plot(it,log10(err_Mx),'ko'),hold on;plot(it,log10(err_My),'rd');plot(it,log10(err_Pf),'ks');plot(it,log10(err_Phi),'b+'); - plot([0 it+200],[log10(tol) log10(tol)],'-r','linewidth',2) - legend('Error Vx','Error Vy','Error Pf','Error \phi','Tolerance','Location','Northwest'); grid on;xlabel('Total iterations');ylabel('log_{10} Error') - drawnow - end - end - end % === END PSEUDO-TIME ITERATION LOOP === -end % === END TIME LOOP === - -% ========================================================================= -% === VISUALIZATION ======================================================= -% ========================================================================= -figure(2) -ax = [-5 5 -5 5]; -sp = 5; -colormap(jet) -% Parameters for scaling results for specific values of parameters -Length_model_m = radius; -Time_model_sec = radius^2/(k_etaf/beta_eff); -Length_phys_meter = 0.01; -Time_phys_sec = 0.01^2/(1e-19/1e-3/(1e-2/8.5e8)); -Vel_phys_m_s = (Length_phys_meter/Length_model_m) / (Time_phys_sec/Time_model_sec); - -subplot('position',[0.1 0.72 0.25 0.25]) -pcolor(X2D,Y2D,Pf/Pini_Pappl/1e8); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--k','linewidth',1) -title('A) p_f [kbar]') -axis equal; axis(ax) -ylabel('Height / radius [ ]') - -subplot('position',[0.36 0.72 0.25 0.25]) -pcolor(X2D,Y2D,Ptot/Pini_Pappl/1e8); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['B) p [kbar]']) -axis equal; axis(ax) - -subplot('position',[0.62 0.72 0.25 0.25]) -pcolor(X2D,Y2D,DIVV*Time_model_sec/Time_phys_sec); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['C) \nabla(v_s) [1/s]']) -axis equal; axis(ax) - -Length_model_m = radius; -Time_model_sec = radius^2/(k_etaf/beta_eff); -Length_phys_meter = 0.01; -Time_phys_sec = 0.01^2/(1e-19/1e-3/(1e-2/8.5e8)); -Vel_phys_m_s = (Length_phys_meter/Length_model_m) / (Time_phys_sec/Time_model_sec); - -subplot('position',[0.1 0.4 0.25 0.25]) -pcolor(X2D,Y2D,sqrt(VX_f.^2+VY_f.^2)*Vel_phys_m_s); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['D) [ (v_x^f)^2 + (v_y^f)^2 ]^{1/2} [m/s]']) -ylabel('Height / radius [ ]') -axis equal; axis(ax) - -subplot('position',[0.36 0.4 0.25 0.25]) -VX_C = (VX(1:end-1,:)+VX(2:end,:))/2; -VY_C = (VY(:,1:end-1)+VY(:,2:end))/2; -pcolor(X2D,Y2D,sqrt(VX_C.^2+VY_C.^2)*Vel_phys_m_s); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['E) [ (v_x^s)^2 + (v_y^s)^2 ]^{1/2} [m/s]']) -axis equal; axis(ax) - -subplot('position',[0.62 0.4 0.25 0.25]) -pcolor(X2D,Y2D,sqrt(VX_f_Ptot.^2+VY_f_Ptot.^2)*Vel_phys_m_s); -col=colorbar; shading interp;hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['F) [ (v_x^f^p)^2 + (v_y^f^p)^2 ]^{1/2} [m/s]']) -axis equal; axis(ax) - -X2D_C = ( X2D( 1:end-1,:) + X2D( 2:end,:) )/2; -X2D_C = ( X2D_C(:,1:end-1) + X2D_C(:,2:end) )/2; -Y2D_C = ( Y2D( 1:end-1,:) + Y2D( 2:end,:) )/2; -Y2D_C = ( Y2D_C(:,1:end-1) + Y2D_C(:,2:end) )/2; - -subplot('position',[0.1 0.08 0.25 0.25]) -pcolor(X2D_C,Y2D_C,TAUXY/Pini_Pappl/1e6); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['G) \tau_{xy} [MPa]']) -axis equal; axis(ax) -ylabel('Height / radius [ ]') -xlabel('Width / radius [ ]'); - -subplot('position',[0.36 0.08 0.25 0.25]) -pcolor(X2D,Y2D,TII/Pini_Pappl/1e6); -col=colorbar; shading interp; hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -axis equal -axis(ax) -title(['H) \tau_{II} [MPa]']) -xlabel('Width / radius [ ]'); %ylabel('Height / radius [ ]') - -subplot('position',[0.62 0.08 0.25 0.25]) -caxis([-0.1 0.05]) -pcolor(X2D,Y2D,ETA*1e20); -col=colorbar; shading interp;hold on -plot(ELLIPSE_XY(1,:),ELLIPSE_XY(2,:),'--w','linewidth',1) -title(['I) \eta^s [Pas]']) -axis equal; axis(ax) -xlabel('Width / radius [ ]'); %ylabel('Height / radius [ ]') - -set(gcf,'position',[524.2000 79.8000 986.4000 698.4000]) - -% ========================================================================= -% === ADDITIONAL FUNCTION -% ========================================================================= -function [B] = swell2(A,ndim); -% Logic: assume 3 points x1 x2 x3 and that the "extended" array is xe -% we have 2 equations (assuming linear extrapolations) -% 1: xe1 + xe2 = 2*x1 -% 2: xe2 = (x1+x2)/2 -%Substitute the second into the first and solve for xe1 gives -% xe1 + x1/2 + x2/2 = (4/2)*x1 -> xe1 = 3/2*x1 -1/2*x2 -if ndim == 1 - B = zeros(size(A,1)+1,size(A,2)); - % B(2:end-1,:) = ava2(A,ndim); - B(2:end-1,:) = (A(2:end,:) + A(1:end-1,:))/2; - B(1, :) = 1.5*A(1,:) -0.5*A(2,:); - B(end,:) = 1.5*A(end,:) -0.5*A(end-1,:); -elseif ndim ==2 - B = zeros(size(A,1),size(A,2)+1); - % B(:,2:end-1) = ava2(A,ndim); - B(:,2:end-1) = (A(:,2:end) + A(:,1:end-1))/2; - B(:,1 ) = 1.5*A(:,1) -0.5*A(:,2); - B(:,end) = 1.5*A(:,end) -0.5*A(:,end-1); -end -return; diff --git a/scripts_2020/LOOK_UP_HMC_Pub.mat b/scripts_2020/LOOK_UP_HMC_Pub.mat deleted file mode 100644 index 1d093b6..0000000 Binary files a/scripts_2020/LOOK_UP_HMC_Pub.mat and /dev/null differ diff --git a/scripts_2020/PT_HMC_bru.jl b/scripts_2020/PT_HMC_bru.jl deleted file mode 100644 index 97a8568..0000000 --- a/scripts_2020/PT_HMC_bru.jl +++ /dev/null @@ -1,412 +0,0 @@ -const run_test = haskey(ENV, "RUN_TEST") ? parse(Bool, ENV["RUN_TEST"]) : false -const USE_GPU = haskey(ENV, "USE_GPU" ) ? parse(Bool, ENV["USE_GPU"] ) : true -const GPU_ID = haskey(ENV, "GPU_ID" ) ? parse(Int, ENV["GPU_ID"] ) : 0 -const do_viz = haskey(ENV, "DO_VIZ" ) ? parse(Bool, ENV["DO_VIZ"] ) : true -const nx = haskey(ENV, "NX" ) ? parse(Int , ENV["NX"] ) : 383 -const ny = haskey(ENV, "NY" ) ? parse(Int , ENV["NY"] ) : 383 -### -using ParallelStencil -using ParallelStencil.FiniteDifferences2D -@static if USE_GPU - @init_parallel_stencil(CUDA, Float64, 2) - CUDA.device!(GPU_ID) # select GPU -else - @init_parallel_stencil(Threads, Float64, 2) -end -using Plots, Printf, Statistics, LinearAlgebra, MAT, Interpolations -################################################## -@views av_xy(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) -@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) -@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) -@views function swell2s!(B, A, ndim) - B .= B.*0.0 - if ndim==1 - B[2:end-1,:] .= (A[2:end,:] .+ A[1:end-1,:])./2.0 - B[1 ,:] .= 1.5*A[1 ,:] .- 0.5*A[2 ,:] - B[end ,:] .= 1.5*A[end,:] .- 0.5*A[end-1,:] - elseif ndim==2 - B[:,2:end-1] .= (A[:,2:end] .+ A[:,1:end-1])./2.0 - B[:,1 ] .= 1.5*A[:,1 ] .- 0.5*A[:,2 ] - B[:,end ] .= 1.5*A[:,end] .- 0.5*A[:,end-1] - end - return B -end - -@parallel_indices (ix,iy) function swell2!(B::Data.Array, A::Data.Array, ndim::Int) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if ndim==1 - if (2<=ix<=size(B,1)-1 && iy<=size(B,2)) B[ix,iy] = 0.5*(A[ix ,iy] + A[ix-1,iy]) end - if ( ix==1 && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix ,iy] - 0.5*A[ix+1,iy] end - if ( ix==size(B,1) && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix-1,iy] - 0.5*A[ix-2,iy] end - elseif ndim==2 - if (ix<=size(B,1) && 2<=iy<=size(B,2)-1) B[ix,iy] = 0.5*(A[ix,iy ] + A[ix,iy-1]) end - if (ix<=size(B,1) && iy==1 ) B[ix,iy] = 1.5*A[ix,iy ] - 0.5*A[ix,iy+1] end - if (ix<=size(B,1) && iy==size(B,2) ) B[ix,iy] = 1.5*A[ix,iy-1] - 0.5*A[ix,iy-2] end - end - return -end - -@parallel function cum_mult2!(A1::Data.Array, A2::Data.Array, B1::Data.Array, B2::Data.Array) - @all(A1) = @all(A1)*@all(B1) - @all(A2) = @all(A2)*@all(B2) - return -end - -@parallel function laplace!(A::Data.Array, TmpX::Data.Array, TmpY::Data.Array, _dx::Data.Number, _dy::Data.Number) - @all(A) = @d_xa(TmpX)*_dx + @d_ya(TmpY)*_dy - return -end -################################################## - -@parallel function compute_1!(Rho_s_old::Data.Array, Rho_f_old::Data.Array, X_s_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Ptot_old::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Ptot::Data.Array) - @all(Rho_s_old) = @all(Rho_s) - @all(Rho_f_old) = @all(Rho_f) - @all(X_s_old) = @all(X_s) - @all(Phi_old) = @all(Phi) - @all(Ptot_old) = @all(Ptot) - @all(Rho_X_old) = @all(Rho_s_old)*@all(X_s_old) - return -end - -@parallel function compute_2!(Rho_X_ini::Data.Array, Phi_old::Data.Array, Phi_ini::Data.Array, Phi::Data.Array, Rho_s_ini::Data.Array, X_s_ini::Data.Array, Rho_X_old::Data.Array, ϕ_ini::Data.Number) - @all(Rho_X_ini) = @all(Rho_s_ini)*@all(X_s_ini) - @all(Phi_old) = 1.0 - @all(Rho_X_ini)*(1.0-ϕ_ini)/@all(Rho_X_old) - @all(Phi_ini) = @all(Phi_old) - @all(Phi) = @all(Phi_old) - return -end - -@parallel_indices (ix,iy) function compute_3!(Eta_m::Data.Array, Lam::Data.Array, Phi::Data.Array, η_m::Data.Number, η_i_fac::Data.Number, λ::Data.Number, λ_i_fac::Data.Number, max_min_ϕ_2::Data.Number) - if (ix<=size(Eta_m,1) && iy<=size(Eta_m,2)) - if (Phi[ix,iy]>max_min_ϕ_2) Eta_m[ix,iy] = η_m*η_i_fac; else Eta_m[ix,iy] = η_m; end - end - if (ix<=size(Lam,1) && iy<=size(Lam,2)) - if (Phi[ix,iy]>max_min_ϕ_2) Lam[ix,iy] = λ*λ_i_fac; else Lam[ix,iy] = λ; end - end - return -end - -@parallel function compute_4!(Eta_pl::Data.Array, Eta::Data.Array, Rho_t_old::Data.Array, Eta_m::Data.Array, Rho_f_old::Data.Array, Phi_old::Data.Array, Rho_s_old::Data.Array) - @all(Eta_pl) = @all(Eta_m) - @all(Eta) = @all(Eta_m) - @all(Rho_t_old) = @all(Rho_f_old)*@all(Phi_old) + @all(Rho_s_old)*(1.0 - @all(Phi_old)) - return -end - -@parallel_indices (ix,iy) function compute_5!(Rho_t::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Rho_f::Data.Array, Phi::Data.Array, Rho_s::Data.Array, K_ηf::Data.Array) - if (ix<=size(Rho_t,1) && iy<=size(Rho_t,2)) Rho_t[ix,iy] = Rho_f[ix,iy]*Phi[ix,iy] + Rho_s[ix,iy]*(1.0-Phi[ix,iy]) end - if (ix<=size(para_cx,1) && iy<=size(para_cx,2)) para_cx[ix,iy] = 0.5*( Rho_f[ix,iy]*K_ηf[ix,iy]*Phi[ix,iy]^3 + Rho_f[ix+1,iy]*K_ηf[ix+1,iy]*Phi[ix+1,iy]^3 ) end - if (ix<=size(para_cy,1) && iy<=size(para_cy,2)) para_cy[ix,iy] = 0.5*( Rho_f[ix,iy]*K_ηf[ix,iy]*Phi[ix,iy]^3 + Rho_f[ix,iy+1]*K_ηf[ix,iy+1]*Phi[ix,iy+1]^3 ) end - return -end - -@parallel function compute_6!(q_f_X::Data.Array, q_f_Y::Data.Array, q_f_X_Ptot::Data.Array, q_f_Y_Ptot::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Pf::Data.Array, Ptot::Data.Array, _dx::Data.Number, _dy::Data.Number) - @all(q_f_X) = -@all(para_cx)*@d_xa(Pf)*_dx # Correct Darcy flux with fluid pressure - @all(q_f_Y) = -@all(para_cy)*@d_ya(Pf)*_dy # Correct Darcy flux with fluid pressure - @all(q_f_X_Ptot) = -@all(para_cx)*@d_xa(Ptot)*_dx # Incorrect Darcy flux with total pressure - @all(q_f_Y_Ptot) = -@all(para_cy)*@d_ya(Ptot)*_dy # Incorrect Darcy flux with total pressure - return -end - -@parallel function compute_7!(∇q_f::Data.Array, Res_Pf::Data.Array, q_f_X::Data.Array, q_f_Y::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, ∇V_ρ_t::Data.Array, dtp::Data.Number, _dx::Data.Number, _dy::Data.Number) - @all(∇q_f) = @d_xi(q_f_X)*_dx + @d_yi(q_f_Y)*_dy - @all(Res_Pf) = -@all(∇q_f) -(@inn(Rho_t) - @inn(Rho_t_old))/dtp - @inn(∇V_ρ_t) # CONSERVATION OF TOTAL MASS EQUATION - return -end - -@parallel function compute_8!(Pf::Data.Array, Rho_X_ϕ::Data.Array, Res_Phi::Data.Array, Phi::Data.Array, Res_Pf::Data.Array, Rho_s::Data.Array, X_s::Data.Array, Phi_old::Data.Array, Rho_X_old::Data.Array, ∇V_ρ_x::Data.Array, dt_Pf::Data.Number, dtp::Data.Number, _dx::Data.Number, _dy::Data.Number) - @inn(Pf) = @inn(Pf) + dt_Pf*@all(Res_Pf) - @all(Rho_X_ϕ) = (1.0-@all(Phi))*@all(Rho_s)*@all(X_s) - @all(Res_Phi) = ( @all(Rho_X_ϕ) - (1.0-@all(Phi_old))*@all(Rho_X_old) )/dtp + @all(∇V_ρ_x) # CONSERVATION OF MASS OF MgO EQUATION - @all(Phi) = @all(Phi) + dtp*@all(Res_Phi) - return -end - - -@parallel function compute_9!(∇V::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array, Ptot::Data.Array, Vx::Data.Array, Vy::Data.Array, Phi::Data.Array, Pf::Data.Array, Lam::Data.Array, _dx::Data.Number, _dy::Data.Number) - @all(∇V) = _dx*@d_xa(Vx) + _dy*@d_ya(Vy) - @all(ε_xx) = _dx*@d_xa(Vx) - 1/3*@all(∇V) - @all(ε_yy) = _dy*@d_ya(Vy) - 1/3*@all(∇V) - @all(ε_xy) = 0.5*(_dy*@d_yi(Vx) + _dx*@d_xi(Vy)) - @all(Ptot) = @all(Pf) - @all(∇V)*(1.0-@all(Phi))*@all(Lam) - return -end - -@parallel function compute_10!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, Eta::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array) - @all(τ_xx) = 2.0*@all(Eta) * @all(ε_xx) - @all(τ_yy) = 2.0*@all(Eta) * @all(ε_yy) - @all(τ_xy) = 2.0*@av(Eta) * @all(ε_xy) - return -end - -@parallel function compute_11!(τII::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, Ptot::Data.Array, τ_xy::Data.Array, _dx::Data.Number, _dy::Data.Number) - @all(τII) = sqrt( 0.25*(@all(τ_xx)-@all(τ_yy))^2 + @all(τ_xyn)^2 ) - @all(Res_Vx) = -@d_xi(Ptot)*_dx + @d_xi(τ_xx)*_dx + @d_ya(τ_xy)*_dy # HORIZONTAL FORCE BALANCE - @all(Res_Vy) = -@d_yi(Ptot)*_dy + @d_yi(τ_yy)*_dy + @d_xa(τ_xy)*_dx # VERTICAL FORCE BALANCE - return -end - -@parallel_indices (ix,iy) function compute_12!(Eta_iter::Data.Array, Eta_pl::Data.Array, Eta::Data.Array, Eta_m::Data.Array, τII::Data.Array, σ_ref::Data.Number, n_exp::Data.Number, relax::Data.Number) - if (ix<=size(Eta_iter,1) && iy<=size(Eta_iter,2)) Eta_iter[ix,iy] = Eta_pl[ix,iy] end # Previous PT viscosity - if (ix<=size(Eta_pl,1) && iy<=size(Eta_pl,2)) Eta_pl[ix,iy] = Eta_m[ix,iy]*(τII[ix,iy]/σ_ref)^(1-n_exp) end - if (ix<=size(Eta_pl,1) && iy<=size(Eta_pl,2)) if (τII[ix,iy]<σ_ref) Eta_pl[ix,iy] = Eta_m[ix,iy]; end; end #η_m - if (ix<=size(Eta_pl,1) && iy<=size(Eta_pl,2)) Eta_pl[ix,iy] = exp(log(Eta_pl[ix,iy])*relax + log(Eta_iter[ix,iy])*(1-relax)) end - if (ix<=size(Eta,1) && iy<=size(Eta,2)) Eta[ix,iy] = 2.0/( 1.0/Eta_m[ix,iy] + 1.0/Eta_pl[ix,iy] ) end - return -end - -@parallel function compute_13!(Vx::Data.Array, Vy::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, dt_Stokes::Data.Number) - @inn(Vx) = @inn(Vx) + dt_Stokes*@all(Res_Vx) # Pseudo-transient form of horizontal force balance - @inn(Vy) = @inn(Vy) + dt_Stokes*@all(Res_Vy) # Pseudo-transient form of vertical force balance - return -end -################################################## -@views function PT_HMC_() - runid = "bru" - # read in mat file - vars = matread(string(@__DIR__, "/LOOK_UP_HMC_Pub.mat")) - Rho_s_LU = get(vars, "Rho_s_07",1) - Rho_f_LU = get(vars, "Rho_f" ,1) - X_LU = get(vars, "X_s_vec" ,1) - P_LU = get(vars, "P_vec" ,1)*1e8 - # Independent parameters - rad = 1.0 # rad of initial P-perturbation [m] - η_m = 1.0 # Viscosity scale [Pa s] - P_ini = 1.0 # Initial ambient pressure [Pa] - ρ_0 = 3000.0 # Density scale [kg/m^3] - # Nondimensional parameters - elli_fac = 3.0 # Use 1 for circle - α = 30.0 # Counterclockwise α of long axis with respect to vertical direction - ϕ_ini = 2e-3 # Initial porosity - η_i_fac = 1e-3 # Factor, how much solid SHEAR viscosity of inclusion is larger (factor>1) or smaller than surrounding - λ_i_fac = 1.0 # Factor, how much solid BULK viscosity of inclusion is larger (factor>1) or smaller than surrounding - n_exp = 3.0 # Stress exponent of matrix; n=1 means linear viscous - λ_η = 1e0 # λ_η = λ / η_m; []; Ratio of bulk to shear viscosity - lc_rad2 = 1e8 # lc_rad2 = k_ηf*η_m/rad^2; []; Ratio of hydraulic fluid extraction to compaction extraction - Da = 0.0024 # Da = ε_bg*η_m/P_ini; []; Ratio of viscous stress to initial stress - σ_y = 0.024 # Stress_ref / P_ini; []; Reference stress used for power-law viscous flow law - lx_rad = 10.0 # Model width divided by inclusion rad - ly_lx = 1.0 # Model height divided by model width - Pini_Pappl = P_ini/8.5e8 # Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table - # Dependant parameters - β_eff = 1e-2/P_ini # Effective compressibility used only to determine PT time step [1/Pa] - k_ηf = lc_rad2*rad^2/η_m # Permeability divided by fluid viscosity; [m^2/(Pa s)] - P_pert = 0.2*P_ini # Pressure perturbation [Pa] - λ = λ_η*η_m # Bulk viscosity [Pa s] - ε_bg = Da*P_ini/η_m # Background strain rate in matrix [1/s] - σ_ref = σ_y*P_ini # Stress reference for power-law viscosity - lx = lx_rad*rad # Model width [m] - ly = ly_lx*lx # Model height [m] - P_LU = P_LU*Pini_Pappl # Transform look-up table stress to PT stress scale - # Numerical resolution - tol = 2e-5 # Tolerance for pseudo-transient iterations - cfl = 1.0/16.1 # CFL parameter for PT-Stokes solution - dtp = 2e0*rad^2/(k_ηf/β_eff) # Time step physical - time_tot = 1.0*dtp # Total time of simulation - relax = 0.5 - itmax = 5e4 - nout = 1e3 - # Configuration of grid, matrices and numerical parameters - dx, dy = lx/(nx-1), ly/(ny-1) # Grid spacing - xc, yc = -lx/2:dx:lx/2, -ly/2:dy:ly/2 # Coordinate vector - xv, yv = -lx/2-dx/2:dx:lx/2+dx/2, -ly/2-dy/2:dy:ly/2+dy/2 # Horizontal vector for Vx which is one more than basic grid - (Xc2, Yc2) = ([x for x=xc,y=yc], [y for x=xc,y=yc]) - (Xc2vx, Yc2vx) = ([x for x=xv, y=yc], [y for x=xv, y=yc]) - (Xc2vy, Yc2vy) = ([x for x=xc, y=yv], [y for x=xc, y=yv]) - rad_a = rad - rad_b = rad_a*elli_fac - X_rot = Xc2*cosd(α)+Yc2*sind(α) - Y_rot = -Xc2*sind(α)+Yc2*cosd(α) - X_elli = rad_a.*cos.(0:0.01:2*pi).*cosd(α).+rad_b.*sin.(0:0.01:2*pi).*sind(α) - Y_elli = -rad_a.*cos.(0:0.01:2*pi).*sind(α).+rad_b.*sin.(0:0.01:2*pi).*cosd(α) - XY_elli = (-X_elli, Y_elli) - # Initial ambient fluid pressure - Pf = P_ini*ones(nx, ny) - Pf[sqrt.(X_rot.^2.0./rad_a.^2.0 .+ Y_rot.^2.0./rad_b.^2) .< 1.0] .= P_ini - P_pert # Fluid pressure petubation - for smo=1:5 # Smooting of perturbation - Pf[2:end-1,:] .= Pf[2:end-1,:] .+ 0.4.*(Pf[3:end,:].-2.0.*Pf[2:end-1,:].+Pf[1:end-2,:]) - Pf[:,2:end-1] .= Pf[:,2:end-1] .+ 0.4.*(Pf[:,3:end].-2.0.*Pf[:,2:end-1].+Pf[:,1:end-2]) - end - # Density, compressibility and gamma from concentration and pressure from thermodynamic data base - itp1 = interpolate( (P_LU[:,1],), Rho_s_LU[:,1], Gridded(Linear())) - itp2 = interpolate( (P_LU[:,1],), Rho_f_LU[:,1], Gridded(Linear())) - itp3 = interpolate( (P_LU[:,1],), X_LU[:,1], Gridded(Linear())) - Rho_s = Data.Array( itp1.(Pf)./ρ_0 ) - Rho_f = Data.Array( itp2.(Pf)./ρ_0 ) - X_s = Data.Array( itp3.(Pf) ) - Rho_s_ini = Data.Array( itp1.(P_ini*ones(nx, ny))./ρ_0 ) - X_s_ini = Data.Array( itp3.(P_ini*ones(nx, ny)) ) - # Initialize ALL arrays in Julia - Ptot = @zeros(nx , ny ) # Initial ambient fluid pressure - ∇V = @zeros(nx , ny ) - ∇V_ρ_x = @zeros(nx , ny ) - ∇V_ρ_t = @zeros(nx , ny ) - τ_xx = @zeros(nx , ny ) # Deviatoric stress - τ_yy = @zeros(nx , ny ) # Deviatoric stress - τ_xy = @zeros(nx-1, ny-1) # Deviatoric stress - τ_xyn = @zeros(nx , ny ) - Res_Vx = @zeros(nx-1, ny-2) - Res_Vy = @zeros(nx-2, ny-1) - Rho_s_old = @zeros(nx , ny ) - Rho_f_old = @zeros(nx , ny ) - X_s_old = @zeros(nx , ny ) - Rho_X_old = @zeros(nx , ny ) - Phi_old = @zeros(nx , ny ) - Ptot_old = @zeros(nx , ny ) - Rho_X_ini = @zeros(nx , ny ) - Rho_t_old = @zeros(nx , ny ) - Rho_t = @zeros(nx , ny ) - para_cx = @zeros(nx-1, ny ) - para_cy = @zeros(nx , ny-1) - q_f_X = @zeros(nx-1, ny ) - q_f_Y = @zeros(nx , ny-1) - q_f_X_Ptot = @zeros(nx-1, ny ) - q_f_Y_Ptot = @zeros(nx , ny-1) - ∇q_f = @zeros(nx-2, ny-2) - Res_Pf = @zeros(nx-2, ny-2) - Rho_X_ϕ = @zeros(nx , ny ) - Res_Phi = @zeros(nx , ny ) - ε_xx = @zeros(nx , ny ) - ε_yy = @zeros(nx , ny ) - ε_xy = @zeros(nx-1, ny-1) - τII = @zeros(nx , ny ) - Eta_iter = @zeros(nx , ny ) - # TMP arrays for swell2 - TmpX = @zeros(nx+1, ny ) - TmpY = @zeros(nx , ny+1) - TmpS1 = @zeros(nx , ny-1) - # arrays for visu - Vx_f = zeros(nx , ny ) - Vy_f = zeros(nx , ny ) - Vx_f_Ptot = zeros(nx , ny ) - VY_f_Ptot = zeros(nx , ny ) - # init - Phi_ini = ϕ_ini*@ones(nx, ny) - Phi = ϕ_ini*@ones(nx, ny) - K_ηf = k_ηf*@ones(nx, ny) - Eta_m = η_m*@ones(nx, ny) - Eta_pl = η_m*@ones(nx, ny) - Eta = η_m*@ones(nx, ny) - Lam = λ*@ones(nx, ny) # Viscosity - Pf_tmp = zeros(nx, ny) - # Data.Array for ParallelStencil - Vx = -ε_bg*Data.Array(Xc2vx) # Pure shear, shortening in x - Vy = ε_bg*Data.Array(Yc2vy) # Pure shear, extension in y - Pf = Data.Array(Pf) - Ptot .= Pf # Initial total pressure - # Parameters for time loop and pseudo-transient iterations - max_dxdy2 = max(dx,dy).^2 - max_min_ϕ_2 = (maximum(Phi)+minimum(Phi))/2.0 - _dx, _dy = 1.0/dx, 1.0/dy - timeP = 0.0 # Initial time - it = 0 # Integer count for iteration loop - itp = 0 # Integer count for time loop - save_count = 0 - Time_vec = [] - if do_viz - !ispath(joinpath(@__DIR__,"../output")) && mkdir(joinpath(@__DIR__,"../output")) - dirname = joinpath(@__DIR__, "../output/output_$(runid)_$(nx)x$(ny)"); !ispath(dirname) && mkdir(dirname) - end - # time loop - while timeP < time_tot - err_M=2*tol; itp+=1.0 - timeP=timeP+dtp; push!(Time_vec, timeP) - @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Rho_s, Rho_f, X_s, Phi, Ptot) - if itp==1 @parallel compute_2!(Rho_X_ini, Phi_old, Phi_ini, Phi, Rho_s_ini, X_s_ini, Rho_X_old, ϕ_ini) end - max_min_ϕ_2 = (maximum(Phi)+minimum(Phi))/2.0 - @parallel compute_3!(Eta_m, Lam, Phi, η_m, η_i_fac, λ, λ_i_fac, max_min_ϕ_2) - @parallel compute_4!(Eta_pl, Eta, Rho_t_old, Eta_m, Rho_f_old, Phi_old, Rho_s_old) - # PT loop - it_tstep=0; err_evo1=[]; err_evo2=[] - dt_Stokes, dt_Pf = cfl*max_dxdy2, cfl*max_dxdy2 - while err_M>tol && it_tstep1 @parallel compute_12!(Eta_iter, Eta_pl, Eta, Eta_m, τII, σ_ref, n_exp, relax) end - @parallel compute_13!(Vx, Vy, Res_Vx, Res_Vy, dt_Stokes) - if mod(it_tstep, nout)==0 && it_tstep>250 - err_Mx = dt_Stokes*maximum(abs.(Res_Vx)/maximum(abs.(Vx))) # Error horizontal velocitiy - err_My = dt_Stokes*maximum(abs.(Res_Vy)/maximum(abs.(Vy))) # Error vertical velocity - err_Pf = dt_Pf*maximum(abs.(Res_Pf)/maximum(abs.(Pf))) # Error fluid pressure - err_Phi = dtp*maximum(abs.(Res_Phi)) # Error porosity - err_M = maximum([err_Pf, err_Mx, err_My, err_Phi]) # Error total - err_evo1 = push!(err_evo1, it_tstep); err_evo2 = push!(err_evo2, err_M) - # plot evol - # p1 = plot(err_evo1, err_evo2, legend=false, xlabel="# iterations", ylabel="log10(error)", linewidth=2, markershape=:circle, markersize=3, labels="max(error)", yaxis=:log10) - # display(p1) - @printf("iter = %d, error = %1.3e \n", it_tstep, err_M) - end - end # end PT loop - end - # Visu - if do_viz - println("iter tot = $it") - swell2s!(Vx_f, Array(q_f_X)./(Array(Rho_f[1:end-1,:])./Array(Phi[1:end-1,:]).+Array(Rho_f[2:end,:])./Array(Phi[2:end,:])).*2.0, 1) - swell2s!(Vy_f, Array(q_f_Y)./(Array(Rho_f[:,1:end-1])./Array(Phi[:,1:end-1]).+Array(Rho_f[:,2:end])./Array(Phi[:,2:end])).*2.0, 2) - swell2s!(Vx_f_Ptot, Array(q_f_X_Ptot)./(Array(Rho_f[1:end-1,:])./Array(Phi[1:end-1,:]).+Array(Rho_f[2:end,:])./Array(Phi[2:end,:])).*2.0, 1) - swell2s!(VY_f_Ptot, Array(q_f_Y_Ptot)./(Array(Rho_f[:,1:end-1])./Array(Phi[:,1:end-1]).+Array(Rho_f[:,2:end])./Array(Phi[:,2:end])).*2.0, 2) - Length_model_m = rad - Time_model_sec = rad^2/(k_ηf/β_eff) - Length_phys_m = 0.01 - Time_phys_sec = 0.01^2/(1e-19/1e-3/(1e-2/8.5e8)) - Vel_phys_m_s = (Length_phys_m/Length_model_m) / (Time_phys_sec/Time_model_sec) - lw = 1.2; TFS = 10 - p2 = heatmap(xc, yc, Array(Pf)'./Pini_Pappl./1e8, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="A) p_f [kbar]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p3 = heatmap(xc, yc, Array(Ptot)'./Pini_Pappl./1e8, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="B) p [kbar]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p4 = heatmap(xc, yc, Array(∇V)'.*Time_model_sec./Time_phys_sec, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="C) ∇(v_s) [1/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p5 = heatmap(xc, yc, sqrt.(Vx_f.^2 .+ Vy_f.^2)'*Vel_phys_m_s, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="D) ||v_f|| [m/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p6 = heatmap(xc, yc, sqrt.(av_xa(Array(Vx)).^2 .+ av_ya(Array(Vy)).^2)'*Vel_phys_m_s, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="E) ||v_s|| [m/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p7 = heatmap(xc, yc, sqrt.(Vx_f_Ptot.^2 .+ VY_f_Ptot.^2)'*Vel_phys_m_s, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="F) ||v_f||p [m/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p8 = heatmap(xv[2:end-1], yv[2:end-1], Array(τ_xy)'/Pini_Pappl/1e6, aspect_ratio=1, xlims=(xv[2], xv[end-1]), ylims=(yv[2], yv[end-1]), c=:hot, title="G) τxy [MPa]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p9 = heatmap(xc, yc, Array(τII)'/Pini_Pappl/1e6, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="H) τII [MPa]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - p10 = heatmap(xc, yc, Array(Eta)'*1e20, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:hot, title="I) ηs [Pas]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false) - display(plot(p2, p3, p4, p5, p6, p7, p8, p9, p10, background_color=:transparent, foreground_color=:gray)) - savefig(joinpath(@__DIR__, dirname, "fig_pt_hmc_bru.png")) - end - return xc, yc, Pf, Phi -end - -if run_test - xc, yc, Pf, Phi = PT_HMC_(); -else - PT_HMC = begin PT_HMC_(); return; end -end diff --git a/scripts_2020/PT_HMC_bru_analytical.jl b/scripts_2020/PT_HMC_bru_analytical.jl deleted file mode 100644 index aa70ad7..0000000 --- a/scripts_2020/PT_HMC_bru_analytical.jl +++ /dev/null @@ -1,443 +0,0 @@ -const run_test = haskey(ENV, "RUN_TEST") ? parse(Bool, ENV["RUN_TEST"]) : false -const USE_GPU = haskey(ENV, "USE_GPU" ) ? parse(Bool, ENV["USE_GPU"] ) : true -const GPU_ID = haskey(ENV, "GPU_ID" ) ? parse(Int, ENV["GPU_ID"] ) : 0 -const do_viz = haskey(ENV, "DO_VIZ" ) ? parse(Bool, ENV["DO_VIZ"] ) : true -const nx = haskey(ENV, "NX" ) ? parse(Int , ENV["NX"] ) : 383 -const ny = haskey(ENV, "NY" ) ? parse(Int , ENV["NY"] ) : 383 -### -using ParallelStencil -using ParallelStencil.FiniteDifferences2D -@static if USE_GPU - @init_parallel_stencil(CUDA, Float64, 2) - CUDA.device!(GPU_ID) # select GPU -else - @init_parallel_stencil(Threads, Float64, 2) -end -using Plots, Printf, Statistics, LinearAlgebra, MAT, Interpolations -################################################## -@views av_xy(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) -@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) -@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) -@views function swell2s!(B, A, ndim) - B .= B.*0.0 - if ndim==1 - B[2:end-1,:] .= (A[2:end,:] .+ A[1:end-1,:])./2.0 - B[1 ,:] .= 1.5*A[1 ,:] .- 0.5*A[2 ,:] - B[end ,:] .= 1.5*A[end,:] .- 0.5*A[end-1,:] - elseif ndim==2 - B[:,2:end-1] .= (A[:,2:end] .+ A[:,1:end-1])./2.0 - B[:,1 ] .= 1.5*A[:,1 ] .- 0.5*A[:,2 ] - B[:,end ] .= 1.5*A[:,end] .- 0.5*A[:,end-1] - end - return B -end - -@parallel_indices (ix,iy) function swell2!(B::Data.Array, A::Data.Array, ndim::Int) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if ndim==1 - if (2<=ix<=size(B,1)-1 && iy<=size(B,2)) B[ix,iy] = 0.5*(A[ix ,iy] + A[ix-1,iy]) end - if ( ix==1 && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix ,iy] - 0.5*A[ix+1,iy] end - if ( ix==size(B,1) && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix-1,iy] - 0.5*A[ix-2,iy] end - elseif ndim==2 - if (ix<=size(B,1) && 2<=iy<=size(B,2)-1) B[ix,iy] = 0.5*(A[ix,iy ] + A[ix,iy-1]) end - if (ix<=size(B,1) && iy==1 ) B[ix,iy] = 1.5*A[ix,iy ] - 0.5*A[ix,iy+1] end - if (ix<=size(B,1) && iy==size(B,2) ) B[ix,iy] = 1.5*A[ix,iy-1] - 0.5*A[ix,iy-2] end - end - return -end - -@parallel function cum_mult2!(A1::Data.Array, A2::Data.Array, B1::Data.Array, B2::Data.Array) - @all(A1) = @all(A1)*@all(B1) - @all(A2) = @all(A2)*@all(B2) - return -end - -@parallel function laplace!(A::Data.Array, TmpX::Data.Array, TmpY::Data.Array, dx::Data.Number, dy::Data.Number) - @all(A) = @d_xa(TmpX)/dx + @d_ya(TmpY)/dy - return -end -################################################## - -@parallel function compute_1!(Rho_s_old::Data.Array, Rho_f_old::Data.Array, X_s_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Ptot_old::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Ptot::Data.Array) - @all(Rho_s_old) = @all(Rho_s) - @all(Rho_f_old) = @all(Rho_f) - @all(X_s_old) = @all(X_s) - @all(Phi_old) = @all(Phi) - @all(Ptot_old) = @all(Ptot) - @all(Rho_X_old) = @all(Rho_s_old)*@all(X_s_old) - return -end - -@parallel function compute_2!(Rho_X_ini::Data.Array, Phi_old::Data.Array, Phi_ini::Data.Array, Phi::Data.Array, Rho_s_ini::Data.Array, X_s_ini::Data.Array, Rho_X_old::Data.Array, ϕ_ini::Data.Number) - @all(Rho_X_ini) = @all(Rho_s_ini)*@all(X_s_ini) - @all(Phi_old) = 1.0 - @all(Rho_X_ini)*(1.0-ϕ_ini)/@all(Rho_X_old) - @all(Phi_ini) = @all(Phi_old) - @all(Phi) = @all(Phi_old) - return -end - -@parallel_indices (ix,iy) function compute_3!(Eta_m::Data.Array, Lam::Data.Array, Phi::Data.Array, η_m::Data.Number, η_i_fac::Data.Number, λ::Data.Number, λ_i_fac::Data.Number, max_min_ϕ_2::Data.Number) - if (ix<=size(Eta_m,1) && iy<=size(Eta_m,2)) - if (Phi[ix,iy]>max_min_ϕ_2) Eta_m[ix,iy] = η_m*η_i_fac; else Eta_m[ix,iy] = η_m; end - end - if (ix<=size(Lam,1) && iy<=size(Lam,2)) - if (Phi[ix,iy]>max_min_ϕ_2) Lam[ix,iy] = λ*λ_i_fac; else Lam[ix,iy] = λ; end - end - return -end - -@parallel function compute_4!(Eta_pl::Data.Array, Eta::Data.Array, Rho_t_old::Data.Array, Eta_m::Data.Array, Rho_f_old::Data.Array, Phi_old::Data.Array, Rho_s_old::Data.Array) - @all(Eta_pl) = @all(Eta_m) - @all(Eta) = @all(Eta_m) - @all(Rho_t_old) = @all(Rho_f_old)*@all(Phi_old) + @all(Rho_s_old)*(1.0 - @all(Phi_old)) - return -end - -@parallel_indices (ix,iy) function compute_5!(Rho_t::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Rho_f::Data.Array, Phi::Data.Array, Rho_s::Data.Array, K_ηf::Data.Array) - if (ix<=size(Rho_t,1) && iy<=size(Rho_t,2)) Rho_t[ix,iy] = Rho_f[ix,iy]*Phi[ix,iy] + Rho_s[ix,iy]*(1.0-Phi[ix,iy]) end - if (ix<=size(para_cx,1) && iy<=size(para_cx,2)) para_cx[ix,iy] = 0.5*( Rho_f[ix,iy]*K_ηf[ix,iy]*Phi[ix,iy]^3 + Rho_f[ix+1,iy]*K_ηf[ix+1,iy]*Phi[ix+1,iy]^3 ) end - if (ix<=size(para_cy,1) && iy<=size(para_cy,2)) para_cy[ix,iy] = 0.5*( Rho_f[ix,iy]*K_ηf[ix,iy]*Phi[ix,iy]^3 + Rho_f[ix,iy+1]*K_ηf[ix,iy+1]*Phi[ix,iy+1]^3 ) end - return -end - -@parallel function compute_6!(q_f_X::Data.Array, q_f_Y::Data.Array, q_f_X_Ptot::Data.Array, q_f_Y_Ptot::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Pf::Data.Array, Ptot::Data.Array, dx::Data.Number, dy::Data.Number) - @all(q_f_X) = -@all(para_cx)*@d_xa(Pf)/dx # Correct Darcy flux with fluid pressure - @all(q_f_Y) = -@all(para_cy)*@d_ya(Pf)/dy # Correct Darcy flux with fluid pressure - @all(q_f_X_Ptot) = -@all(para_cx)*@d_xa(Ptot)/dx # Incorrect Darcy flux with total pressure - @all(q_f_Y_Ptot) = -@all(para_cy)*@d_ya(Ptot)/dy # Incorrect Darcy flux with total pressure - return -end - -# @parallel function compute_7L!(∇q_f::Data.Array, Res_Pf::Data.Array, q_f_X::Data.Array, q_f_Y::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, ∇V_ρ_t::Data.Array, dtp::Data.Number, dx::Data.Number, dy::Data.Number) -# @all(∇q_f) = @d_xi(q_f_X)/dx + @d_yi(q_f_Y)/dy -# @all(Res_Pf) = -@all(∇q_f) -(@inn(Rho_t) - @inn(Rho_t_old))/dtp - @inn(∇V_ρ_t) # CONSERVATION OF TOTAL MASS EQUATION -# return -# end - -@parallel function compute_7!(∇q_f::Data.Array, Res_Pf::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, q_f_X::Data.Array, q_f_Y::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, ∇V_ρ_t::Data.Array, Pf::Data.Array, SlopeA::Data.Array, p_reactA::Data.Number, rho_s_difA::Data.Number, rho_s_minA::Data.Number, ρ_0::Data.Number, rho_f_minA::Data.Number, facA::Data.Number, p_minA::Data.Number, x_difA::Data.Number, x_minA::Data.Number, dtp::Data.Number, dx::Data.Number, dy::Data.Number) - @all(∇q_f) = @d_xi(q_f_X)/dx + @d_yi(q_f_Y)/dy - @all(Res_Pf) = -@all(∇q_f) - (@inn(Rho_t) - @inn(Rho_t_old))/dtp - @inn(∇V_ρ_t) # CONSERVATION OF TOTAL MASS EQUATION - - @all(Rho_s) = (-tanh( 5e2*(@all(Pf)-p_reactA) )*rho_s_difA/2.0 + rho_s_difA/2.0 + rho_s_minA + @all(SlopeA))/ρ_0 - @all(Rho_f) = (rho_f_minA-facA*p_minA^(1/20) .+ facA*@all(Pf)^(1/20))/ρ_0 - @all(X_s) = -tanh( 5e2*(@all(Pf)-p_reactA) )*x_difA/2.0 + x_difA/2.0 + x_minA - return -end - -@parallel function compute_8!(Pf::Data.Array, Rho_X_ϕ::Data.Array, Res_Phi::Data.Array, Phi::Data.Array, Res_Pf::Data.Array, Rho_s::Data.Array, X_s::Data.Array, Phi_old::Data.Array, Rho_X_old::Data.Array, ∇V_ρ_x::Data.Array, dt_Pf::Data.Number, dtp::Data.Number) - @inn(Pf) = @inn(Pf) + dt_Pf*@all(Res_Pf) - @all(Rho_X_ϕ) = (1.0-@all(Phi))*@all(Rho_s)*@all(X_s) - @all(Res_Phi) = ( @all(Rho_X_ϕ) - (1.0-@all(Phi_old))*@all(Rho_X_old) )/dtp + @all(∇V_ρ_x) # CONSERVATION OF MASS OF MgO EQUATION - @all(Phi) = @all(Phi) + dtp*@all(Res_Phi) - return -end - - -@parallel function compute_9!(∇V::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array, Ptot::Data.Array, Vx::Data.Array, Vy::Data.Array, Phi::Data.Array, Pf::Data.Array, Lam::Data.Array, dx::Data.Number, dy::Data.Number) - @all(∇V) = @d_xa(Vx)/dx + @d_ya(Vy)/dy - @all(ε_xx) = @d_xa(Vx)/dx - 1.0/3.0*@all(∇V) - @all(ε_yy) = @d_ya(Vy)/dy - 1.0/3.0*@all(∇V) - @all(ε_xy) = 0.5*(@d_yi(Vx)/dy + @d_xi(Vy)/dx) - @all(Ptot) = @all(Pf) - @all(∇V)*(1.0-@all(Phi))*@all(Lam) - return -end - -@parallel function compute_10!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, Eta::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array) - @all(τ_xx) = 2.0*@all(Eta) * @all(ε_xx) - @all(τ_yy) = 2.0*@all(Eta) * @all(ε_yy) - @all(τ_xy) = 2.0*@av(Eta) * @all(ε_xy) - return -end - -@parallel function compute_11!(τII::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, Ptot::Data.Array, τ_xy::Data.Array, dx::Data.Number, dy::Data.Number) - @all(τII) = sqrt( 0.25*(@all(τ_xx)-@all(τ_yy))^2 + @all(τ_xyn)^2 ) - @all(Res_Vx) = -@d_xi(Ptot)/dx + @d_xi(τ_xx)/dx + @d_ya(τ_xy)/dy # HORIZONTAL FORCE BALANCE - @all(Res_Vy) = -@d_yi(Ptot)/dy + @d_yi(τ_yy)/dy + @d_xa(τ_xy)/dx # VERTICAL FORCE BALANCE - return -end - -@parallel_indices (ix,iy) function compute_12!(Eta_iter::Data.Array, Eta_pl::Data.Array, Eta::Data.Array, Eta_m::Data.Array, τII::Data.Array, σ_ref::Data.Number, n_exp::Data.Number, relax::Data.Number) - if (ix<=size(Eta_iter,1) && iy<=size(Eta_iter,2)) Eta_iter[ix,iy] = Eta_pl[ix,iy] end # Previous PT viscosity - if (ix<=size(Eta_pl,1) && iy<=size(Eta_pl,2)) Eta_pl[ix,iy] = Eta_m[ix,iy]*(τII[ix,iy]/σ_ref)^(1-n_exp) end - if (ix<=size(Eta_pl,1) && iy<=size(Eta_pl,2)) if (τII[ix,iy]<σ_ref) Eta_pl[ix,iy] = Eta_m[ix,iy]; end; end #η_m - if (ix<=size(Eta_pl,1) && iy<=size(Eta_pl,2)) Eta_pl[ix,iy] = exp(log(Eta_pl[ix,iy])*relax + log(Eta_iter[ix,iy])*(1.0-relax)) end - if (ix<=size(Eta,1) && iy<=size(Eta,2)) Eta[ix,iy] = 2.0/( 1.0/Eta_m[ix,iy] + 1.0/Eta_pl[ix,iy] ) end - return -end - -@parallel function compute_13!(Vx::Data.Array, Vy::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, dt_Stokes::Data.Number) - @inn(Vx) = @inn(Vx) + dt_Stokes*@all(Res_Vx) # Pseudo-transient form of horizontal force balance - @inn(Vy) = @inn(Vy) + dt_Stokes*@all(Res_Vy) # Pseudo-transient form of vertical force balance - return -end -################################################## -@views function PT_HMC_() - runid = "bru_analyt" - # read in mat file - vars = matread(string(@__DIR__, "/LOOK_UP_HMC_Pub.mat")) - Rho_s_LU = get(vars, "Rho_s_07",1) - Rho_f_LU = get(vars, "Rho_f" ,1) - X_LU = get(vars, "X_s_vec" ,1) - P_LU = get(vars, "P_vec" ,1)*1e8 - # Independent parameters - rad = 1.0 # rad of initial P-perturbation [m] - η_m = 1.0 # Viscosity scale [Pa s] - P_ini = 1.0 # Initial ambient pressure [Pa] - ρ_0 = 3000.0 # Density scale [kg/m^3] - # Nondimensional parameters - elli_fac = 3.0 # Use 1 for circle - α = 30.0 # Counterclockwise α of long axis with respect to vertical direction - ϕ_ini = 2e-3 # Initial porosity - η_i_fac = 1e-3 # Factor, how much solid SHEAR viscosity of inclusion is larger (factor>1) or smaller than surrounding - λ_i_fac = 1.0 # Factor, how much solid BULK viscosity of inclusion is larger (factor>1) or smaller than surrounding - n_exp = 3.0 # Stress exponent of matrix; n=1 means linear viscous - lx_rad = 10.0 # Model width divided by inclusion rad - lc_rad2 = 1e8 # lc_rad2 = k_ηf*η_m/rad^2; []; Ratio of hydraulic fluid extraction to compaction extraction - λ_η = 1e0 # λ_η = λ / η_m; []; Ratio of bulk to shear viscosity - Da = 0.0024 # Da = ε_bg*η_m/P_ini; []; Ratio of viscous stress to initial stress - σ_y = 0.024 # Stress_ref / P_ini; []; Reference stress used for power-law viscous flow law - ly_lx = 1.0 # Model height divided by model width - Pini_Pappl = P_ini/8.5e8 # Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table - # Dependant parameters - β_eff = 1e-2/P_ini # Effective compressibility used only to determine PT time step [1/Pa] - k_ηf = lc_rad2*rad^2/η_m # Permeability divided by fluid viscosity; [m^2/(Pa s)] - P_pert = 0.2*P_ini # Pressure perturbation [Pa] - λ = λ_η*η_m # Bulk viscosity [Pa s] - ε_bg = Da*P_ini/η_m # Background strain rate in matrix [1/s] - σ_ref = σ_y*P_ini # Stress reference for power-law viscosity - lx = lx_rad*rad # Model width [m] - ly = ly_lx*lx # Model height [m] - P_LU = P_LU*Pini_Pappl # Transform look-up table stress to PT stress scale - # Numerical resolution - tol = 1e-5 # Tolerance for pseudo-transient iterations - cfl = 1/16.1 # CFL parameter for PT-Stokes solution - dtp = 2e0*rad^2/(k_ηf/β_eff) # Time step physical - time_tot = 1.0*dtp # Total time of simulation - relax = 0.5 - itmax = 5e4 - nout = 1e3 - # Configuration of grid, matrices and numerical parameters - dx, dy = lx/(nx-1), ly/(ny-1) # Grid spacing - xc, yc = -lx/2:dx:lx/2, -ly/2:dy:ly/2 # Coordinate vector - xv, yv = -lx/2-dx/2:dx:lx/2+dx/2, -ly/2-dy/2:dy:ly/2+dy/2 # Horizontal vector for Vx which is one more than basic grid - (Xc2, Yc2) = ([x for x=xc, y=yc], [y for x=xc, y=yc]) - (Xc2vx, Yc2vx) = ([x for x=xv, y=yc], [y for x=xv, y=yc]) - (Xc2vy, Yc2vy) = ([x for x=xc, y=yv], [y for x=xc, y=yv]) - rad_a = rad - rad_b = rad_a*elli_fac - X_rot = Xc2*cosd(α)+Yc2*sind(α) - Y_rot = -Xc2*sind(α)+Yc2*cosd(α) - X_elli = rad_a.*cos.(0:0.01:2*pi).*cosd(α).+rad_b.*sin.(0:0.01:2*pi).*sind(α) - Y_elli = -rad_a.*cos.(0:0.01:2*pi).*sind(α).+rad_b.*sin.(0:0.01:2*pi).*cosd(α) - XY_elli = (-X_elli, Y_elli) - # Initial ambient fluid pressure - Pf = P_ini*ones(nx, ny) - Pf[sqrt.(X_rot.^2.0./rad_a.^2.0 .+ Y_rot.^2.0./rad_b.^2) .< 1.0] .= P_ini - P_pert # Fluid pressure petubation - for smo=1:2 # Smooting of perturbation - Pf[2:end-1,:] .= Pf[2:end-1,:] .+ 0.4.*(Pf[3:end,:].-2.0.*Pf[2:end-1,:].+Pf[1:end-2,:]) - Pf[:,2:end-1] .= Pf[:,2:end-1] .+ 0.4.*(Pf[:,3:end].-2.0.*Pf[:,2:end-1].+Pf[:,1:end-2]) - end - # Analytical fit of look-up table - p_minA, p_maxA = minimum(P_LU), maximum(P_LU) - rho_s_up = 100.0 - SlopeA = (Pf.-p_minA)/p_maxA*rho_s_up - Slope_iniA = (P_ini*ones(nx,ny).-p_minA)/p_maxA*rho_s_up - rho_s_max = Rho_s_LU[1] - rho_s_minA = minimum(Rho_s_LU) - rho_s_difA = rho_s_max-rho_s_minA - p_reactA = 7.85*1e8*Pini_Pappl - rho_f_minA = minimum(Rho_f_LU) - facA = 6e3 - x_max = maximum(X_LU) - x_minA = minimum(X_LU) - x_difA = x_max-x_minA - # Density, compressibility and gamma from concentration and pressure from thermodynamic data base - # itp1 = interpolate( (P_LU[:,1],), Rho_s_LU[:,1], Gridded(Linear())) - # itp2 = interpolate( (P_LU[:,1],), Rho_f_LU[:,1], Gridded(Linear())) - # itp3 = interpolate( (P_LU[:,1],), X_LU[:,1], Gridded(Linear())) - # Rho_s = Data.Array( itp1.(Pf)./ρ_0 ) - # Rho_f = Data.Array( itp2.(Pf)./ρ_0 ) - # X_s = Data.Array( itp3.(Pf) ) - # Rho_s_ini = Data.Array( itp1.(P_ini*ones(nx, ny))./ρ_0 ) - # X_s_ini = Data.Array( itp3.(P_ini*ones(nx, ny)) ) - # Pf_tmp = zeros(nx, ny) - Rho_s = Data.Array( (-tanh.( 5e2*(Pf.-p_reactA) )*rho_s_difA/2.0 .+ rho_s_difA/2.0 .+ rho_s_minA .+ SlopeA)/ρ_0 ) - Rho_f = Data.Array( (rho_f_minA-facA*p_minA^(1/20) .+ facA*Pf.^(1/20))/ρ_0 ) - X_s = Data.Array( -tanh.( 5e2*(Pf.-p_reactA) )*x_difA/2.0 .+ x_difA/2.0 .+ x_minA ) - Rho_s_ini = Data.Array( (-tanh.( 5e2*(P_ini*ones(nx,ny).-p_reactA) )*rho_s_difA/2.0 .+ rho_s_difA/2.0 .+ rho_s_minA .+ Slope_iniA)/ρ_0 ) - X_s_ini = Data.Array( -tanh.( 5e2*(P_ini*ones(nx,ny).-p_reactA) )*x_difA/2.0 .+ x_difA/2.0 .+ x_minA ) - SlopeA = Data.Array( SlopeA ) - # Initialize ALL arrays in Julia - Ptot = @zeros(nx , ny ) # Initial ambient fluid pressure - ∇V = @zeros(nx , ny ) - ∇V_ρ_x = @zeros(nx , ny ) - ∇V_ρ_t = @zeros(nx , ny ) - τ_xx = @zeros(nx , ny ) # Deviatoric stress - τ_yy = @zeros(nx , ny ) # Deviatoric stress - τ_xy = @zeros(nx-1, ny-1) # Deviatoric stress - τ_xyn = @zeros(nx , ny ) - Res_Vx = @zeros(nx-1, ny-2) - Res_Vy = @zeros(nx-2, ny-1) - Rho_s_old = @zeros(nx , ny ) - Rho_f_old = @zeros(nx , ny ) - X_s_old = @zeros(nx , ny ) - Rho_X_old = @zeros(nx , ny ) - Phi_old = @zeros(nx , ny ) - Ptot_old = @zeros(nx , ny ) - Rho_X_ini = @zeros(nx , ny ) - Rho_t_old = @zeros(nx , ny ) - Rho_t = @zeros(nx , ny ) - para_cx = @zeros(nx-1, ny ) - para_cy = @zeros(nx , ny-1) - q_f_X = @zeros(nx-1, ny ) - q_f_Y = @zeros(nx , ny-1) - q_f_X_Ptot = @zeros(nx-1, ny ) - q_f_Y_Ptot = @zeros(nx , ny-1) - ∇q_f = @zeros(nx-2, ny-2) - Res_Pf = @zeros(nx-2, ny-2) - Rho_X_ϕ = @zeros(nx , ny ) - Res_Phi = @zeros(nx , ny ) - ε_xx = @zeros(nx , ny ) - ε_yy = @zeros(nx , ny ) - ε_xy = @zeros(nx-1, ny-1) - τII = @zeros(nx , ny ) - Eta_iter = @zeros(nx , ny ) - # TMP arrays for swell2 - TmpX = @zeros(nx+1, ny ) - TmpY = @zeros(nx , ny+1) - TmpS1 = @zeros(nx , ny-1) - # arrays for visu - Vx_f = zeros(nx , ny ) - Vy_f = zeros(nx , ny ) - Vx_f_Ptot = zeros(nx , ny ) - VY_f_Ptot = zeros(nx , ny ) - # init - Phi_ini = ϕ_ini*@ones(nx, ny) - Phi = ϕ_ini*@ones(nx, ny) - K_ηf = k_ηf*@ones(nx, ny) - Eta_m = η_m*@ones(nx, ny) - Eta_pl = η_m*@ones(nx, ny) - Eta = η_m*@ones(nx, ny) - Lam = λ*@ones(nx, ny) # Viscosity - # Data.Array for ParallelStencil - Vx = -ε_bg*Data.Array(Xc2vx) # Pure shear, shortening in x - Vy = ε_bg*Data.Array(Yc2vy) # Pure shear, extension in y - Pf = Data.Array(Pf) - Ptot .= Pf # Initial total pressure - # Parameters for time loop and pseudo-transient iterations - max_dxdy2 = max(dx,dy).^2 - max_min_ϕ_2 = (maximum(Phi)+minimum(Phi))/2.0 - timeP = 0.0 # Initial time - it = 0 # Integer count for iteration loop - itp = 0 # Integer count for time loop - save_count = 0 - Time_vec = [] - if do_viz - !ispath(joinpath(@__DIR__,"../output")) && mkdir(joinpath(@__DIR__,"../output")) - dirname = joinpath(@__DIR__, "../output/output_$(runid)_$(nx)x$(ny)"); !ispath(dirname) && mkdir(dirname) - end - # time loop - while timeP < time_tot - err_M=2*tol; itp+=1.0 - timeP=timeP+dtp; push!(Time_vec, timeP) - @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Rho_s, Rho_f, X_s, Phi, Ptot) - if itp==1 @parallel compute_2!(Rho_X_ini, Phi_old, Phi_ini, Phi, Rho_s_ini, X_s_ini, Rho_X_old, ϕ_ini) end - max_min_ϕ_2 = (maximum(Phi)+minimum(Phi))/2.0 - @parallel compute_3!(Eta_m, Lam, Phi, η_m, η_i_fac, λ, λ_i_fac, max_min_ϕ_2) - @parallel compute_4!(Eta_pl, Eta, Rho_t_old, Eta_m, Rho_f_old, Phi_old, Rho_s_old) - # PT loop - it_tstep=0; err_evo1=[]; err_evo2=[] - dt_Stokes, dt_Pf = cfl*max_dxdy2, cfl*max_dxdy2 - while err_M>tol && it_tstep1 @parallel compute_12!(Eta_iter, Eta_pl, Eta, Eta_m, τII, σ_ref, n_exp, relax) end - @parallel compute_13!(Vx, Vy, Res_Vx, Res_Vy, dt_Stokes) - if it_tstep % nout == 0 && it_tstep>250 - err_Mx = dt_Stokes*maximum(abs.(Res_Vx)/maximum(abs.(Vx))) # Error horizontal velocitiy - err_My = dt_Stokes*maximum(abs.(Res_Vy)/maximum(abs.(Vy))) # Error vertical velocity - err_Pf = dt_Pf*maximum(abs.(Res_Pf)/maximum(abs.(Pf))) # Error fluid pressure - err_Phi = dtp*maximum(abs.(Res_Phi)) # Error porosity - err_M = maximum([err_Pf, err_Mx, err_My, err_Phi]) # Error total - err_evo1 = push!(err_evo1, it_tstep); err_evo2 = push!(err_evo2, err_M) - # plot evol - # p1 = plot(err_evo1, err_evo2, legend=false, xlabel="# iterations", ylabel="log10(error)", linewidth=2, markershape=:circle, markersize=3, labels="max(error)", yaxis=:log10) - # display(p1) - @printf("iter = %d, error = %1.3e \n", it_tstep, err_M) - end - end # end PT loop - end - # Visu - if do_viz - println("iter tot = $it") - swell2s!(Vx_f, Array(q_f_X)./(Array(Rho_f[1:end-1,:])./Array(Phi[1:end-1,:]).+Array(Rho_f[2:end,:])./Array(Phi[2:end,:])).*2.0, 1) - swell2s!(Vy_f, Array(q_f_Y)./(Array(Rho_f[:,1:end-1])./Array(Phi[:,1:end-1]).+Array(Rho_f[:,2:end])./Array(Phi[:,2:end])).*2.0, 2) - swell2s!(Vx_f_Ptot, Array(q_f_X_Ptot)./(Array(Rho_f[1:end-1,:])./Array(Phi[1:end-1,:]).+Array(Rho_f[2:end,:])./Array(Phi[2:end,:])).*2.0, 1) - swell2s!(VY_f_Ptot, Array(q_f_Y_Ptot)./(Array(Rho_f[:,1:end-1])./Array(Phi[:,1:end-1]).+Array(Rho_f[:,2:end])./Array(Phi[:,2:end])).*2.0, 2) - Length_model_m = rad - Time_model_sec = rad^2/(k_ηf/β_eff) - Length_phys_m = 0.01 - Time_phys_sec = 0.01^2/(1e-19/1e-3/(1e-2/8.5e8)) - Vel_phys_m_s = (Length_phys_m/Length_model_m) / (Time_phys_sec/Time_model_sec) - lw = 1.2; TFS = 10 - p2 = heatmap(xc, yc, Array(Pf)'./Pini_Pappl./1e8, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="A) p_f [kbar]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p3 = heatmap(xc, yc, Array(Ptot)'./Pini_Pappl./1e8, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="B) p [kbar]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p4 = heatmap(xc, yc, Array(∇V)'.*Time_model_sec./Time_phys_sec, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="C) ∇(v_s) [1/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p5 = heatmap(xc, yc, sqrt.(Vx_f.^2 .+ Vy_f.^2)'*Vel_phys_m_s, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="D) ||v_f|| [m/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p6 = heatmap(xc, yc, sqrt.(av_xa(Array(Vx)).^2 .+ av_ya(Array(Vy)).^2)'*Vel_phys_m_s, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="E) ||v_s|| [m/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p7 = heatmap(xc, yc, sqrt.(Vx_f_Ptot.^2 .+ VY_f_Ptot.^2)'*Vel_phys_m_s, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="F) ||v_f||p [m/s]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p8 = heatmap(xv[2:end-1], yv[2:end-1], Array(τ_xy)'/Pini_Pappl/1e6, aspect_ratio=1, xlims=(xv[2], xv[end-1]), ylims=(yv[2], yv[end-1]), c=:viridis, title="G) τxy [MPa]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p9 = heatmap(xc, yc, Array(τII)'/Pini_Pappl/1e6, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="H) τII [MPa]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p10 = heatmap(xc, yc, Array(Eta)'*1e20, aspect_ratio=1, xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c=:viridis, title="I) ηs [Pas]", titlefontsize=TFS) - plot!(XY_elli[1], XY_elli[2], linewidth=lw, linecolor="white", legend=false, framestyle=:box) - display(plot(p2, p3, p4, p5, p6, p7, p8, p9, p10, background_color=:transparent, foreground_color=:gray, dpi=150)) - savefig(joinpath(@__DIR__, dirname, "fig_pt_hmc_bru.png")) - end - return xc, yc, Pf, Phi -end - -if run_test - xc, yc, Pf, Phi = PT_HMC_(); -else - PT_HMC = begin PT_HMC_(); return; end -end - diff --git a/scripts_2022/PT_HMC_atg.jl b/scripts_2022/PT_HMC_atg.jl deleted file mode 100644 index b7e2168..0000000 --- a/scripts_2022/PT_HMC_atg.jl +++ /dev/null @@ -1,589 +0,0 @@ -const run_test = haskey(ENV, "RUN_TEST") ? parse(Bool, ENV["RUN_TEST"]) : false -const USE_GPU = haskey(ENV, "USE_GPU" ) ? parse(Bool, ENV["USE_GPU"] ) : true -const GPU_ID = haskey(ENV, "GPU_ID" ) ? parse(Int, ENV["GPU_ID"] ) : 0 -const do_viz = haskey(ENV, "DO_VIZ" ) ? parse(Bool, ENV["DO_VIZ"] ) : true -const do_save = haskey(ENV, "DO_SAVE" ) ? parse(Bool, ENV["DO_SAVE"] ) : false -const nx = haskey(ENV, "NX" ) ? parse(Int , ENV["NX"] ) : 383 -const ny = haskey(ENV, "NY" ) ? parse(Int , ENV["NY"] ) : 383 -### -using ParallelStencil -using ParallelStencil.FiniteDifferences2D -@static if USE_GPU - @init_parallel_stencil(CUDA, Float64, 2) - CUDA.device!(GPU_ID) # select GPU -else - @init_parallel_stencil(Threads, Float64, 2) -end -using Plots, Printf, Statistics, LinearAlgebra, MAT - -import ParallelStencil: INDICES -ix,iy = INDICES[1], INDICES[2] -ixi,iyi = :($ix+1), :($iy+1) - -"Average in x and y dimension" -@views av(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) -"Average in x dimension" -@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) -"Average in y dimension" -@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) - -@views function swell2h!(B, A, ndim) - B .= B.*0.0 - if ndim==1 - B[2:end-1,:] .= (A[2:end,:] .+ A[1:end-1,:])./2.0 - B[1 ,:] .= 1.5*A[1 ,:] .- 0.5*A[2 ,:] - B[end ,:] .= 1.5*A[end,:] .- 0.5*A[end-1,:] - elseif ndim==2 - B[:,2:end-1] .= (A[:,2:end] .+ A[:,1:end-1])./2.0 - B[:,1 ] .= 1.5*A[:,1 ] .- 0.5*A[:,2 ] - B[:,end ] .= 1.5*A[:,end] .- 0.5*A[:,end-1] - end - return B -end - -@parallel_indices (ix,iy) function swell2_x!(B::Data.Array, A::Data.Array) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if (2<=ix<=size(B,1)-1 && iy<=size(B,2)) B[ix,iy] = 0.5*(A[ix ,iy] + A[ix-1,iy]) end - if ( ix==1 && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix ,iy] - 0.5*A[ix+1,iy] end - if ( ix==size(B,1) && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix-1,iy] - 0.5*A[ix-2,iy] end - return -end - -@parallel_indices (ix,iy) function swell2_y!(B::Data.Array, A::Data.Array) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if (ix<=size(B,1) && 2<=iy<=size(B,2)-1) B[ix,iy] = 0.5*(A[ix,iy ] + A[ix,iy-1]) end - if (ix<=size(B,1) && iy==1 ) B[ix,iy] = 1.5*A[ix,iy ] - 0.5*A[ix,iy+1] end - if (ix<=size(B,1) && iy==size(B,2) ) B[ix,iy] = 1.5*A[ix,iy-1] - 0.5*A[ix,iy-2] end - return -end - -@parallel function cum_mult2!(A1::Data.Array, A2::Data.Array, B1::Data.Array, B2::Data.Array) - @all(A1) = @all(A1)*@all(B1) - @all(A2) = @all(A2)*@all(B2) - return -end - -@parallel function laplace!(A::Data.Array, TmpX::Data.Array, TmpY::Data.Array, dx::Data.Number, dy::Data.Number) - @all(A) = @d_xa(TmpX)/dx + @d_ya(TmpY)/dy - return -end - -@parallel_indices (iy) function bc_x!(A::Data.Array) - A[1 , iy] = A[2 , iy] - A[end, iy] = A[end-1, iy] - return -end - -@parallel_indices (ix) function bc_y!(A::Data.Array) - A[ix, 1 ] = A[ix, 2 ] - A[ix, end] = A[ix, end-1] - return -end - -@parallel function compute_1!(Rho_s_old::Data.Array, Rho_f_old::Data.Array, X_s_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Ptot_old::Data.Array, Pf_old::Data.Array, Rho_t_old::Data.Array, Eta::Data.Array, Lam::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Ptot::Data.Array, Pf::Data.Array, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number) - @all(Rho_s_old) = @all(Rho_s) - @all(Rho_f_old) = @all(Rho_f) - @all(X_s_old) = @all(X_s) - @all(Phi_old) = @all(Phi) - @all(Ptot_old) = @all(Ptot) - @all(Pf_old) = @all(Pf) - @all(Rho_X_old) = @all(Rho_s_old)*@all(X_s_old) - @all(Rho_t_old) = @all(Rho_f_old)*@all(Phi_old) + @all(Rho_s_old)*(1.0 - @all(Phi_old)) - @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - @all(Lam) = λ_η*@all(Eta) - return -end - -@parallel_indices (ix,iy) function compute_2!(Rho_t::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Rho_f::Data.Array, Phi::Data.Array, Rho_s::Data.Array, k_ηf::Data.Number) - if (ix<=size(Rho_t,1) && iy<=size(Rho_t,2)) Rho_t[ix,iy] = Rho_f[ix,iy]*Phi[ix,iy] + Rho_s[ix,iy]*(1.0-Phi[ix,iy]) end - if (ix<=size(para_cx,1) && iy<=size(para_cx,2)) para_cx[ix,iy] = 0.5*( Rho_f[ix,iy]*k_ηf*Phi[ix,iy]^3 + Rho_f[ix+1,iy]*k_ηf*Phi[ix+1,iy]^3 ) end - if (ix<=size(para_cy,1) && iy<=size(para_cy,2)) para_cy[ix,iy] = 0.5*( Rho_f[ix,iy]*k_ηf*Phi[ix,iy]^3 + Rho_f[ix,iy+1]*k_ηf*Phi[ix,iy+1]^3 ) end - return -end - -@parallel function compute_3!(q_f_X::Data.Array, q_f_Y::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Pf::Data.Array, dx::Data.Number, dy::Data.Number) - @all(q_f_X) = -@all(para_cx)*@d_xa(Pf)/dx # Correct Darcy flux with fluid pressure - @all(q_f_Y) = -@all(para_cy)*@d_ya(Pf)/dy # Correct Darcy flux with fluid pressure - return -end - -@parallel function compute_4!(∇q_f::Data.Array, Res_Pf::Data.Array, Rho_f::Data.Array, Rho_s_eq::Data.Array, X_s_eq::Data.Array, q_f_X::Data.Array, q_f_Y::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, ∇V_ρ_t::Data.Array, Pf::Data.Array, SlopeA::Data.Array, - rho_f_maxA::Data.Number, ρ_0::Data.Number, p_reactA::Data.Number, rho_s_difA::Data.Number, rho_s_up::Data.Number, rho_s_minA::Data.Number, x_difA::Data.Number, x_minA::Data.Number, dtp::Data.Number, dx::Data.Number, dy::Data.Number) - @all(∇q_f) = @d_xi(q_f_X)/dx + @d_yi(q_f_Y)/dy - @all(Res_Pf) = -@all(∇q_f) - (@inn(Rho_t) - @inn(Rho_t_old))/dtp - @inn(∇V_ρ_t) # CONSERVATION OF TOTAL MASS EQUATION - @all(Rho_f) = (rho_f_maxA * log(@all(Pf) + 1.0)^(1.0/3.5))/ρ_0 - @all(Rho_s_eq) = (-tanh( 6e2*(@all(Pf)-p_reactA) )*(rho_s_difA/2.0 + rho_s_up/3.0) + (rho_s_difA/2.0 - rho_s_up/3.0) + rho_s_minA + @all(SlopeA))/ρ_0 - @all(X_s_eq) = -tanh( 6e2*(@all(Pf)-p_reactA) )*x_difA/2.0 + x_difA/2.0 + x_minA - return -end - -@parallel function compute_5!(X_s::Data.Array, Rho_s::Data.Array, X_s_old::Data.Array, X_s_eq::Data.Array, Rho_s_old::Data.Array, Rho_s_eq::Data.Array, dtp::Data.Number, kin_time::Data.Number) - @all(X_s) = @all(X_s_old) + dtp*(@all(X_s_eq) - @all(X_s) )/kin_time - @all(Rho_s) = @all(Rho_s_old) + dtp*(@all(Rho_s_eq) - @all(Rho_s))/kin_time - return -end - -@parallel function compute_6!(dPfdτ::Data.Array, Pf::Data.Array, Rho_X_ϕ::Data.Array, Res_Phi::Data.Array, Phi::Data.Array, Res_Pf::Data.Array, Rho_s::Data.Array, X_s::Data.Array, Phi_old::Data.Array, Rho_X_old::Data.Array, ∇V_ρ_X::Data.Array, dampPf::Data.Number, dt_Pf::Data.Number, dtp::Data.Number) - @all(dPfdτ) = dampPf*@all(dPfdτ) + @all(Res_Pf) - @inn(Pf) = @inn(Pf) + dt_Pf*@all(dPfdτ) - @all(Rho_X_ϕ) = (1.0-@all(Phi))*@all(Rho_s)*@all(X_s) - @all(Res_Phi) = ( @all(Rho_X_ϕ) - (1.0-@all(Phi_old))*@all(Rho_X_old) )/dtp + @all(∇V_ρ_X) # CONSERVATION OF MASS OF MgO EQUATION - @all(Phi) = @all(Phi) + dtp*@all(Res_Phi) - return -end - -macro limit_min(A,min_val) esc(:( max($A[$ix,$iy],$min_val) )) end -@parallel function compute_7!(Eta::Data.Array, Lam::Data.Array, ∇V::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array, Ptot::Data.Array, Vx::Data.Array, Vy::Data.Array, Phi::Data.Array, Ptot_old::Data.Array, Pf::Data.Array, Pf_old::Data.Array, - dtPt::Data.Number, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number, dtp::Data.Number, K_d::Data.Number, η_min::Data.Number, α::Data.Number, dx::Data.Number, dy::Data.Number) - @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - @all(Eta) = @limit_min(Eta,η_min) - @all(Lam) = λ_η*@all(Eta) - @all(∇V) = @d_xa(Vx)/dx + @d_ya(Vy)/dy - @all(ε_xx) = @d_xa(Vx)/dx - 1.0/3.0*@all(∇V) - @all(ε_yy) = @d_ya(Vy)/dy - 1.0/3.0*@all(∇V) - @all(ε_xy) = 0.5*(@d_yi(Vx)/dy + @d_xi(Vy)/dx) - @all(Ptot) = @all(Ptot) - dtPt*( @all(Ptot) - (@all(Ptot_old)-dtp*( K_d*@all(∇V) - α*( (@all(Pf) - @all(Pf_old))/dtp ) - K_d*@all(Pf) / ((1.0-@all(Phi))*@all(Lam)) )) / ( 1.0 + dtp*K_d/((1.0-@all(Phi))*@all(Lam)) ) ) - return -end - -@parallel function compute_8!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, Eta::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array) - @all(τ_xx) = 2.0*@all(Eta) * @all(ε_xx) - @all(τ_yy) = 2.0*@all(Eta) * @all(ε_yy) - @all(τ_xy) = 2.0*@av(Eta) * @all(ε_xy) - return -end - -@parallel function compute_plast_1!(τII::Data.Array, LamP::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, σ_y::Data.Number) - @all(τII) = sqrt( 0.5*(@all(τ_xx)*@all(τ_xx) + @all(τ_yy)*@all(τ_yy)) + @all(τ_xyn)*@all(τ_xyn) ) - @all(LamP) = max(0.0, (1.0 - σ_y/@all(τII))) - return -end - -@parallel function compute_plast_2!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, LamP::Data.Array) - @all(τ_xx) = (1.0-@all(LamP))*@all(τ_xx) - @all(τ_yy) = (1.0-@all(LamP))*@all(τ_yy) - @all(τ_xy) = (1.0- @av(LamP))*@all(τ_xy) - return -end - -@parallel function compute_plast_3!(τII::Data.Array, LamP2::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, LamP::Data.Array) - @all(τII) = sqrt( 0.5*(@all(τ_xx)*@all(τ_xx) + @all(τ_yy)*@all(τ_yy)) + @all(τ_xyn)*@all(τ_xyn) ) - @all(LamP2) = @all(LamP2) + @all(LamP) - return -end - -@parallel function compute_9!(Res_Vx::Data.Array, Res_Vy::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, Ptot::Data.Array, τ_xy::Data.Array, dx::Data.Number, dy::Data.Number) - @all(Res_Vx) = -@d_xi(Ptot)/dx + @d_xi(τ_xx)/dx + @d_ya(τ_xy)/dy # HORIZONTAL FORCE BALANCE - @all(Res_Vy) = -@d_yi(Ptot)/dy + @d_yi(τ_yy)/dy + @d_xa(τ_xy)/dx # VERTICAL FORCE BALANCE - return -end - -@parallel function compute_10!(dVxdτ::Data.Array, dVydτ::Data.Array, Vx::Data.Array, Vy::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, dampV::Data.Number, dt_Stokes::Data.Number) - @all(dVxdτ) = @all(dVxdτ)*dampV + @all(Res_Vx) # dVxdτ .= dVxdτ.*(1-Vdmp/nx) .+ Rx - @all(dVydτ) = @all(dVydτ)*dampV + @all(Res_Vy) - @inn(Vx) = @inn(Vx) + dt_Stokes*@all(dVxdτ) # Pseudo-transient form of horizontal force balance - @inn(Vy) = @inn(Vy) + dt_Stokes*@all(dVydτ) # Pseudo-transient form of vertical force balance - return -end - -@parallel function postprocess!(dRhoT_dt::Data.Array, dRhosPhi_dt::Data.Array, dRhofPhi_dt::Data.Array, dRhoXPhi_dt::Data.Array, dPf_dt::Data.Array, dPt_dt::Data.Array, dPhi_dt::Data.Array, dRhos_dt::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Rho_s_old::Data.Array, Rho_f_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, Pf::Data.Array, Pf_old::Data.Array, Ptot::Data.Array, Ptot_old::Data.Array, dtp::Data.Number) - @all(dRhoT_dt) = (@all(Rho_t) - @all(Rho_t_old)) /dtp - @all(dRhosPhi_dt) = (@all(Rho_s)*(1.0-@all(Phi)) - @all(Rho_s_old)*(1.0-@all(Phi_old))) /dtp - @all(dRhofPhi_dt) = (@all(Rho_f)*@all(Phi) - @all(Rho_f_old)*@all(Phi_old)) /dtp - @all(dRhoXPhi_dt) = (@all(Rho_s)*@all(X_s)*(1-@all(Phi)) - @all(Rho_X_old)*(1-@all(Phi_old))) /dtp - @all(dPf_dt) = (@all(Pf) - @all(Pf_old)) /dtp - @all(dPt_dt) = (@all(Ptot) - @all(Ptot_old)) /dtp - @all(dPhi_dt) = (@all(Phi) - @all(Phi_old)) /dtp - @all(dRhos_dt) = (@all(Rho_s) - @all(Rho_s_old)) /dtp - return -end -################################################## -@views function PT_HMC_() - runid = "plast1" - nsave = 25 - nviz = 20 - do_restart = false - irestart = 1750 # Step to restart from if do_reatart - # read in mat file - vars = matread( string(@__DIR__, "/LOOK_UP_atg.mat") ) - Rho_s_LU = get(vars, "Rho_s" ,1) - Rho_f_LU = get(vars, "Rho_f" ,1) - X_LU = get(vars, "X_s_vec",1) - P_LU = get(vars, "P_vec" ,1)*1e8 - # Independent parameters - rad = 1.0 # Radius of initial P-perturbation [m] - η_m = 1.0 # Viscosity scale [Pa s] - P_ini = 1.0 # Initial ambient pressure [Pa] - ρ_0 = 3000.0 # Density scale [kg/m^3] - # Nondimensional parameters - elli_fac = 2.0 # Use 1 for circle - α = 0.0 # Counterclockwise angle of long axis with respect to vertical direction - ϕ_ini = 2e-2 # Initial porosity - ϕ_exp = 30.0 # Parameter controlling viscosity-porosity relation - lx_rad = 40.0 # LAMBDA_1 in equation (15) in the manuscript; Model height divided by inclusion radius; - lc_rad2 = 1e1 # LAMBDA_2 in equation (15) in the manuscript; Lc_rad2 = k_etaf*eta_mat/radius^2; []; Ratio of hydraulic fluid extraction to compaction extraction - λ_η = 2.0 # LAMBDA_3 in equation (15) in the manuscript; lam_eta = lambda / eta_mat; []; Ratio of bulk to shear viscosity - ly_lx = 1.0 # Model height divided by model width - Pini_Pappl = P_ini/12.75e8 # Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table - σ_y = 150.0*Pini_Pappl*1e6 # yield stress - # Dependant parameters - K_s = 1e11*Pini_Pappl # Solid elastic bulk modulus - k_ηf = lc_rad2*rad^2/η_m # Permeability divided by fluid viscosity; [m^2/(Pa s)] - lx = lx_rad*rad # Model width [m] - ly = ly_lx*lx # Model height [m] - P_LU = P_LU*Pini_Pappl # Transform look-up table stress to PT stress scale - K_d = K_s/2.0 # Elastic bulk modulus, drained - α = 1.0 - K_d/K_s # Biot-Willis coefficient - # Characteristic time scales - τ_f_dif = rad^2 / (k_ηf *K_s) - τ_f_dif_ϕ = rad^2 / (k_ηf*ϕ_ini^3*K_s) - τ_relax = η_m / K_s - τ_kinetic = 1.0/5.0/3.0/3.0/3.0 * 1/3*τ_f_dif_ϕ - τ_deform = 0.5/7.0 * 1.0*τ_f_dif_ϕ - ε_bg = 1.0 / τ_deform - Da = ε_bg/(P_ini/η_m) # Re-scaling of Da (LAMBDA_4) - # Numerics - nt = 1e4 - tol = 1e-8 # Tolerance for pseudo-transient iterations - cfl = 1.0/16.1 # CFL parameter for PT-Stokes solution - damping = 1 - Re_Pf = 60π - Re_V = 60π - r = 1.5 - dt_fact = 1.0 - dtp = τ_f_dif / 2.0 / dt_fact # Time step physical - time_tot = dt_fact * 2*5e3*dtp # Total time of simulation - itmax = 5e6 - nout = 1e3 - nsm = 5 # number of porosity smoothing steps - explicit diffusion - η_min = 1e-6 - kin_time = 1e1*τ_f_dif_ϕ - kin_time_final = τ_kinetic - Kin_time_vec = [1e25*τ_f_dif_ϕ; range(kin_time, stop=kin_time_final, length=20); kin_time_final*ones(Int(round(time_tot/dtp)))] - # Configuration of grid, matrices and numerical parameters - dx, dy = lx/(nx-1), ly/(ny-1) # Grid spacing - xc, yc = -lx/2:dx:lx/2, -ly/2:dy:ly/2 # Coordinate vector - xv, yv = -lx/2-dx/2:dx:lx/2+dx/2, -ly/2-dy/2:dy:ly/2+dy/2 # Horizontal vector for Vx which is one more than basic grid - (Xc2, Yc2) = ([x for x=xc, y=yc], [y for x=xc, y=yc]) - (Xc2vx, Yc2vx) = ([x for x=xv, y=yc], [y for x=xv, y=yc]) - (Xc2vy, Yc2vy) = ([x for x=xc, y=yv], [y for x=xc, y=yv]) - rad_a = rad - rad_b = rad_a*elli_fac - X_rot = Xc2*cosd(α)+Yc2*sind(α) - Y_rot = -Xc2*sind(α)+Yc2*cosd(α) - X_elli = rad_a.*cos.(0:0.01:2*pi).*cosd(α).+rad_b.*sin.(0:0.01:2*pi).*sind(α) - Y_elli = -rad_a.*cos.(0:0.01:2*pi).*sind(α).+rad_b.*sin.(0:0.01:2*pi).*cosd(α) - XY_elli = (-X_elli, Y_elli) - # Analytical fit of look-up table - p_minA, p_maxA = minimum(P_LU), maximum(P_LU) - rho_s_up = 50.0 - Pf = P_ini*ones(nx, ny) - SlopeA = (Pf.-p_minA)/p_maxA*rho_s_up - rho_s_max = Rho_s_LU[1] - rho_s_minA = minimum(Rho_s_LU) - rho_s_difA = rho_s_max-rho_s_minA - p_reactA = 12.65*1e8*Pini_Pappl - rho_f_maxA = maximum(Rho_f_LU) # Parameters for fluid density - x_max = maximum(X_LU) # Parameters for mass fraction - x_minA = minimum(X_LU) - x_difA = x_max-x_minA - # Density, compressibility and gamma from concentration and pressure from thermodynamic data base - Rho_s = Data.Array( (-tanh.( 6e2*(Pf.-p_reactA) )*(rho_s_difA/2.0 .+ rho_s_up/3.0) .+ (rho_s_difA/2.0 .- rho_s_up/3.0) .+ rho_s_minA .+ SlopeA)/ρ_0 ) - Rho_f = Data.Array( (rho_f_maxA .* log.(Pf .+ 1.0).^(1.0/3.5))/ρ_0 ) - X_s = Data.Array( -tanh.( 6e2*(Pf.-p_reactA) )*x_difA/2.0 .+ x_difA/2.0 .+ x_minA ) - SlopeA = Data.Array( SlopeA ) - # Initialize ALL arrays in Julia - Ptot = @zeros(nx , ny ) # Initial ambient fluid pressure - ∇V = @zeros(nx , ny ) - ∇V_ρ_X = @zeros(nx , ny ) - ∇V_ρ_t = @zeros(nx , ny ) - τ_xx = @zeros(nx , ny ) # Deviatoric stress - τ_yy = @zeros(nx , ny ) # Deviatoric stress - τ_xy = @zeros(nx-1, ny-1) # Deviatoric stress - τ_xyn = @zeros(nx , ny ) - Res_Vx = @zeros(nx-1, ny-2) - Res_Vy = @zeros(nx-2, ny-1) - dVxdτ = @zeros(nx-1, ny-2) # damping - dVydτ = @zeros(nx-2, ny-1) # damping - Rho_s_eq = @zeros(nx , ny ) - X_s_eq = @zeros(nx , ny ) - Rho_s_old = @zeros(nx , ny ) - Rho_f_old = @zeros(nx , ny ) - X_s_old = @zeros(nx , ny ) - Rho_X_old = @zeros(nx , ny ) - Phi_old = @zeros(nx , ny ) - Ptot_old = @zeros(nx , ny ) - Pf_old = @zeros(nx , ny ) - Rho_t_old = @zeros(nx , ny ) - Rho_t = @zeros(nx , ny ) - para_cx = @zeros(nx-1, ny ) - para_cy = @zeros(nx , ny-1) - q_f_X = @zeros(nx-1, ny ) - q_f_Y = @zeros(nx , ny-1) - ∇q_f = @zeros(nx-2, ny-2) - Res_Pf = @zeros(nx-2, ny-2) - dPfdτ = @zeros(nx-2, ny-2) # damping - Rho_X_ϕ = @zeros(nx , ny ) - Res_Phi = @zeros(nx , ny ) - ε_xx = @zeros(nx , ny ) - ε_yy = @zeros(nx , ny ) - ε_xy = @zeros(nx-1, ny-1) - τII = @zeros(nx , ny ) - LamP = @zeros(nx , ny ) - LamP2 = @zeros(nx , ny ) - # Arrays for post-processing - dRhoT_dt = @zeros(nx , ny ) - dRhosPhi_dt = @zeros(nx , ny ) - dRhofPhi_dt = @zeros(nx , ny ) - dRhoXPhi_dt = @zeros(nx , ny ) - dPf_dt = @zeros(nx , ny ) - dPt_dt = @zeros(nx , ny ) - dPhi_dt = @zeros(nx , ny ) - dRhos_dt = @zeros(nx , ny ) - # TMP arrays for swell2 - TmpX = @zeros(nx+1, ny ) - TmpY = @zeros(nx , ny+1) - TmpS1 = @zeros(nx , ny-1) - # arrays for visu - Vx_f = zeros(nx , ny ) - Vy_f = zeros(nx , ny ) - # init - Phi_ini = ϕ_ini*ones(nx, ny) - # Phi_ini[sqrt.((X_rot .- 2.0).^2 ./ rad_a.^2 .+ (Y_rot .+ 6.0).^2 ./ rad_b.^2) .< 1.0] .= 2.5*ϕ_ini # Porosity petubation - # Phi_ini[sqrt.((X_rot .+ 2.0).^2 ./ rad_a.^2 .+ (Y_rot .- 6.0).^2 ./ rad_b.^2) .< 1.0] .= 2.5*ϕ_ini # Porosity petubation - # for smo=1:nsm # Smooting of perturbation - # Phi_ini[2:end-1,:] .= Phi_ini[2:end-1,:] .+ 0.4.*(Phi_ini[3:end,:].-2.0.*Phi_ini[2:end-1,:].+Phi_ini[1:end-2,:]) - # Phi_ini[:,2:end-1] .= Phi_ini[:,2:end-1] .+ 0.4.*(Phi_ini[:,3:end].-2.0.*Phi_ini[:,2:end-1].+Phi_ini[:,1:end-2]) - # end - Pert = Data.Array((8 .* Phi_ini .- Phi_ini) .* exp.(.-(Xc2./rad_a).^2 .- (Yc2./rad_b).^2)) - Phi_ini = Data.Array(Phi_ini) - Phi = Phi_ini .+ Pert - # Phi = copy(Phi_ini) - Eta = η_m*@ones(nx, ny) # Shear viscosity, alternative init: # @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - Lam = λ_η*@ones(nx, ny) # Bulk viscosity, alternative init: # @all(Lam) = λ_η*@all(Eta) - # Vx_ps = ε_bg*Data.Array(Xc2vx) # Pure shear, shortening in x - # Vy_ps = -ε_bg*Data.Array(Yc2vy) # Pure shear, extension in y - # Vx_ss = ε_bg*Data.Array(Yc2vx) # Simple shear, shearing in x - # Vy_ss = 0.0*Data.Array(Yc2vy) # Simple shear, zero velocity in y - # Vx = 0.5.*(Vx_ps .+ Vx_ss) - # Vy = 0.5.*(Vy_ps .+ Vy_ss) - Vx = ε_bg*Data.Array(Yc2vx) # Simple shear, shearing in x - Vy = 0.0*Data.Array(Yc2vy) # Simple shear, zero velocity in y - Pf = Data.Array(Pf) - Ptot .= Pf # Initial total pressure - # Parameters for time loop and pseudo-transient iterations - min_dxdy2 = min(dx,dy).^2 - timeP = 0.0 # Initial time - it = 0 # Integer count for iteration loop - itp = 0 # Integer count for time loop - save_count = 0 - Time_vec = [] - ρ_i_Pf = cfl*Re_Pf/nx - ρ_i_V = cfl*Re_V /nx - dampPf = damping.*(1.0 .- ρ_i_Pf) - dampV = damping.*(1.0 .- ρ_i_V ) - if do_save || do_viz - !ispath(joinpath(@__DIR__,"../output")) && mkdir(joinpath(@__DIR__,"../output")) - dirname = joinpath(@__DIR__, "../output/output_$(runid)_$(nx)x$(ny)"); !ispath(dirname) && mkdir(dirname) - end - it_viz = 0 - # time loop - while timeP < time_tot && itp < nt - if do_restart - restart_file = joinpath(@__DIR__, dirname, "pt_hmc_Atg_") * @sprintf("%04d", irestart) * ".mat" - vars_restart = matread(restart_file) - Ptot .= Data.Array(get(vars_restart, "Ptot" ,1)) - Pf .= Data.Array(get(vars_restart, "Pf" ,1)) - X_s .= Data.Array(get(vars_restart, "X_s" ,1)) - Phi .= Data.Array(get(vars_restart, "Phi" ,1)) - Rho_s .= Data.Array(get(vars_restart, "Rho_s" ,1)) - Rho_f .= Data.Array(get(vars_restart, "Rho_f" ,1)) - Vx .= Data.Array(get(vars_restart, "Vx" ,1)) - Vy .= Data.Array(get(vars_restart, "Vy" ,1)) - Vx_f .= Data.Array(get(vars_restart, "Vx_f" ,1)) - Vy_f .= Data.Array(get(vars_restart, "Vy_f" ,1)) - LamP2 .= Data.Array(get(vars_restart, "LamP2" ,1)) - Rho_s_old .= Data.Array(get(vars_restart, "Rho_s_old",1)) - Rho_f_old .= Data.Array(get(vars_restart, "Rho_f_old",1)) - X_s_old .= Data.Array(get(vars_restart, "X_s_old" ,1)) - Rho_X_old .= Data.Array(get(vars_restart, "Rho_X_old",1)) - Phi_old .= Data.Array(get(vars_restart, "Phi_old" ,1)) - Ptot_old .= Data.Array(get(vars_restart, "Ptot_old" ,1)) - Pf_old .= Data.Array(get(vars_restart, "Pf_old" ,1)) - Rho_t_old .= Data.Array(get(vars_restart, "Rho_t_old",1)) - Time_vec = get(vars_restart, "Time_vec" ,1) - itp = get(vars_restart, "itp" ,1) - timeP = get(vars_restart, "timeP" ,1) - it = get(vars_restart, "it" ,1) - it_tstep = get(vars_restart, "it_tstep" ,1) - do_restart = false - end - err_M = 2*tol; itp += 1 - timeP = timeP+dtp; push!(Time_vec, timeP) - @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η) - kin_time = Kin_time_vec[itp] - # PT loop - it_tstep=0; err_evo1=[]; err_evo2=[]; err_pl=[] - dt_Stokes, dt_Pf = cfl*min_dxdy2, cfl*min_dxdy2 - dt_Pt = maximum(Eta)/(lx/dx) - while err_M>tol && it_tstep 1) @parallel compute_5!(X_s, Rho_s, X_s_old, X_s_eq, Rho_s_old, Rho_s_eq, dtp, kin_time) end - # Porosity evolution - @parallel compute_6!(dPfdτ, Pf, Rho_X_ϕ, Res_Phi, Phi, Res_Pf, Rho_s, X_s, Phi_old, Rho_X_old, ∇V_ρ_X, dampPf, dt_Pf, dtp) - @parallel (1:size(Pf,1)) bc_y!(Pf) - @parallel (1:size(Pf,2)) bc_x!(Pf) - # Stokes - @parallel swell2_x!(TmpX, Rho_X_ϕ) - @parallel swell2_y!(TmpY, Rho_X_ϕ) - @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) - @parallel laplace!(∇V_ρ_X, TmpX, TmpY, dx, dy) - @parallel swell2_x!(TmpX, Rho_t) - @parallel swell2_y!(TmpY, Rho_t) - @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) - @parallel laplace!(∇V_ρ_t, TmpX, TmpY, dx, dy) - @parallel compute_7!(Eta, Lam, ∇V, ε_xx, ε_yy, ε_xy, Ptot, Vx, Vy, Phi, Ptot_old, Pf, Pf_old, dt_Pt, η_m, ϕ_exp, ϕ_ini, λ_η, dtp, K_d, η_min, α, dx, dy) - @parallel compute_8!(τ_xx, τ_yy, τ_xy, Eta, ε_xx, ε_yy, ε_xy) - @parallel swell2_x!(TmpS1, τ_xy) - @parallel swell2_y!(τ_xyn, TmpS1) - # Plastic starts - @parallel compute_plast_1!(τII, LamP, τ_xx, τ_yy, τ_xyn, σ_y) - @parallel compute_plast_2!(τ_xx, τ_yy, τ_xy, LamP) - @parallel swell2_x!(TmpS1, τ_xy) - @parallel swell2_y!(τ_xyn, TmpS1) - @parallel compute_plast_3!(τII, LamP2, τ_xx, τ_yy, τ_xyn, LamP) - # Plastic ends - @parallel compute_9!(Res_Vx, Res_Vy, τ_xx, τ_yy, τ_xyn, Ptot, τ_xy, dx, dy) - @parallel compute_10!(dVxdτ, dVydτ, Vx, Vy, Res_Vx, Res_Vy, dampV, dt_Stokes) - if it_tstep % nout == 0 && it_tstep > 250 - err_Mx = dt_Stokes*maximum(abs.(Res_Vx)/maximum(abs.(Vx))) # Error horizontal velocitiy - err_R_Mx = maximum(abs.(Res_Vx)) # Error horizontal force balance - err_My = dt_Stokes*maximum(abs.(Res_Vy)/maximum(abs.(Vy))) # Error vertical velocity - err_R_My = maximum(abs.(Res_Vy)) # Error vertical force balance - err_Pf = dt_Pf*maximum(abs.(Res_Pf)/maximum(abs.(Pf))) # Error fluid pressure - err_R_Pf = maximum(abs.(Res_Pf)) # Error total mass conservation - err_Phi = dtp*maximum(abs.(Res_Phi)) # Error porosity - err_R_Phi= maximum(abs.(Res_Phi)) # Error MgO mass conservation - err_M = maximum([err_Pf, err_Mx, err_My, err_Phi, err_R_Pf, err_R_Mx, err_R_My, err_R_Phi]) # Error total - if isnan(err_M) error("NoNs - stopping simulation.") end - err_evo1 = push!(err_evo1, it_tstep); err_evo2 = push!(err_evo2, err_M) - err_pl = push!(err_pl, maximum(τII)/σ_y - 1.0) - # plot evol - # p1 = plot(err_evo1, err_evo2, legend=false, xlabel="# iterations", ylabel="log10(error)", linewidth=2, markershape=:circle, markersize=3, labels="max(error)", yaxis=:log10) - # display(p1) - @printf("iter = %d, error = %1.3e \n", it_tstep, err_M) - end - end # end PT loop - println("it = $(itp), time = $(round(timeP, sigdigits=3)) (time_tot = $(round(time_tot, sigdigits=3)))") - # Visu - if do_viz && (itp % nviz == 0 || itp == 1) - it_viz += 1 - swell2h!(Vx_f, Array(q_f_X)./(Array(Rho_f[1:end-1,:])./Array(Phi[1:end-1,:]).+Array(Rho_f[2:end,:])./Array(Phi[2:end,:])).*2.0, 1) - swell2h!(Vy_f, Array(q_f_Y)./(Array(Rho_f[:,1:end-1])./Array(Phi[:,1:end-1]).+Array(Rho_f[:,2:end])./Array(Phi[:,2:end])).*2.0, 2) - η_char = 1e19 - Length_model_m = rad - Time_model_sec = rad^2/(k_ηf*K_s) - Length_phys_m = 0.01 - Time_phys_sec = 0.01^2 / (1e-19 / 1e-3 / (1e-2/8.5e8)) - Vel_phys_m_s = (Length_phys_m/Length_model_m) / (Time_phys_sec/Time_model_sec) - lw = 1.2; fontsize = 8 - opts1 = (aspect_ratio=1, yaxis=font(fontsize, "Courier"), xaxis=font(fontsize, "Courier"), - ticks=nothing, framestyle=:box, titlefontsize=fontsize, titlefont="Courier", colorbar_title="", - xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c = cgrad(:davos, rev = true) ) - opts2 = (linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p2 = heatmap(xc, yc, Array(Pf)'./Pini_Pappl./1e8; title="A) p_f [kbar]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2... ) - p3 = heatmap(xc, yc, Array(Ptot)'./Pini_Pappl./1e8; title="B) p [kbar]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p4 = heatmap(xc, yc, Array(∇V)'.*Time_model_sec./Time_phys_sec; title="C) ∇(v_s) [1/s]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p5 = heatmap(xc, yc, Array(X_s)'; title="D) X_s", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p6 = heatmap(xc, yc, Array(Rho_s)'.*ρ_0; title="E) ρ_s [kg/m^3]", opts1...) - # p6 = heatmap(xc, yc, sqrt.(av_xa(Array(Vx)).^2 .+ av_ya(Array(Vy)).^2)'*Vel_phys_m_s; title="E) ||v_s|| [m/s]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p7 = heatmap(xc, yc, Array(Phi)'; title="F) ϕ", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p8 = heatmap(xc, yc, Array(Rho_f)'.*ρ_0; title="G) ρ_f [kg/m^3]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p9 = heatmap(xc, yc, Array(τII)'./Pini_Pappl./1e6; title="H) τII [MPa]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - p10 = heatmap(xc, yc, log10.(Array(Eta)'.*η_char); title="I) log10(ηs) [Pas]", opts1...) - plot!(XY_elli[1], XY_elli[2]; opts2...) - display(plot(p2, p3, p4, p5, p6, p7, p8, p9, p10, background_color=:transparent, foreground_color=:gray, dpi=300)) - savefig(joinpath(@__DIR__, dirname, "fig_pt_hmc_Atg_$(it_viz).png")) - end - if do_save && (itp % nsave == 0 || itp==1) - @parallel postprocess!(dRhoT_dt, dRhosPhi_dt, dRhofPhi_dt, dRhoXPhi_dt, dPf_dt, dPt_dt, dPhi_dt, dRhos_dt, Rho_s, Rho_f, X_s, Phi, Rho_s_old, Rho_f_old, Rho_X_old, Phi_old, Rho_t, Rho_t_old, Pf, Pf_old, Ptot, Ptot_old, dtp) - matwrite(joinpath(@__DIR__, dirname, "pt_hmc_Atg_") * @sprintf("%04d", itp) * ".mat", - Dict("Ptot"=> Array(Ptot), - "Pf"=> Array(Pf), - "divV"=> Array(∇V), - "X_s"=> Array(X_s), - "Rho_s"=> Array(Rho_s), - "Phi"=> Array(Phi), - "Rho_f"=> Array(Rho_f), - "TauII"=> Array(τII), - "Eta"=> Array(Eta), - "Tauxx"=> Array(τ_xx), - "Tauyy"=> Array(τ_yy), - "Tauxy"=> Array(τ_xy), - "Vx"=> Array(Vx), - "Vy"=> Array(Vy), - "Vx_f"=> Array(Vx_f), - "Vy_f"=> Array(Vy_f), - "Ellipse_x"=> Array(X_elli), - "Ellipse_y"=> Array(Y_elli), - "Time_vec"=> Array(Time_vec), - "LamP2"=> Array(LamP2), - "Rho_s_old"=> Array(Rho_s_old), - "Rho_f_old"=> Array(Rho_f_old), - "X_s_old"=> Array(X_s_old), - "Rho_X_old"=> Array(Rho_X_old), - "Phi_old"=> Array(Phi_old), - "Ptot_old"=> Array(Ptot_old), - "Pf_old"=> Array(Pf_old), - "Rho_t_old"=> Array(Rho_t_old), - "Lam"=> Array(Lam), - "dRhoT_dt"=> Array(dRhoT_dt), - "dRhosPhi_dt"=> Array(dRhosPhi_dt), - "dRhofPhi_dt"=> Array(dRhofPhi_dt), - "dRhoXPhi_dt"=> Array(dRhoXPhi_dt), - "dPf_dt"=> Array(dPf_dt), - "dPt_dt"=> Array(dPt_dt), - "dPhi_dt"=> Array(dPhi_dt), - "dRhos_dt"=> Array(dRhos_dt), - "Res_pf"=> Array(Res_Pf), - "div_qf"=> Array(∇q_f), - "div_rhoTvs"=> Array(∇V_ρ_t), - "div_rhoXvs"=> Array(∇V_ρ_X), - "Ch_ti_fluid_dif_phi"=> τ_f_dif_ϕ, - "Ch_ti_deformation"=> τ_deform, - "Ch_ti_kinetic"=> τ_kinetic, - "Ch_ti_relaxation"=> τ_relax, - "itp"=> itp, - "timeP"=> timeP, - "it"=> it, - "it_tstep"=> it_tstep, - "xc"=> Array(xc), "yc"=> Array(yc)); compress = true) - end - if (run_test && itp==1) break; end - end - return xc, yc, Pf, Phi -end - -if run_test - xc, yc, Pf, Phi = PT_HMC_(); -else - PT_HMC = begin PT_HMC_(); return; end -end diff --git a/scripts_2022/PT_HMC_atg_rand.jl b/scripts_2022/PT_HMC_atg_rand.jl deleted file mode 100644 index 7c9957c..0000000 --- a/scripts_2022/PT_HMC_atg_rand.jl +++ /dev/null @@ -1,626 +0,0 @@ -const USE_GPU = haskey(ENV, "USE_GPU") ? parse(Bool, ENV["USE_GPU"]) : true -const GPU_ID = haskey(ENV, "GPU_ID" ) ? parse(Int, ENV["GPU_ID"] ) : 0 -const do_viz = haskey(ENV, "DO_VIZ" ) ? parse(Bool, ENV["DO_VIZ"] ) : true -const do_save = haskey(ENV, "DO_SAVE") ? parse(Bool, ENV["DO_SAVE"]) : false -const nx = haskey(ENV, "NX" ) ? parse(Int , ENV["NX"] ) : 383 -const ny = haskey(ENV, "NY" ) ? parse(Int , ENV["NY"] ) : 383 -### -using ParallelStencil -using ParallelStencil.FiniteDifferences2D -@static if USE_GPU - @init_parallel_stencil(CUDA, Float64, 2) - CUDA.device!(GPU_ID) # select GPU - using ParallelRandomFields.grf2D_CUDA -else - @init_parallel_stencil(Threads, Float64, 2) - using ParallelRandomFields.grf2D_Threads -end -using Plots, Printf, Statistics, LinearAlgebra, MAT - -import ParallelStencil: INDICES -ix,iy = INDICES[1], INDICES[2] -ixi,iyi = :($ix+1), :($iy+1) - -"Average in x and y dimension" -@views av(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) -"Average in x dimension" -@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) -"Average in y dimension" -@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) - -@views function swell2h!(B, A, ndim) - B .= B.*0.0 - if ndim==1 - B[2:end-1,:] .= (A[2:end,:] .+ A[1:end-1,:])./2.0 - B[1 ,:] .= 1.5*A[1 ,:] .- 0.5*A[2 ,:] - B[end ,:] .= 1.5*A[end,:] .- 0.5*A[end-1,:] - elseif ndim==2 - B[:,2:end-1] .= (A[:,2:end] .+ A[:,1:end-1])./2.0 - B[:,1 ] .= 1.5*A[:,1 ] .- 0.5*A[:,2 ] - B[:,end ] .= 1.5*A[:,end] .- 0.5*A[:,end-1] - end - return B -end - -@parallel_indices (ix,iy) function swell2_x!(B::Data.Array, A::Data.Array) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if (2<=ix<=size(B,1)-1 && iy<=size(B,2)) B[ix,iy] = 0.5*(A[ix ,iy] + A[ix-1,iy]) end - if ( ix==1 && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix ,iy] - 0.5*A[ix+1,iy] end - if ( ix==size(B,1) && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix-1,iy] - 0.5*A[ix-2,iy] end - return -end - -@parallel_indices (ix,iy) function swell2_y!(B::Data.Array, A::Data.Array) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if (ix<=size(B,1) && 2<=iy<=size(B,2)-1) B[ix,iy] = 0.5*(A[ix,iy ] + A[ix,iy-1]) end - if (ix<=size(B,1) && iy==1 ) B[ix,iy] = 1.5*A[ix,iy ] - 0.5*A[ix,iy+1] end - if (ix<=size(B,1) && iy==size(B,2) ) B[ix,iy] = 1.5*A[ix,iy-1] - 0.5*A[ix,iy-2] end - return -end - -@parallel function cum_mult2!(A1::Data.Array, A2::Data.Array, B1::Data.Array, B2::Data.Array) - @all(A1) = @all(A1)*@all(B1) - @all(A2) = @all(A2)*@all(B2) - return -end - -@parallel function laplace!(A::Data.Array, TmpX::Data.Array, TmpY::Data.Array, dx::Data.Number, dy::Data.Number) - @all(A) = @d_xa(TmpX)/dx + @d_ya(TmpY)/dy - return -end - -@parallel_indices (iy) function bc_x!(A::Data.Array) - A[1 , iy] = A[2 , iy] - A[end, iy] = A[end-1, iy] - return -end - -@parallel_indices (ix) function bc_y!(A::Data.Array) - A[ix, 1 ] = A[ix, 2 ] - A[ix, end] = A[ix, end-1] - return -end - -@parallel_indices (ix,iy) function smooth_border_x!(Phi::Data.Array, xind) - if (ix<=xind && iy<=size(Phi,2)) Phi[ix,iy] = Phi[ix,iy] * ((ix - 1)/xind) end - if (ix>=(size(Phi,1)-xind+1) && iy<=size(Phi,2)) Phi[ix,iy] = Phi[ix,iy] * ((size(Phi,1) - ix)/xind) end - return -end - -@parallel_indices (ix,iy) function smooth_border_y!(Phi::Data.Array, yind) - if (ix<=size(Phi,1) && iy<=yind ) Phi[ix,iy] = Phi[ix,iy] * ((iy - 1)/yind) end - if (ix<=size(Phi,1) && iy>=(size(Phi,2)-yind+1)) Phi[ix,iy] = Phi[ix,iy] * ((size(Phi,2) - iy)/yind) end - return -end - -@parallel function compute_1!(Rho_s_old::Data.Array, Rho_f_old::Data.Array, X_s_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Ptot_old::Data.Array, Pf_old::Data.Array, Rho_t_old::Data.Array, Eta::Data.Array, Lam::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Ptot::Data.Array, Pf::Data.Array, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number) - @all(Rho_s_old) = @all(Rho_s) - @all(Rho_f_old) = @all(Rho_f) - @all(X_s_old) = @all(X_s) - @all(Phi_old) = @all(Phi) - @all(Ptot_old) = @all(Ptot) - @all(Pf_old) = @all(Pf) - @all(Rho_X_old) = @all(Rho_s_old)*@all(X_s_old) - @all(Rho_t_old) = @all(Rho_f_old)*@all(Phi_old) + @all(Rho_s_old)*(1.0 - @all(Phi_old)) - @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - @all(Lam) = λ_η*@all(Eta) - return -end - -@parallel_indices (ix,iy) function compute_2!(Rho_t::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Rho_f::Data.Array, Phi::Data.Array, Rho_s::Data.Array, k_ηf::Data.Number) - if (ix<=size(Rho_t,1) && iy<=size(Rho_t,2)) Rho_t[ix,iy] = Rho_f[ix,iy]*Phi[ix,iy] + Rho_s[ix,iy]*(1.0-Phi[ix,iy]) end - if (ix<=size(para_cx,1) && iy<=size(para_cx,2)) para_cx[ix,iy] = 0.5*( Rho_f[ix,iy]*k_ηf*Phi[ix,iy]^3 + Rho_f[ix+1,iy]*k_ηf*Phi[ix+1,iy]^3 ) end - if (ix<=size(para_cy,1) && iy<=size(para_cy,2)) para_cy[ix,iy] = 0.5*( Rho_f[ix,iy]*k_ηf*Phi[ix,iy]^3 + Rho_f[ix,iy+1]*k_ηf*Phi[ix,iy+1]^3 ) end - return -end - -@parallel function compute_3!(q_f_X::Data.Array, q_f_Y::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Pf::Data.Array, dx::Data.Number, dy::Data.Number) - @all(q_f_X) = -@all(para_cx)*@d_xa(Pf)/dx # Correct Darcy flux with fluid pressure - @all(q_f_Y) = -@all(para_cy)*@d_ya(Pf)/dy # Correct Darcy flux with fluid pressure - return -end - -@parallel function compute_4!(∇q_f::Data.Array, Res_Pf::Data.Array, Rho_f::Data.Array, Rho_s_eq::Data.Array, X_s_eq::Data.Array, q_f_X::Data.Array, q_f_Y::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, ∇V_ρ_t::Data.Array, Pf::Data.Array, SlopeA::Data.Array, - rho_f_maxA::Data.Number, ρ_0::Data.Number, p_reactA::Data.Number, rho_s_difA::Data.Number, rho_s_up::Data.Number, rho_s_minA::Data.Number, x_difA::Data.Number, x_minA::Data.Number, dtp::Data.Number, dx::Data.Number, dy::Data.Number) - @all(∇q_f) = @d_xi(q_f_X)/dx + @d_yi(q_f_Y)/dy - @all(Res_Pf) = -@all(∇q_f) - (@inn(Rho_t) - @inn(Rho_t_old))/dtp - @inn(∇V_ρ_t) # CONSERVATION OF TOTAL MASS EQUATION - @all(Rho_f) = (rho_f_maxA * log(@all(Pf) + 1.0)^(1.0/3.5))/ρ_0 - @all(Rho_s_eq) = (-tanh( 6e2*(@all(Pf)-p_reactA) )*(rho_s_difA/2.0 + rho_s_up/3.0) + (rho_s_difA/2.0 - rho_s_up/3.0) + rho_s_minA + @all(SlopeA))/ρ_0 - @all(X_s_eq) = -tanh( 6e2*(@all(Pf)-p_reactA) )*x_difA/2.0 + x_difA/2.0 + x_minA - return -end - -@parallel function compute_5!(X_s::Data.Array, Rho_s::Data.Array, X_s_old::Data.Array, X_s_eq::Data.Array, Rho_s_old::Data.Array, Rho_s_eq::Data.Array, dtp::Data.Number, kin_time::Data.Number) - @all(X_s) = @all(X_s_old) + dtp*(@all(X_s_eq) - @all(X_s) )/kin_time - @all(Rho_s) = @all(Rho_s_old) + dtp*(@all(Rho_s_eq) - @all(Rho_s))/kin_time - return -end - -@parallel function compute_6!(dPfdτ::Data.Array, Pf::Data.Array, Rho_X_ϕ::Data.Array, Res_Phi::Data.Array, Phi::Data.Array, Res_Pf::Data.Array, Rho_s::Data.Array, X_s::Data.Array, Phi_old::Data.Array, Rho_X_old::Data.Array, ∇V_ρ_X::Data.Array, dampPf::Data.Number, dt_Pf::Data.Number, dtp::Data.Number) - @all(dPfdτ) = dampPf*@all(dPfdτ) + @all(Res_Pf) - @inn(Pf) = @inn(Pf) + dt_Pf*@all(dPfdτ) - @all(Rho_X_ϕ) = (1.0-@all(Phi))*@all(Rho_s)*@all(X_s) - @all(Res_Phi) = ( @all(Rho_X_ϕ) - (1.0-@all(Phi_old))*@all(Rho_X_old) )/dtp + @all(∇V_ρ_X) # CONSERVATION OF MASS OF MgO EQUATION - @all(Phi) = @all(Phi) + dtp*@all(Res_Phi) - return -end - -macro limit_min(A,min_val) esc(:( max($A[$ix,$iy],$min_val) )) end -@parallel function compute_7!(Eta::Data.Array, Lam::Data.Array, ∇V::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array, Ptot::Data.Array, Vx::Data.Array, Vy::Data.Array, Phi::Data.Array, Ptot_old::Data.Array, Pf::Data.Array, Pf_old::Data.Array, - dtPt::Data.Number, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number, dtp::Data.Number, K_d::Data.Number, η_min::Data.Number, α::Data.Number, dx::Data.Number, dy::Data.Number) - @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - @all(Eta) = @limit_min(Eta,η_min) - @all(Lam) = λ_η*@all(Eta) - @all(∇V) = @d_xa(Vx)/dx + @d_ya(Vy)/dy - @all(ε_xx) = @d_xa(Vx)/dx - 1.0/3.0*@all(∇V) - @all(ε_yy) = @d_ya(Vy)/dy - 1.0/3.0*@all(∇V) - @all(ε_xy) = 0.5*(@d_yi(Vx)/dy + @d_xi(Vy)/dx) - @all(Ptot) = @all(Ptot) - dtPt*( @all(Ptot) - (@all(Ptot_old)-dtp*( K_d*@all(∇V) - α*( (@all(Pf) - @all(Pf_old))/dtp ) - K_d*@all(Pf) / ((1.0-@all(Phi))*@all(Lam)) )) / ( 1.0 + dtp*K_d/((1.0-@all(Phi))*@all(Lam)) ) ) - return -end - -@parallel function compute_8!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, Eta::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array) - @all(τ_xx) = 2.0*@all(Eta) * @all(ε_xx) - @all(τ_yy) = 2.0*@all(Eta) * @all(ε_yy) - @all(τ_xy) = 2.0*@av(Eta) * @all(ε_xy) - return -end - -@parallel function compute_plast_1!(τII::Data.Array, LamP::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, σ_y::Data.Number) - @all(τII) = sqrt( 0.5*(@all(τ_xx)*@all(τ_xx) + @all(τ_yy)*@all(τ_yy)) + @all(τ_xyn)*@all(τ_xyn) ) - @all(LamP) = max(0.0, (1.0 - σ_y/@all(τII))) - return -end - -@parallel function compute_plast_2!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, LamP::Data.Array) - @all(τ_xx) = (1.0-@all(LamP))*@all(τ_xx) - @all(τ_yy) = (1.0-@all(LamP))*@all(τ_yy) - @all(τ_xy) = (1.0- @av(LamP))*@all(τ_xy) - return -end - -@parallel function compute_plast_3!(τII::Data.Array, LamP2::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, LamP::Data.Array) - @all(τII) = sqrt( 0.5*(@all(τ_xx)*@all(τ_xx) + @all(τ_yy)*@all(τ_yy)) + @all(τ_xyn)*@all(τ_xyn) ) - @all(LamP2) = @all(LamP2) + @all(LamP) - return -end - -@parallel function compute_9!(Res_Vx::Data.Array, Res_Vy::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, Ptot::Data.Array, τ_xy::Data.Array, dx::Data.Number, dy::Data.Number) - @all(Res_Vx) = -@d_xi(Ptot)/dx + @d_xi(τ_xx)/dx + @d_ya(τ_xy)/dy # HORIZONTAL FORCE BALANCE - @all(Res_Vy) = -@d_yi(Ptot)/dy + @d_yi(τ_yy)/dy + @d_xa(τ_xy)/dx # VERTICAL FORCE BALANCE - return -end - -@parallel function compute_10!(dVxdτ::Data.Array, dVydτ::Data.Array, Vx::Data.Array, Vy::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, dampV::Data.Number, dt_Stokes::Data.Number) - @all(dVxdτ) = @all(dVxdτ)*dampV + @all(Res_Vx) # dVxdτ .= dVxdτ.*(1-Vdmp/nx) .+ Rx - @all(dVydτ) = @all(dVydτ)*dampV + @all(Res_Vy) - @inn(Vx) = @inn(Vx) + dt_Stokes*@all(dVxdτ) # Pseudo-transient form of horizontal force balance - @inn(Vy) = @inn(Vy) + dt_Stokes*@all(dVydτ) # Pseudo-transient form of vertical force balance - return -end - -@parallel function postprocess!(dRhoT_dt::Data.Array, dRhosPhi_dt::Data.Array, dRhofPhi_dt::Data.Array, dRhoXPhi_dt::Data.Array, dPf_dt::Data.Array, dPt_dt::Data.Array, dPhi_dt::Data.Array, dRhos_dt::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Rho_s_old::Data.Array, Rho_f_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, Pf::Data.Array, Pf_old::Data.Array, Ptot::Data.Array, Ptot_old::Data.Array, dtp::Data.Number) - @all(dRhoT_dt) = (@all(Rho_t) - @all(Rho_t_old)) /dtp - @all(dRhosPhi_dt) = (@all(Rho_s)*(1.0-@all(Phi)) - @all(Rho_s_old)*(1.0-@all(Phi_old))) /dtp - @all(dRhofPhi_dt) = (@all(Rho_f)*@all(Phi) - @all(Rho_f_old)*@all(Phi_old)) /dtp - @all(dRhoXPhi_dt) = (@all(Rho_s)*@all(X_s)*(1-@all(Phi)) - @all(Rho_X_old)*(1-@all(Phi_old))) /dtp - @all(dPf_dt) = (@all(Pf) - @all(Pf_old)) /dtp - @all(dPt_dt) = (@all(Ptot) - @all(Ptot_old)) /dtp - @all(dPhi_dt) = (@all(Phi) - @all(Phi_old)) /dtp - @all(dRhos_dt) = (@all(Rho_s) - @all(Rho_s_old)) /dtp - return -end -################################################## -@views function PT_HMC() - runid = "plast1_rand" - nsave = 25 - nviz = 20 - do_restart = false - irestart = 100 # Step to restart from if do_reatart - # read in mat file - vars = matread(string(@__DIR__, "/LOOK_UP_atg.mat")) - Rho_s_LU = get(vars, "Rho_s" ,1) - Rho_f_LU = get(vars, "Rho_f" ,1) - X_LU = get(vars, "X_s_vec",1) - P_LU = get(vars, "P_vec" ,1)*1e8 - # Independent parameters - rad = 1.0 # Radius of initial P-perturbation [m] - η_m = 1.0 # Viscosity scale [Pa s] - P_ini = 1.0 # Initial ambient pressure [Pa] - ρ_0 = 3000.0 # Density scale [kg/m^3] - # Nondimensional parameters - elli_fac = 2.0 # Use 1 for circle - α = 0.0 # Counterclockwise angle of long axis with respect to vertical direction - ϕ_ini = 2e-2 # Initial porosity - ϕ_exp = 30.0 # Parameter controlling viscosity-porosity relation - lx_rad = 40.0 # LAMBDA_1 in equation (15) in the manuscript; Model height divided by inclusion radius; - lc_rad2 = 1e1 # LAMBDA_2 in equation (15) in the manuscript; Lc_rad2 = k_etaf*eta_mat/radius^2; []; Ratio of hydraulic fluid extraction to compaction extraction - λ_η = 2.0 # LAMBDA_3 in equation (15) in the manuscript; lam_eta = lambda / eta_mat; []; Ratio of bulk to shear viscosity - ly_lx = 1.0 # Model height divided by model width - Pini_Pappl = P_ini/12.73e8 # Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table - σ_y = 250.0*Pini_Pappl*1e6 # yield stress - # Dependant parameters - K_s = 1e11*Pini_Pappl # Solid elastic bulk modulus - k_ηf = lc_rad2*rad^2/η_m # Permeability divided by fluid viscosity; [m^2/(Pa s)] - lx = lx_rad*rad # Model width [m] - ly = ly_lx*lx # Model height [m] - P_LU = P_LU*Pini_Pappl # Transform look-up table stress to PT stress scale - K_d = K_s/2.0 # Elastic bulk modulus, drained - α = 1.0 - K_d/K_s # Biot-Willis coefficient - # Characteristic time scales - τ_f_dif = rad^2 / (k_ηf *K_s) - τ_f_dif_ϕ = rad^2 / (k_ηf*ϕ_ini^3*K_s) - τ_relax = η_m / K_s - τ_kinetic = 1.0/5.0/3.0/3.0/3.0/3.0 * 1/3*τ_f_dif_ϕ - τ_deform = 0.5/7.0/6.0 * 1.0*τ_f_dif_ϕ - ε_bg = 1.0 / τ_deform - Da = ε_bg/(P_ini/η_m) # Re-scaling of Da (LAMBDA_4) - # Numerics - nt = 1e4 - tol = 1e-7 # Tolerance for pseudo-transient iterations - cfl = 1.0/16.1 # CFL parameter for PT-Stokes solution - damping = 1 - Re_Pf = 100π - Re_V = 100π - r = 1.5 - dt_fact = 1.0 - dtp = τ_f_dif / 2.0 / dt_fact # Time step physical - time_tot = dt_fact * 2*5e3*dtp # Total time of simulation - itmax = 5e6 - nout = 1e3 - nsm = 5 # number of porosity smoothing steps - explicit diffusion - η_min = 1e-5 - kin_time = 1e1*τ_f_dif_ϕ - kin_time_final = τ_kinetic - Kin_time_vec = [1e25*τ_f_dif_ϕ; range(kin_time, stop=kin_time_final, length=20); kin_time_final*ones(Int(round(time_tot/dtp)))] - # Configuration of grid, matrices and numerical parameters - dx, dy = lx/(nx-1), ly/(ny-1) # Grid spacing - xc, yc = -lx/2:dx:lx/2, -ly/2:dy:ly/2 # Coordinate vector - xv, yv = -lx/2-dx/2:dx:lx/2+dx/2, -ly/2-dy/2:dy:ly/2+dy/2 # Horizontal vector for Vx which is one more than basic grid - (Xc2, Yc2) = ([x for x=xc, y=yc], [y for x=xc, y=yc]) - (Xc2vx, Yc2vx) = ([x for x=xv, y=yc], [y for x=xv, y=yc]) - (Xc2vy, Yc2vy) = ([x for x=xc, y=yv], [y for x=xc, y=yv]) - rad_a = rad - rad_b = rad_a*elli_fac - X_rot = Xc2*cosd(α)+Yc2*sind(α) - Y_rot = -Xc2*sind(α)+Yc2*cosd(α) - X_elli = rad_a.*cos.(0:0.01:2*pi).*cosd(α).+rad_b.*sin.(0:0.01:2*pi).*sind(α) - Y_elli = -rad_a.*cos.(0:0.01:2*pi).*sind(α).+rad_b.*sin.(0:0.01:2*pi).*cosd(α) - XY_elli = (-X_elli, Y_elli) - # Analytical fit of look-up table - p_minA, p_maxA = minimum(P_LU), maximum(P_LU) - rho_s_up = 50.0 - Pf = P_ini*ones(nx, ny) - SlopeA = (Pf.-p_minA)/p_maxA*rho_s_up - rho_s_max = Rho_s_LU[1] - rho_s_minA = minimum(Rho_s_LU) - rho_s_difA = rho_s_max-rho_s_minA - p_reactA = 12.65*1e8*Pini_Pappl - rho_f_maxA = maximum(Rho_f_LU) # Parameters for fluid density - x_max = maximum(X_LU) # Parameters for mass fraction - x_minA = minimum(X_LU) - x_difA = x_max-x_minA - # Density, compressibility and gamma from concentration and pressure from thermodynamic data base - Rho_s = Data.Array( (-tanh.( 6e2*(Pf.-p_reactA) )*(rho_s_difA/2.0 .+ rho_s_up/3.0) .+ (rho_s_difA/2.0 .- rho_s_up/3.0) .+ rho_s_minA .+ SlopeA)/ρ_0 ) - Rho_f = Data.Array( (rho_f_maxA .* log.(Pf .+ 1.0).^(1.0/3.5))/ρ_0 ) - X_s = Data.Array( -tanh.( 6e2*(Pf.-p_reactA) )*x_difA/2.0 .+ x_difA/2.0 .+ x_minA ) - SlopeA = Data.Array( SlopeA ) - # Initialize ALL arrays in Julia - Ptot = @zeros(nx , ny ) # Initial ambient fluid pressure - ∇V = @zeros(nx , ny ) - ∇V_ρ_X = @zeros(nx , ny ) - ∇V_ρ_t = @zeros(nx , ny ) - τ_xx = @zeros(nx , ny ) # Deviatoric stress - τ_yy = @zeros(nx , ny ) # Deviatoric stress - τ_xy = @zeros(nx-1, ny-1) # Deviatoric stress - τ_xyn = @zeros(nx , ny ) - Res_Vx = @zeros(nx-1, ny-2) - Res_Vy = @zeros(nx-2, ny-1) - dVxdτ = @zeros(nx-1, ny-2) # damping - dVydτ = @zeros(nx-2, ny-1) # damping - Rho_s_eq = @zeros(nx , ny ) - X_s_eq = @zeros(nx , ny ) - Rho_s_old = @zeros(nx , ny ) - Rho_f_old = @zeros(nx , ny ) - X_s_old = @zeros(nx , ny ) - Rho_X_old = @zeros(nx , ny ) - Phi_old = @zeros(nx , ny ) - Ptot_old = @zeros(nx , ny ) - Pf_old = @zeros(nx , ny ) - Rho_t_old = @zeros(nx , ny ) - Rho_t = @zeros(nx , ny ) - para_cx = @zeros(nx-1, ny ) - para_cy = @zeros(nx , ny-1) - q_f_X = @zeros(nx-1, ny ) - q_f_Y = @zeros(nx , ny-1) - ∇q_f = @zeros(nx-2, ny-2) - Res_Pf = @zeros(nx-2, ny-2) - dPfdτ = @zeros(nx-2, ny-2) # damping - Rho_X_ϕ = @zeros(nx , ny ) - Res_Phi = @zeros(nx , ny ) - ε_xx = @zeros(nx , ny ) - ε_yy = @zeros(nx , ny ) - ε_xy = @zeros(nx-1, ny-1) - τII = @zeros(nx , ny ) - LamP = @zeros(nx , ny ) - LamP2 = @zeros(nx , ny ) - # Arrays for post-processing - dRhoT_dt = @zeros(nx , ny ) - dRhosPhi_dt = @zeros(nx , ny ) - dRhofPhi_dt = @zeros(nx , ny ) - dRhoXPhi_dt = @zeros(nx , ny ) - dPf_dt = @zeros(nx , ny ) - dPt_dt = @zeros(nx , ny ) - dPhi_dt = @zeros(nx , ny ) - dRhos_dt = @zeros(nx , ny ) - # TMP arrays for swell2 - TmpX = @zeros(nx+1, ny ) - TmpY = @zeros(nx , ny+1) - TmpS1 = @zeros(nx , ny-1) - # arrays for visu - Vx_f = zeros(nx , ny ) - Vy_f = zeros(nx , ny ) - # POROSITY INITIAL ############################################################################# - # Elliptical porosity field #################################################################### - #Phi_ini = ϕ_ini*ones(nx, ny) - # Phi_ini[sqrt.((X_rot .- 2.0).^2 ./ rad_a.^2 .+ (Y_rot .+ 6.0).^2 ./ rad_b.^2) .< 1.0] .= 2.5*ϕ_ini # Porosity pertubation - # Phi_ini[sqrt.((X_rot .+ 2.0).^2 ./ rad_a.^2 .+ (Y_rot .- 6.0).^2 ./ rad_b.^2) .< 1.0] .= 2.5*ϕ_ini # Porosity pertubation - # for smo=1:nsm # Smooting of perturbation - # Phi_ini[2:end-1,:] .= Phi_ini[2:end-1,:] .+ 0.4.*(Phi_ini[3:end,:].-2.0.*Phi_ini[2:end-1,:].+Phi_ini[1:end-2,:]) - # Phi_ini[:,2:end-1] .= Phi_ini[:,2:end-1] .+ 0.4.*(Phi_ini[:,3:end].-2.0.*Phi_ini[:,2:end-1].+Phi_ini[:,1:end-2]) - # end - # Gaussian porosity field ###################################################################### - #Pert = Data.Array((8 .* Phi_ini .- Phi_ini) .* exp.(.-(Xc2./rad_a).^2 .- (Yc2./rad_b).^2)) - #Phi_ini = Data.Array(Phi_ini) - #Phi = Phi_ini .+ Pert - #Phi = copy(Phi_ini) - # Random porosity field - Phi = @ones(nx, ny) - ϕ_range = (0.015, 0.16) # range - sf = 1.0 # standard deviation - cl = (lx/12.0, ly/8.0) # correlation length - nh = 10000 # inner parameter, number of harmonics - grf2D_expon!(Phi, sf, cl, nh, size(Phi,1), size(Phi,2), dx, dy; do_reset=true) - xb, yb = lx/4, ly/4 # width of the boundary region - xind, yind = Int(ceil(xb/dx)), Int(ceil(yb/dy)) - @parallel smooth_border_x!(Phi, xind) - @parallel smooth_border_y!(Phi, yind) - for smo=1:25 - Phi[2:end-1,:] .= Phi[2:end-1,:] .+ 0.4.*(Phi[3:end,:].-2.0.*Phi[2:end-1,:].+Phi[1:end-2,:]) - Phi[:,2:end-1] .= Phi[:,2:end-1] .+ 0.4.*(Phi[:,3:end].-2.0.*Phi[:,2:end-1].+Phi[:,1:end-2]) - end - nxyb = 100 - for smo=1:50 - Phi[2:nxyb,:] .= Phi[2:nxyb,:] .+ 0.4.*(Phi[3:nxyb+1,:] .-2.0.*Phi[2:nxyb,:].+Phi[1:nxyb-1,:]) - Phi[:,2:nxyb] .= Phi[:,2:nxyb] .+ 0.4.*(Phi[:,3:nxyb+1] .-2.0.*Phi[:,2:nxyb].+Phi[:,1:nxyb-1]) - Phi[end-nxyb:end-1,:] .= Phi[end-nxyb:end-1,:] .+ 0.4.*(Phi[end-nxyb+1:end,:].-2.0.*Phi[end-nxyb:end-1,:].+Phi[end-nxyb-1:end-2,:]) - Phi[:,end-nxyb:end-1] .= Phi[:,end-nxyb:end-1] .+ 0.4.*(Phi[:,end-nxyb+1:end].-2.0.*Phi[:,end-nxyb:end-1].+Phi[:,end-nxyb-1:end-2]) - end - min_ϕ = minimum(Phi) - Phi .= Phi .- min_ϕ - max_ϕ = maximum(Phi) - Phi .= Phi ./ max_ϕ .* (ϕ_range[2] - ϕ_range[1]) .+ ϕ_range[1] - # POROSITY INITIAL ############################################################################# - Eta = η_m*@ones(nx, ny) # Shear viscosity, alternative init: # @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - Lam = λ_η*@ones(nx, ny) # Bulk viscosity, alternative init: # @all(Lam) = λ_η*@all(Eta) - # Vx_ps = ε_bg*Data.Array(Xc2vx) # Pure shear, shortening in x - # Vy_ps = -ε_bg*Data.Array(Yc2vy) # Pure shear, extension in y - # Vx_ss = ε_bg*Data.Array(Yc2vx) # Simple shear, shearing in x - # Vy_ss = 0.0*Data.Array(Yc2vy) # Simple shear, zero velocity in y - # Vx = 0.5.*(Vx_ps .+ Vx_ss) - # Vy = 0.5.*(Vy_ps .+ Vy_ss) - Vx = ε_bg*Data.Array(Yc2vx) # Simple shear, shearing in x - Vy = 0.0*Data.Array(Yc2vy) # Simple shear, zero velocity in y - Pf = Data.Array(Pf) - Ptot .= Pf # Initial total pressure - # Parameters for time loop and pseudo-transient iterations - min_dxdy2 = min(dx,dy).^2 - timeP = 0.0 # Initial time - it = 0 # Integer count for iteration loop - itp = 0 # Integer count for time loop - save_count = 0 - Time_vec = [] - ρ_i_Pf = cfl*Re_Pf/nx - ρ_i_V = cfl*Re_V /nx - dampPf = damping.*(1.0 .- ρ_i_Pf) - dampV = damping.*(1.0 .- ρ_i_V ) - if do_save || do_viz - !ispath(joinpath(@__DIR__,"../output")) && mkdir(joinpath(@__DIR__,"../output")) - dirname = joinpath(@__DIR__, "../output/output_$(runid)_$(nx)x$(ny)"); !ispath(dirname) && mkdir(dirname) - end - it_viz = 0 - # time loop - while timeP < time_tot && itp < nt - if do_restart - restart_file = joinpath(@__DIR__, dirname, "pt_hmc_Atg_") * @sprintf("%04d", irestart) * ".mat" - vars_restart = matread(restart_file) - Ptot .= Data.Array(get(vars_restart, "Ptot" ,1)) - Pf .= Data.Array(get(vars_restart, "Pf" ,1)) - X_s .= Data.Array(get(vars_restart, "X_s" ,1)) - Phi .= Data.Array(get(vars_restart, "Phi" ,1)) - Rho_s .= Data.Array(get(vars_restart, "Rho_s" ,1)) - Rho_f .= Data.Array(get(vars_restart, "Rho_f" ,1)) - Vx .= Data.Array(get(vars_restart, "Vx" ,1)) - Vy .= Data.Array(get(vars_restart, "Vy" ,1)) - Vx_f .= Data.Array(get(vars_restart, "Vx_f" ,1)) - Vy_f .= Data.Array(get(vars_restart, "Vy_f" ,1)) - LamP2 .= Data.Array(get(vars_restart, "LamP2" ,1)) - Rho_s_old .= Data.Array(get(vars_restart, "Rho_s_old",1)) - Rho_f_old .= Data.Array(get(vars_restart, "Rho_f_old",1)) - X_s_old .= Data.Array(get(vars_restart, "X_s_old" ,1)) - Rho_X_old .= Data.Array(get(vars_restart, "Rho_X_old",1)) - Phi_old .= Data.Array(get(vars_restart, "Phi_old" ,1)) - Ptot_old .= Data.Array(get(vars_restart, "Ptot_old" ,1)) - Pf_old .= Data.Array(get(vars_restart, "Pf_old" ,1)) - Rho_t_old .= Data.Array(get(vars_restart, "Rho_t_old",1)) - Time_vec = get(vars_restart, "Time_vec" ,1) - itp = get(vars_restart, "itp" ,1) - timeP = get(vars_restart, "timeP" ,1) - it = get(vars_restart, "it" ,1) - it_tstep = get(vars_restart, "it_tstep" ,1) - do_restart = false - end - err_M = 2*tol; itp += 1 - timeP = timeP+dtp; push!(Time_vec, timeP) - @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η) - kin_time = Kin_time_vec[itp] - # PT loop - it_tstep=0; err_evo1=[]; err_evo2=[]; err_pl=[] - dt_Stokes, dt_Pf = cfl*min_dxdy2, cfl*min_dxdy2 - dt_Pt = maximum(Eta)/(lx/dx) - while err_M>tol && it_tstep 1) @parallel compute_5!(X_s, Rho_s, X_s_old, X_s_eq, Rho_s_old, Rho_s_eq, dtp, kin_time) end - # Porosity evolution - @parallel compute_6!(dPfdτ, Pf, Rho_X_ϕ, Res_Phi, Phi, Res_Pf, Rho_s, X_s, Phi_old, Rho_X_old, ∇V_ρ_X, dampPf, dt_Pf, dtp) - @parallel (1:size(Pf,1)) bc_y!(Pf) - @parallel (1:size(Pf,2)) bc_x!(Pf) - # Stokes - @parallel swell2_x!(TmpX, Rho_X_ϕ) - @parallel swell2_y!(TmpY, Rho_X_ϕ) - @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) - @parallel laplace!(∇V_ρ_X, TmpX, TmpY, dx, dy) - @parallel swell2_x!(TmpX, Rho_t) - @parallel swell2_y!(TmpY, Rho_t) - @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) - @parallel laplace!(∇V_ρ_t, TmpX, TmpY, dx, dy) - @parallel compute_7!(Eta, Lam, ∇V, ε_xx, ε_yy, ε_xy, Ptot, Vx, Vy, Phi, Ptot_old, Pf, Pf_old, dt_Pt, η_m, ϕ_exp, ϕ_ini, λ_η, dtp, K_d, η_min, α, dx, dy) - @parallel compute_8!(τ_xx, τ_yy, τ_xy, Eta, ε_xx, ε_yy, ε_xy) - @parallel swell2_x!(TmpS1, τ_xy) - @parallel swell2_y!(τ_xyn, TmpS1) - # Plastic starts - @parallel compute_plast_1!(τII, LamP, τ_xx, τ_yy, τ_xyn, σ_y) - @parallel compute_plast_2!(τ_xx, τ_yy, τ_xy, LamP) - @parallel swell2_x!(TmpS1, τ_xy) - @parallel swell2_y!(τ_xyn, TmpS1) - @parallel compute_plast_3!(τII, LamP2, τ_xx, τ_yy, τ_xyn, LamP) - # Plastic ends - @parallel compute_9!(Res_Vx, Res_Vy, τ_xx, τ_yy, τ_xyn, Ptot, τ_xy, dx, dy) - @parallel compute_10!(dVxdτ, dVydτ, Vx, Vy, Res_Vx, Res_Vy, dampV, dt_Stokes) - if it_tstep % nout == 0 && it_tstep > 250 - err_Mx = dt_Stokes*maximum(abs.(Res_Vx)/maximum(abs.(Vx))) # Error horizontal velocitiy - err_R_Mx = maximum(abs.(Res_Vx)) # Error horizontal force balance - err_My = dt_Stokes*maximum(abs.(Res_Vy)/maximum(abs.(Vy))) # Error vertical velocity - err_R_My = maximum(abs.(Res_Vy)) # Error vertical force balance - err_Pf = dt_Pf*maximum(abs.(Res_Pf)/maximum(abs.(Pf))) # Error fluid pressure - err_R_Pf = maximum(abs.(Res_Pf)) # Error total mass conservation - err_Phi = dtp*maximum(abs.(Res_Phi)) # Error porosity - err_R_Phi= maximum(abs.(Res_Phi)) # Error MgO mass conservation - err_M = maximum([err_Pf, err_Mx, err_My, err_Phi, err_R_Pf, err_R_Mx, err_R_My, err_R_Phi]) # Error total - if isnan(err_M) error("NoNs - stopping simulation.") end - err_evo1 = push!(err_evo1, it_tstep); err_evo2 = push!(err_evo2, err_M) - err_pl = push!(err_pl, maximum(τII)/σ_y - 1.0) - # plot evol - # p1 = plot(err_evo1, err_evo2, legend=false, xlabel="# iterations", ylabel="log10(error)", linewidth=2, markershape=:circle, markersize=3, labels="max(error)", yaxis=:log10) - # display(p1) - @printf("iter = %d, error = %1.3e \n", it_tstep, err_M) - end - end # end PT loop - println("it = $(itp), time = $(round(timeP, sigdigits=3)) (time_tot = $(round(time_tot, sigdigits=3)))") - # Visu - if do_viz && (itp % nviz == 0 || itp == 1) - it_viz += 1 - swell2h!(Vx_f, Array(q_f_X)./(Array(Rho_f[1:end-1,:])./Array(Phi[1:end-1,:]).+Array(Rho_f[2:end,:])./Array(Phi[2:end,:])).*2.0, 1) - swell2h!(Vy_f, Array(q_f_Y)./(Array(Rho_f[:,1:end-1])./Array(Phi[:,1:end-1]).+Array(Rho_f[:,2:end])./Array(Phi[:,2:end])).*2.0, 2) - η_char = 1e19 - Length_model_m = rad - Time_model_sec = rad^2/(k_ηf*K_s) - Length_phys_m = 0.01 - Time_phys_sec = 0.01^2 / (1e-19 / 1e-3 / (1e-2/8.5e8)) - Vel_phys_m_s = (Length_phys_m/Length_model_m) / (Time_phys_sec/Time_model_sec) - lw = 1.2; fontsize = 8 - opts1 = (aspect_ratio=1, yaxis=font(fontsize, "Courier"), xaxis=font(fontsize, "Courier"), - ticks=nothing, framestyle=:box, titlefontsize=fontsize, titlefont="Courier", colorbar_title="", - xlims=(xc[1], xc[end]), ylims=(yc[1], yc[end]), c = cgrad(:davos, rev = true) ) - opts2 = (linewidth=lw, linecolor="white", legend=false, framestyle=:box) - p2 = heatmap(xc, yc, Array(Pf)'./Pini_Pappl./1e8; title="A) p_f [kbar]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2... ) - p3 = heatmap(xc, yc, Array(Ptot)'./Pini_Pappl./1e8; title="B) p [kbar]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p4 = heatmap(xc, yc, Array(∇V)'.*Time_model_sec./Time_phys_sec; title="C) ∇(v_s) [1/s]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p5 = heatmap(xc, yc, Array(X_s)'; title="D) X_s", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p6 = heatmap(xc, yc, Array(Rho_s)'.*ρ_0; title="E) ρ_s [kg/m^3]", opts1...) - # p6 = heatmap(xc, yc, sqrt.(av_xa(Array(Vx)).^2 .+ av_ya(Array(Vy)).^2)'*Vel_phys_m_s; title="E) ||v_s|| [m/s]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p7 = heatmap(xc, yc, Array(Phi)'; title="F) ϕ", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p8 = heatmap(xc, yc, Array(Rho_f)'.*ρ_0; title="G) ρ_f [kg/m^3]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p9 = heatmap(xc, yc, Array(τII)'./Pini_Pappl./1e6; title="H) τII [MPa]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - p10 = heatmap(xc, yc, log10.(Array(Eta)'.*η_char); title="I) log10(ηs) [Pas]", opts1...) - # plot!(XY_elli[1], XY_elli[2]; opts2...) - display(plot(p2, p3, p4, p5, p6, p7, p8, p9, p10, background_color=:transparent, foreground_color=:gray, dpi=300)) - savefig(joinpath(@__DIR__, dirname, "fig_pt_hmc_Atg_$(it_viz).png")) - end - if do_save && (itp % nsave == 0 || itp==1) - @parallel postprocess!(dRhoT_dt, dRhosPhi_dt, dRhofPhi_dt, dRhoXPhi_dt, dPf_dt, dPt_dt, dPhi_dt, dRhos_dt, Rho_s, Rho_f, X_s, Phi, Rho_s_old, Rho_f_old, Rho_X_old, Phi_old, Rho_t, Rho_t_old, Pf, Pf_old, Ptot, Ptot_old, dtp) - matwrite(joinpath(@__DIR__, dirname, "pt_hmc_Atg_") * @sprintf("%04d", itp) * ".mat", - Dict("Ptot"=> Array(Ptot), - "Pf"=> Array(Pf), - "divV"=> Array(∇V), - "X_s"=> Array(X_s), - "Rho_s"=> Array(Rho_s), - "Phi"=> Array(Phi), - "Rho_f"=> Array(Rho_f), - "TauII"=> Array(τII), - "Eta"=> Array(Eta), - "Tauxx"=> Array(τ_xx), - "Tauyy"=> Array(τ_yy), - "Tauxy"=> Array(τ_xy), - "Vx"=> Array(Vx), - "Vy"=> Array(Vy), - "Vx_f"=> Array(Vx_f), - "Vy_f"=> Array(Vy_f), - "Ellipse_x"=> Array(X_elli), - "Ellipse_y"=> Array(Y_elli), - "Time_vec"=> Array(Time_vec), - "LamP2"=> Array(LamP2), - "Rho_s_old"=> Array(Rho_s_old), - "Rho_f_old"=> Array(Rho_f_old), - "X_s_old"=> Array(X_s_old), - "Rho_X_old"=> Array(Rho_X_old), - "Phi_old"=> Array(Phi_old), - "Ptot_old"=> Array(Ptot_old), - "Pf_old"=> Array(Pf_old), - "Rho_t_old"=> Array(Rho_t_old), - "Lam"=> Array(Lam), - "dRhoT_dt"=> Array(dRhoT_dt), - "dRhosPhi_dt"=> Array(dRhosPhi_dt), - "dRhofPhi_dt"=> Array(dRhofPhi_dt), - "dRhoXPhi_dt"=> Array(dRhoXPhi_dt), - "dPf_dt"=> Array(dPf_dt), - "dPt_dt"=> Array(dPt_dt), - "dPhi_dt"=> Array(dPhi_dt), - "dRhos_dt"=> Array(dRhos_dt), - "Res_pf"=> Array(Res_Pf), - "div_qf"=> Array(∇q_f), - "div_rhoTvs"=> Array(∇V_ρ_t), - "div_rhoXvs"=> Array(∇V_ρ_X), - "Ch_ti_fluid_dif_phi"=> τ_f_dif_ϕ, - "Ch_ti_deformation"=> τ_deform, - "Ch_ti_kinetic"=> τ_kinetic, - "Ch_ti_relaxation"=> τ_relax, - "itp"=> itp, - "timeP"=> timeP, - "it"=> it, - "it_tstep"=> it_tstep, - "xc"=> Array(xc), "yc"=> Array(yc)); compress = true) - end - end - return -end - -PT_HMC() diff --git a/scripts_2023/DeHy.jl b/scripts_2023/DeHy.jl deleted file mode 100644 index 9a33b7a..0000000 --- a/scripts_2023/DeHy.jl +++ /dev/null @@ -1,634 +0,0 @@ -# Hydro-mechanical-chemical 2D model for olivine vein formation by dehydration of serpentinite -# Stefan Schmalholz, 22.03.2023 -# Resolution `nx`, `ny` is 500 x 500 for fast calculation. Use 900 x 900 to reproduce results in manuscript. -# Time step is limited to 4000 steps `it` -const run_test = haskey(ENV, "RUN_TEST") ? parse(Bool, ENV["RUN_TEST"]) : false -const USE_GPU = haskey(ENV, "USE_GPU" ) ? parse(Bool, ENV["USE_GPU"] ) : true -const GPU_ID = haskey(ENV, "GPU_ID" ) ? parse(Int, ENV["GPU_ID"] ) : 0 -using ParallelStencil -using ParallelStencil.FiniteDifferences2D -@static if USE_GPU - @init_parallel_stencil(CUDA, Float64, 2) - CUDA.device!(GPU_ID) # select GPU - using ParallelRandomFields.grf2D_CUDA -else - @init_parallel_stencil(Threads, Float64, 2) - using ParallelRandomFields.grf2D_Threads -end -using Plots, Printf, Statistics, LinearAlgebra, MAT - -import ParallelStencil: INDICES -ix,iy = INDICES[1], INDICES[2] -ixi,iyi = :($ix+1), :($iy+1) - -"Average in x and y dimension" -@views av(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) -"Average in x dimension" -@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) -"Average in y dimension" -@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) - -@views function swell2h!(B, A, ndim) - B .= B.*0.0 - if ndim==1 - B[2:end-1,:] .= (A[2:end,:] .+ A[1:end-1,:])./2.0 - B[1 ,:] .= 1.5*A[1 ,:] .- 0.5*A[2 ,:] - B[end ,:] .= 1.5*A[end,:] .- 0.5*A[end-1,:] - elseif ndim==2 - B[:,2:end-1] .= (A[:,2:end] .+ A[:,1:end-1])./2.0 - B[:,1 ] .= 1.5*A[:,1 ] .- 0.5*A[:,2 ] - B[:,end ] .= 1.5*A[:,end] .- 0.5*A[:,end-1] - end - return B -end - -@parallel_indices (ix,iy) function swell2_x!(B::Data.Array, A::Data.Array) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if (2<=ix<=size(B,1)-1 && iy<=size(B,2)) B[ix,iy] = 0.5*(A[ix ,iy] + A[ix-1,iy]) end - if ( ix==1 && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix ,iy] - 0.5*A[ix+1,iy] end - if ( ix==size(B,1) && iy<=size(B,2)) B[ix,iy] = 1.5*A[ix-1,iy] - 0.5*A[ix-2,iy] end - return -end - -@parallel_indices (ix,iy) function swell2_y!(B::Data.Array, A::Data.Array) - if (ix<=size(B,1) && iy<=size(B,2)) B[ix,iy] = 0.0 end - if (ix<=size(B,1) && 2<=iy<=size(B,2)-1) B[ix,iy] = 0.5*(A[ix,iy ] + A[ix,iy-1]) end - if (ix<=size(B,1) && iy==1 ) B[ix,iy] = 1.5*A[ix,iy ] - 0.5*A[ix,iy+1] end - if (ix<=size(B,1) && iy==size(B,2) ) B[ix,iy] = 1.5*A[ix,iy-1] - 0.5*A[ix,iy-2] end - return -end - -@parallel function cum_mult2!(A1::Data.Array, A2::Data.Array, B1::Data.Array, B2::Data.Array) - @all(A1) = @all(A1)*@all(B1) - @all(A2) = @all(A2)*@all(B2) - return -end - -@parallel function laplace!(A::Data.Array, TmpX::Data.Array, TmpY::Data.Array, dx::Data.Number, dy::Data.Number) - @all(A) = @d_xa(TmpX)/dx + @d_ya(TmpY)/dy - return -end - -@parallel_indices (iy) function bc_x!(A::Data.Array) - A[1 , iy] = A[2 , iy] - A[end, iy] = A[end-1, iy] - return -end - -@parallel_indices (ix) function bc_y!(A::Data.Array) - A[ix, 1 ] = A[ix, 2 ] - A[ix, end] = A[ix, end-1] - return -end - -@parallel_indices (ix,iy) function smooth_border_x!(Phi::Data.Array, xind) - if (ix<=xind && iy<=size(Phi,2)) Phi[ix,iy] = Phi[ix,iy] * ((ix - 1)/xind) end - if (ix>=(size(Phi,1)-xind+1) && iy<=size(Phi,2)) Phi[ix,iy] = Phi[ix,iy] * ((size(Phi,1) - ix)/xind) end - return -end - -@parallel_indices (ix,iy) function smooth_border_y!(Phi::Data.Array, yind) - if (ix<=size(Phi,1) && iy<=yind ) Phi[ix,iy] = Phi[ix,iy] * ((iy - 1)/yind) end - if (ix<=size(Phi,1) && iy>=(size(Phi,2)-yind+1)) Phi[ix,iy] = Phi[ix,iy] * ((size(Phi,2) - iy)/yind) end - return -end - -################################################## - -@parallel function compute_1_ini!(Rho_s_old::Data.Array, Rho_f_old::Data.Array, X_s_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Ptot_old::Data.Array, Pf_old::Data.Array, Rho_t_old::Data.Array, Eta::Data.Array, Lam::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Ptot::Data.Array, Pf::Data.Array, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number, n_v::Data.Number, Rho_s_amb::Data.Array, X_s_amb::Data.Array) - @all(Rho_s_old) = @all(Rho_s) - @all(Rho_f_old) = @all(Rho_f) - @all(X_s_old) = @all(X_s) - @all(Pf_old) = @all(Pf) - @all(Rho_X_old) = @all(Rho_s_old)*@all(X_s_old) - @all(Phi_old) = @all(Phi) - @all(Ptot_old) = @all(Ptot) - @all(Phi_old) = 1.0 - ( @all(Rho_s_amb)*@all(X_s_amb) ) * (1.0 - ϕ_ini)/@all(Rho_X_old) - @all(Phi) = @all(Phi_old) - @all(Rho_t_old) = @all(Rho_f_old)*@all(Phi_old) + @all(Rho_s_old)*(1.0 - @all(Phi_old)) - @all(Eta) = η_m*exp(-ϕ_exp*( @all(Phi)/ϕ_ini - @all(Phi)/@all(Phi) )) -# @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) -# @all(Eta) = η_m*(ϕ_ini/@all(Phi))^n_v - @all(Lam) = λ_η*@all(Eta) - return -end - -@parallel function compute_1!(Rho_s_old::Data.Array, Rho_f_old::Data.Array, X_s_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Ptot_old::Data.Array, Pf_old::Data.Array, Rho_t_old::Data.Array, Eta::Data.Array, Lam::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Ptot::Data.Array, Pf::Data.Array, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number, n_v::Data.Number, Rho_s_amb::Data.Array, X_s_amb::Data.Array) - @all(Rho_s_old) = @all(Rho_s) - @all(Rho_f_old) = @all(Rho_f) - @all(X_s_old) = @all(X_s) - @all(Pf_old) = @all(Pf) - @all(Rho_X_old) = @all(Rho_s_old)*@all(X_s_old) - @all(Phi_old) = @all(Phi) - @all(Ptot_old) = @all(Ptot) - @all(Rho_t_old) = @all(Rho_f_old)*@all(Phi_old) + @all(Rho_s_old)*(1.0 - @all(Phi_old)) - @all(Eta) = η_m*exp(-ϕ_exp*( @all(Phi)/ϕ_ini - @all(Phi)/@all(Phi) )) -# @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) -# @all(Eta) = η_m*(ϕ_ini/@all(Phi))^n_v - @all(Lam) = λ_η*@all(Eta) - return -end - -@parallel_indices (ix,iy) function compute_2!(Rho_t::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Rho_f::Data.Array, Phi::Data.Array, Rho_s::Data.Array, k_ηf::Data.Number, n_p::Data.Number) - if (ix<=size(Rho_t,1) && iy<=size(Rho_t,2)) Rho_t[ix,iy] = Rho_f[ix,iy]*Phi[ix,iy] + Rho_s[ix,iy]*(1.0-Phi[ix,iy]) end - if (ix<=size(para_cx,1) && iy<=size(para_cx,2)) para_cx[ix,iy] = 0.5*( Rho_f[ix,iy]*k_ηf*Phi[ix,iy]^n_p + Rho_f[ix+1,iy]*k_ηf*Phi[ix+1,iy]^n_p ) end - if (ix<=size(para_cy,1) && iy<=size(para_cy,2)) para_cy[ix,iy] = 0.5*( Rho_f[ix,iy]*k_ηf*Phi[ix,iy]^n_p + Rho_f[ix,iy+1]*k_ηf*Phi[ix,iy+1]^n_p ) end - return -end - -@parallel function compute_3!(q_f_X::Data.Array, q_f_Y::Data.Array, para_cx::Data.Array, para_cy::Data.Array, Pf::Data.Array, dx::Data.Number, dy::Data.Number) - @all(q_f_X) = -@all(para_cx)*@d_xa(Pf)/dx # Correct Darcy flux with fluid pressure - @all(q_f_Y) = -@all(para_cy)*@d_ya(Pf)/dy # Correct Darcy flux with fluid pressure - return -end - -@parallel function compute_4!(∇q_f::Data.Array, Res_Pf::Data.Array, Rho_f::Data.Array, Rho_s_eq::Data.Array, X_s_eq::Data.Array, q_f_X::Data.Array, q_f_Y::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, ∇V_ρ_t::Data.Array, Pf::Data.Array, SlopeA::Data.Array, - rho_f_maxA::Data.Number, ρ_0::Data.Number, p_reactA::Data.Number, rho_s_difA::Data.Number, rho_s_up::Data.Number, rho_s_minA::Data.Number, x_difA::Data.Number, x_minA::Data.Number, dtp::Data.Number, dx::Data.Number, dy::Data.Number) - @all(∇q_f) = @d_xi(q_f_X)/dx + @d_yi(q_f_Y)/dy - @all(Res_Pf) = -@all(∇q_f) - (@inn(Rho_t) - @inn(Rho_t_old))/dtp - @inn(∇V_ρ_t) # CONSERVATION OF TOTAL MASS EQUATION - @all(Rho_f) = (rho_f_maxA * log(@all(Pf) + 1.0)^(1.0/3.5))/ρ_0 - @all(Rho_s_eq) = (-tanh( 6e2*(@all(Pf)-p_reactA) )*(rho_s_difA/2.0 + rho_s_up/3.0) + (rho_s_difA/2.0 - rho_s_up/3.0) + rho_s_minA + @all(SlopeA))/ρ_0 - @all(X_s_eq) = -tanh( 6e2*(@all(Pf)-p_reactA) )*x_difA/2.0 + x_difA/2.0 + x_minA - return -end - -@parallel function compute_5!(X_s::Data.Array, Rho_s::Data.Array, X_s_old::Data.Array, X_s_eq::Data.Array, Rho_s_old::Data.Array, Rho_s_eq::Data.Array, dtp::Data.Number, kin_time::Data.Number) - @all(X_s) = @all(X_s_old) + dtp*(@all(X_s_eq) - @all(X_s) )/kin_time - @all(Rho_s) = @all(Rho_s_old) + dtp*(@all(Rho_s_eq) - @all(Rho_s))/kin_time - return -end - -@parallel function compute_6!(dPfdτ::Data.Array, Pf::Data.Array, Rho_X_ϕ::Data.Array, Res_Phi::Data.Array, Phi::Data.Array, Res_Pf::Data.Array, Rho_s::Data.Array, X_s::Data.Array, Phi_old::Data.Array, Rho_X_old::Data.Array, ∇V_ρ_X::Data.Array, dampPf::Data.Number, dt_Pf::Data.Number, dtp::Data.Number) - @all(dPfdτ) = dampPf*@all(dPfdτ) + @all(Res_Pf) - @inn(Pf) = @inn(Pf) + dt_Pf*@all(dPfdτ) - @all(Rho_X_ϕ) = (1.0-@all(Phi))*@all(Rho_s)*@all(X_s) - @all(Res_Phi) = ( @all(Rho_X_ϕ) - (1.0-@all(Phi_old))*@all(Rho_X_old) )/dtp + @all(∇V_ρ_X) # CONSERVATION OF MASS OF MgO EQUATION -# @all(Phi) = @all(Phi) + dtp*@all(Res_Phi) - @inn(Phi) = @inn(Phi) + dtp*@inn(Res_Phi) - return -end - -macro limit_min(A,min_val) esc(:( max($A[$ix,$iy],$min_val) )) end -@parallel function compute_7!(Eta::Data.Array, Lam::Data.Array, ∇V::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array, Ptot::Data.Array, Vx::Data.Array, Vy::Data.Array, Phi::Data.Array, Ptot_old::Data.Array, Pf::Data.Array, Pf_old::Data.Array, - dtPt::Data.Number, η_m::Data.Number, ϕ_exp::Data.Number, ϕ_ini::Data.Number, λ_η::Data.Number, dtp::Data.Number, K_d::Data.Number, η_min::Data.Number, α::Data.Number, dx::Data.Number, dy::Data.Number, n_v::Data.Number) - @all(Eta) = η_m*exp(-ϕ_exp*( @all(Phi)/ϕ_ini - @all(Phi)/@all(Phi) )) -# @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) -# @all(Eta) = η_m*(ϕ_ini/@all(Phi))^n_v - @all(Eta) = @limit_min(Eta,η_min) - @all(Lam) = λ_η*@all(Eta) - @all(∇V) = @d_xa(Vx)/dx + @d_ya(Vy)/dy - @all(ε_xx) = @d_xa(Vx)/dx - 1.0/3.0*@all(∇V) - @all(ε_yy) = @d_ya(Vy)/dy - 1.0/3.0*@all(∇V) - @all(ε_xy) = 0.5*(@d_yi(Vx)/dy + @d_xi(Vy)/dx) - @all(Ptot) = @all(Ptot) - dtPt*( @all(Ptot) - (@all(Ptot_old)-dtp*( K_d*@all(∇V) - α*( (@all(Pf) - @all(Pf_old))/dtp ) - K_d*@all(Pf) / ((1.0-@all(Phi))*@all(Lam)) )) / ( 1.0 + dtp*K_d/((1.0-@all(Phi))*@all(Lam)) ) ) - return -end - -@parallel function compute_8!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, Eta::Data.Array, ε_xx::Data.Array, ε_yy::Data.Array, ε_xy::Data.Array) - @all(τ_xx) = 2.0*@all(Eta) * @all(ε_xx) - @all(τ_yy) = 2.0*@all(Eta) * @all(ε_yy) - @all(τ_xy) = 2.0*@av(Eta) * @all(ε_xy) - return -end - -@parallel function compute_plast_1!(τII::Data.Array, LamP::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, σ_y::Data.Number) - @all(τII) = sqrt( 0.5*(@all(τ_xx)*@all(τ_xx) + @all(τ_yy)*@all(τ_yy)) + @all(τ_xyn)*@all(τ_xyn) ) - @all(LamP) = max(0.0, (1.0 - σ_y/@all(τII))) - return -end - -@parallel function compute_plast_2!(τ_xx::Data.Array, τ_yy::Data.Array, τ_xy::Data.Array, LamP::Data.Array) - @all(τ_xx) = (1.0-@all(LamP))*@all(τ_xx) - @all(τ_yy) = (1.0-@all(LamP))*@all(τ_yy) - @all(τ_xy) = (1.0- @av(LamP))*@all(τ_xy) - return -end - -@parallel function compute_plast_3!(τII::Data.Array, LamP2::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, LamP::Data.Array) - @all(τII) = sqrt( 0.5*(@all(τ_xx)*@all(τ_xx) + @all(τ_yy)*@all(τ_yy)) + @all(τ_xyn)*@all(τ_xyn) ) - @all(LamP2) = @all(LamP2) + @all(LamP) - return -end - -@parallel function compute_9!(Res_Vx::Data.Array, Res_Vy::Data.Array, τ_xx::Data.Array, τ_yy::Data.Array, τ_xyn::Data.Array, Ptot::Data.Array, τ_xy::Data.Array, dx::Data.Number, dy::Data.Number) - @all(Res_Vx) = -@d_xi(Ptot)/dx + @d_xi(τ_xx)/dx + @d_ya(τ_xy)/dy # HORIZONTAL FORCE BALANCE - @all(Res_Vy) = -@d_yi(Ptot)/dy + @d_yi(τ_yy)/dy + @d_xa(τ_xy)/dx # VERTICAL FORCE BALANCE - return -end - -@parallel function compute_10!(dVxdτ::Data.Array, dVydτ::Data.Array, Vx::Data.Array, Vy::Data.Array, Res_Vx::Data.Array, Res_Vy::Data.Array, dampV::Data.Number, dt_Stokes::Data.Number) - @all(dVxdτ) = @all(dVxdτ)*dampV + @all(Res_Vx) # dVxdτ .= dVxdτ.*(1-Vdmp/nx) .+ Rx - @all(dVydτ) = @all(dVydτ)*dampV + @all(Res_Vy) - @inn(Vx) = @inn(Vx) + dt_Stokes*@all(dVxdτ) # Pseudo-transient form of horizontal force balance - @inn(Vy) = @inn(Vy) + dt_Stokes*@all(dVydτ) # Pseudo-transient form of vertical force balance - return -end - -@parallel function postprocess!(dRhoT_dt::Data.Array, dRhosPhi_dt::Data.Array, dRhofPhi_dt::Data.Array, dRhoXPhi_dt::Data.Array, dPf_dt::Data.Array, dPt_dt::Data.Array, dPhi_dt::Data.Array, dRhos_dt::Data.Array, Rho_s::Data.Array, Rho_f::Data.Array, X_s::Data.Array, Phi::Data.Array, Rho_s_old::Data.Array, Rho_f_old::Data.Array, Rho_X_old::Data.Array, Phi_old::Data.Array, Rho_t::Data.Array, Rho_t_old::Data.Array, Pf::Data.Array, Pf_old::Data.Array, Ptot::Data.Array, Ptot_old::Data.Array, dtp::Data.Number) - @all(dRhoT_dt) = (@all(Rho_t) - @all(Rho_t_old)) /dtp - @all(dRhosPhi_dt) = (@all(Rho_s)*(1.0-@all(Phi)) - @all(Rho_s_old)*(1.0-@all(Phi_old))) /dtp - @all(dRhofPhi_dt) = (@all(Rho_f)*@all(Phi) - @all(Rho_f_old)*@all(Phi_old)) /dtp - @all(dRhoXPhi_dt) = (@all(Rho_s)*@all(X_s)*(1-@all(Phi)) - @all(Rho_X_old)*(1-@all(Phi_old))) /dtp - @all(dPf_dt) = (@all(Pf) - @all(Pf_old)) /dtp - @all(dPt_dt) = (@all(Ptot) - @all(Ptot_old)) /dtp - @all(dPhi_dt) = (@all(Phi) - @all(Phi_old)) /dtp - @all(dRhos_dt) = (@all(Rho_s) - @all(Rho_s_old)) /dtp - return -end - -################################################## -@views function PT_HMC(; nx=500, ny=500, do_save=false, run_test=false) - runid = "dehy" - nsave = 100 - do_Phi_rnd = false - do_Pf_pert = false - do_restart = false - irestart = 1200 # Step to restart from if do_reatart - # read in mat file - vars = matread( string(@__DIR__, "/LOOK_UP_atg.mat") ) - Rho_s_LU = get(vars, "Rho_s" ,1) - Rho_f_LU = get(vars, "Rho_f" ,1) - X_LU = get(vars, "X_s_vec",1) - P_LU = get(vars, "P_vec" ,1)*1e8 - # Independent parameters - rad = 1.0 # Radius of initial P-perturbation [m] - η_m = 1.0 # Viscosity scale [Pa s] - P_ini = 1.0 # Initial ambient pressure [Pa] - ρ_0 = 3000.0 # Density scale [kg/m^3] - # Nondimensional parameters - elli_fac = 2.0 # Use 1 for circle - angle = 45.0 # Counterclockwise angle of long axis with respect to vertical direction - ϕ_ini = 2e-2 # Initial porosity - ϕ_amp = 12 # Amplitude of porosity perturbation - ϕ_exp = 1/2.5 # Parameter controlling viscosity-porosity relation - lc_rad2 = 40.0 # OMEGA_1 = ( lc_rad2*ϕ_ini^3 * (2+4/3) )^0.5 - Da = 0.0784*1.5 # OMEGA_2 - lx_rad = 40.0 # OMEGA_3 - λ_η = 2.0 # OMEGA_4 - Om5 = 0.0025 # OMEGA_5 - n_v = 3.0 # Exponent in viscosity - porosity relation - n_p = 3.0 # Exponent in permeablity - porosity relation (Kozeny-Carman) - ly_lx = 1.0 # Model height divided by model width - Pini_Pappl = P_ini/12.75e8# Dimensionless ratio of abritrary model-P_ini to P_ini in applicable Pa-values; necessary for Look-up table - σ_y = 250.0*Pini_Pappl*1e6 # yield stress - P_pert = 60*Pini_Pappl*1e6 - # Dependant parameters - K_s = 1e11*Pini_Pappl # Solid elastic bulk modulus - k_ηf = lc_rad2*rad^2/η_m # Permeability divided by fluid viscosity; [m^2/(Pa s)] - lx = lx_rad*rad # Model width [m] - ly = ly_lx*lx # Model height [m] - P_LU = P_LU*Pini_Pappl # Transform look-up table stress to PT stress scale - K_d = K_s/2.0 # Elastic bulk modulus, drained - α = 1.0 - K_d/K_s # Biot-Willis coefficient - ε_bg = Da * P_ini / η_m # Shearing rate - # Characteristic time scales - τ_f_dif_ϕ = rad^2 / (k_ηf*ϕ_ini^n_p*K_s) - τ_relax = η_m / K_s - τ_kinetic = Om5 * τ_f_dif_ϕ - # Numerics - dtp = 4e-6 * τ_f_dif_ϕ # Time step physical - nt = 4e3+1 - tol = 1e-6 # Tolerance for pseudo-transient iterations - cfl = 1/16.1 # CFL parameter for PT-Stokes solution - damping = 1 - Re_Pf = 170π - Re_V = 170π - r = 1.5 - time_tot = nt*dtp # Total time of simulation - itmax = 5e6 - nout = 1e3 - nsm = 40 # number of porosity smoothing steps - explicit diffusion - η_min = 1e-8 - kin_time = 1e1*τ_f_dif_ϕ - kin_time_final = τ_kinetic - Kin_time_vec = [1e25*τ_f_dif_ϕ; range(kin_time, stop=kin_time_final, length=26); kin_time_final*ones(Int(round(time_tot/dtp)))] - # Configuration of grid, matrices and numerical parameters - dx, dy = lx/(nx-1), ly/(ny-1) # Grid spacing - xc, yc = -lx/2:dx:lx/2, -ly/2:dy:ly/2 # Coordinate vector - xv, yv = -lx/2-dx/2:dx:lx/2+dx/2, -ly/2-dy/2:dy:ly/2+dy/2 # Horizontal vector for Vx which is one more than basic grid - (Xc2, Yc2) = ([x for x=xc, y=yc], [y for x=xc, y=yc]) - (Xc2vx, Yc2vx) = ([x for x=xv, y=yc], [y for x=xv, y=yc]) - (Xc2vy, Yc2vy) = ([x for x=xc, y=yv], [y for x=xc, y=yv]) - rad_a = rad - rad_b = rad_a*elli_fac - X_rot = Xc2*cosd(angle)+Yc2*sind(angle) - Y_rot = -Xc2*sind(angle)+Yc2*cosd(angle) - X_elli = rad_a.*cos.(0:0.01:2*pi).*cosd(angle).+rad_b.*sin.(0:0.01:2*pi).*sind(angle) - Y_elli = -rad_a.*cos.(0:0.01:2*pi).*sind(angle).+rad_b.*sin.(0:0.01:2*pi).*cosd(angle) - XY_elli = (-X_elli, Y_elli) - # Analytical fit of look-up table - p_minA, p_maxA = minimum(P_LU), maximum(P_LU) - rho_s_up = 50.0 - ########################################################################################################### - # Pore pressure perturbation - Pf = P_ini*ones(nx, ny) - Pf_amb = P_ini*ones(nx, ny) - if do_Pf_pert - Pf[sqrt.((X_rot .- 0.0).^2 ./ rad_a.^2 .+ (Y_rot .+ 0.0).^2 ./ rad_b.^2) .< 1.0] .= P_ini - P_pert # Porosity petubation - for smo=1:nsm # Smooting of perturbation - Pf[2:end-1,:] .= Pf[2:end-1,:] .+ 0.4.*(Pf[3:end,:].-2.0.*Pf[2:end-1,:].+Pf[1:end-2,:]) - Pf[:,2:end-1] .= Pf[:,2:end-1] .+ 0.4.*(Pf[:,3:end].-2.0.*Pf[:,2:end-1].+Pf[:,1:end-2]) - end - end - Pf = Data.Array(Pf) - Pf_amb = Data.Array(Pf_amb) - ########################################################################################################### - SlopeA = (Pf.-p_minA)/p_maxA*rho_s_up - rho_s_max = Rho_s_LU[1] - rho_s_minA = minimum(Rho_s_LU) - rho_s_difA = rho_s_max-rho_s_minA - p_reactA = 12.65*1e8*Pini_Pappl - rho_f_maxA = maximum(Rho_f_LU) # Parameters for fluid density - x_max = maximum(X_LU) # Parameters for mass fraction - x_minA = minimum(X_LU) - x_difA = x_max-x_minA - # Density, compressibility and gamma from concentration and pressure from thermodynamic data base - Rho_f = Data.Array( (rho_f_maxA .* log.(Pf .+ 1.0).^(1.0/3.5))/ρ_0 ) - Rho_s = Data.Array( (-tanh.( 6e2*(Pf .-p_reactA) )*(rho_s_difA/2.0 .+ rho_s_up/3.0) .+ (rho_s_difA/2.0 .- rho_s_up/3.0) .+ rho_s_minA .+ SlopeA)/ρ_0 ) - X_s = Data.Array( -tanh.( 6e2*(Pf .-p_reactA) )*x_difA/2.0 .+ x_difA/2.0 .+ x_minA ) - Rho_s_amb = Data.Array( (-tanh.( 6e2*(Pf_amb.-p_reactA) )*(rho_s_difA/2.0 .+ rho_s_up/3.0) .+ (rho_s_difA/2.0 .- rho_s_up/3.0) .+ rho_s_minA .+ SlopeA)/ρ_0 ) - X_s_amb = Data.Array( -tanh.( 6e2*(Pf_amb.-p_reactA) )*x_difA/2.0 .+ x_difA/2.0 .+ x_minA ) - SlopeA = Data.Array( SlopeA ) - # Initialize ALL arrays in Julia - Ptot = @zeros(nx , ny ) # Initial ambient fluid pressure - ∇V = @zeros(nx , ny ) - ∇V_ρ_X = @zeros(nx , ny ) - ∇V_ρ_t = @zeros(nx , ny ) - τ_xx = @zeros(nx , ny ) # Deviatoric stress - τ_yy = @zeros(nx , ny ) # Deviatoric stress - τ_xy = @zeros(nx-1, ny-1) # Deviatoric stress - τ_xyn = @zeros(nx , ny ) - Res_Vx = @zeros(nx-1, ny-2) - Res_Vy = @zeros(nx-2, ny-1) - dVxdτ = @zeros(nx-1, ny-2) # damping - dVydτ = @zeros(nx-2, ny-1) # damping - Rho_s_eq = @zeros(nx , ny ) - X_s_eq = @zeros(nx , ny ) - Rho_s_old = @zeros(nx , ny ) - Rho_f_old = @zeros(nx , ny ) - X_s_old = @zeros(nx , ny ) - Rho_X_old = @zeros(nx , ny ) - Phi_old = @zeros(nx , ny ) - Ptot_old = @zeros(nx , ny ) - Pf_old = @zeros(nx , ny ) - Rho_t_old = @zeros(nx , ny ) - Rho_t = @zeros(nx , ny ) - para_cx = @zeros(nx-1, ny ) - para_cy = @zeros(nx , ny-1) - q_f_X = @zeros(nx-1, ny ) - q_f_Y = @zeros(nx , ny-1) - ∇q_f = @zeros(nx-2, ny-2) - Res_Pf = @zeros(nx-2, ny-2) - dPfdτ = @zeros(nx-2, ny-2) # damping - Rho_X_ϕ = @zeros(nx , ny ) - Res_Phi = @zeros(nx , ny ) - ε_xx = @zeros(nx , ny ) - ε_yy = @zeros(nx , ny ) - ε_xy = @zeros(nx-1, ny-1) - τII = @zeros(nx , ny ) - LamP = @zeros(nx , ny ) - LamP2 = @zeros(nx , ny ) - # Arrays for post-processing - dRhoT_dt = @zeros(nx , ny ) - dRhosPhi_dt = @zeros(nx , ny ) - dRhofPhi_dt = @zeros(nx , ny ) - dRhoXPhi_dt = @zeros(nx , ny ) - dPf_dt = @zeros(nx , ny ) - dPt_dt = @zeros(nx , ny ) - dPhi_dt = @zeros(nx , ny ) - dRhos_dt = @zeros(nx , ny ) - # TMP arrays for swell2 - TmpX = @zeros(nx+1, ny ) - TmpY = @zeros(nx , ny+1) - TmpS1 = @zeros(nx , ny-1) - # arrays for visu - Vx_f = zeros(nx , ny ) - Vy_f = zeros(nx , ny ) - # init - ########################################################################################################### - # Porosity perturbation - Phi_ini = ϕ_ini*ones(nx, ny) - # Phi_ini[sqrt.((X_rot .- 0.0).^2 ./ rad_a.^2 .+ (Y_rot .+ 0.0).^2 ./ rad_b.^2) .< 1.0] .= ϕ_amp*ϕ_ini # Porosity petubation - # # Phi_ini[sqrt.((X_rot .+ 2.0).^2 ./ rad_a.^2 .+ (Y_rot .- 6.0).^2 ./ rad_b.^2) .< 1.0] .= 2.5*ϕ_ini # Porosity petubation - # for smo=1:nsm # Smooting of perturbation - # Phi_ini[2:end-1,:] .= Phi_ini[2:end-1,:] .+ 0.4.*(Phi_ini[3:end,:].-2.0.*Phi_ini[2:end-1,:].+Phi_ini[1:end-2,:]) - # Phi_ini[:,2:end-1] .= Phi_ini[:,2:end-1] .+ 0.4.*(Phi_ini[:,3:end].-2.0.*Phi_ini[:,2:end-1].+Phi_ini[:,1:end-2]) - # end - Pert = Data.Array((ϕ_amp .* Phi_ini .- Phi_ini) .* exp.(.-(X_rot./rad_a).^2 .- (Y_rot./rad_b).^2)) - Phi_ini = Data.Array(Phi_ini) - Phi = Phi_ini .+ Pert - if do_Pf_pert - Phi_ini = ϕ_ini*ones(nx, ny) - Phi = copy(Phi_ini) - end - if do_Phi_rnd - Phi = @ones(nx, ny) - ϕ_range = (0.02, 0.24) # range - sf = 1.0 # standard deviation - cl = (lx/10.0, ly/10.0) # correlation length - nh = 10000 # inner parameter, number of harmonics - grf2D_expon!(Phi, sf, cl, nh, size(Phi,1), size(Phi,2), dx, dy; do_reset=true) - xb, yb = lx/4, ly/4 # width of the boundary region - xind, yind = Int(ceil(xb/dx)), Int(ceil(yb/dy)) - @parallel smooth_border_x!(Phi, xind) - @parallel smooth_border_y!(Phi, yind) - for _ = 1:15 - Phi[2:end-1,:] .= Phi[2:end-1,:] .+ 0.4.*(Phi[3:end,:].-2.0.*Phi[2:end-1,:].+Phi[1:end-2,:]) - Phi[:,2:end-1] .= Phi[:,2:end-1] .+ 0.4.*(Phi[:,3:end].-2.0.*Phi[:,2:end-1].+Phi[:,1:end-2]) - end - nxyb = 75 - for _ = 1:50 - Phi[2:nxyb,:] .= Phi[2:nxyb,:] .+ 0.4.*(Phi[3:nxyb+1,:].-2.0.*Phi[2:nxyb,:].+Phi[1:nxyb-1,:]) - Phi[:,2:nxyb] .= Phi[:,2:nxyb] .+ 0.4.*(Phi[:,3:nxyb+1].-2.0.*Phi[:,2:nxyb].+Phi[:,1:nxyb-1]) - Phi[end-nxyb:end-1,:] .= Phi[end-nxyb:end-1,:] .+ 0.4.*(Phi[end-nxyb+1:end,:].-2.0.*Phi[end-nxyb:end-1,:].+Phi[end-nxyb-1:end-2,:]) - Phi[:,end-nxyb:end-1] .= Phi[:,end-nxyb:end-1] .+ 0.4.*(Phi[:,end-nxyb+1:end].-2.0.*Phi[:,end-nxyb:end-1].+Phi[:,end-nxyb-1:end-2]) - end - min_ϕ = minimum(Phi) - Phi .= Phi .- min_ϕ - max_ϕ = maximum(Phi) - Phi .= Phi ./ max_ϕ .* (ϕ_range[2] - ϕ_range[1]) .+ ϕ_range[1] - end - # Porosity perturbation - Eta = η_m*@ones(nx, ny) # Shear viscosity, alternative init: # @all(Eta) = η_m*exp(-ϕ_exp*(@all(Phi)-ϕ_ini)) - Lam = λ_η*@ones(nx, ny) # Bulk viscosity, alternative init: # @all(Lam) = λ_η*@all(Eta) - # Vx_ps = ε_bg*Data.Array(Xc2vx) # Pure shear, shortening in x - # Vy_ps = -ε_bg*Data.Array(Yc2vy) # Pure shear, extension in y - Vx = ε_bg*Data.Array(Yc2vx) # Simple shear, shearing in x - Vy = 0.0*Data.Array(Yc2vy) # Simple shear, zero velocity in y - Pf = Data.Array(Pf) - Ptot .= Pf # Initial total pressure - # Parameters for time loop and pseudo-transient iterations - max_dxdy2 = max(dx,dy).^2 - timeP = 0.0 # Initial time - itp = 0 # Integer count for time loop - Time_vec = [] - ρ_i_Pf = cfl*Re_Pf/nx - ρ_i_V = cfl*Re_V /nx - dampPf = damping.*(1.0 .- ρ_i_Pf) - dampV = damping.*(1.0 .- ρ_i_V ) - !run_test && (dirname = "../output_$(runid)_$(nx)x$(ny)"; !ispath(dirname) && mkdir(dirname)) - # time loop - while timeP < time_tot && itp < nt - if do_restart - restart_file = joinpath(@__DIR__, dirname, "dehy_") * @sprintf("%04d", irestart) * ".mat" - vars_restart = matread(restart_file) - Ptot .= Data.Array( get(vars_restart, "Ptot", 1) ) - Pf .= Data.Array( get(vars_restart, "Pf", 1) ) - X_s .= Data.Array( get(vars_restart, "X_s", 1) ) - Phi .= Data.Array( get(vars_restart, "Phi", 1) ) - Rho_s .= Data.Array( get(vars_restart, "Rho_s", 1) ) - Rho_f .= Data.Array( get(vars_restart, "Rho_f", 1) ) - Vx .= Data.Array( get(vars_restart, "Vx", 1) ) - Vy .= Data.Array( get(vars_restart, "Vy", 1) ) - Vx_f .= Data.Array( get(vars_restart, "Vx_f", 1) ) - Vy_f .= Data.Array( get(vars_restart, "Vy_f", 1) ) - LamP2 .= Data.Array( get(vars_restart, "LamP2", 1) ) - Rho_s_old .= Data.Array( get(vars_restart, "Rho_s_old", 1) ) - Rho_f_old .= Data.Array( get(vars_restart, "Rho_f_old", 1) ) - X_s_old .= Data.Array( get(vars_restart, "X_s_old", 1) ) - Rho_X_old .= Data.Array( get(vars_restart, "Rho_X_old", 1) ) - Phi_old .= Data.Array( get(vars_restart, "Phi_old", 1) ) - Ptot_old .= Data.Array( get(vars_restart, "Ptot_old", 1) ) - Pf_old .= Data.Array( get(vars_restart, "Pf_old", 1) ) - Rho_t_old .= Data.Array( get(vars_restart, "Rho_t_old", 1) ) - Time_vec = get(vars_restart, "Time_vec", 1) - itp = get(vars_restart, "itp", 1) - timeP = get(vars_restart, "timeP", 1) - it_tstep = get(vars_restart, "it_tstep", 1) - do_restart = false - end - err_M = 2*tol; itp += 1 - timeP = timeP+dtp; push!(Time_vec, timeP) - if do_Pf_pert - if itp==1 - # Necessary only of Pf-perturbation is applied - @parallel compute_1_ini!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η, n_v, Rho_s_amb, X_s_amb) - end - if itp>1 - @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η, n_v, Rho_s_amb, X_s_amb) - end - else - @parallel compute_1!(Rho_s_old, Rho_f_old, X_s_old, Rho_X_old, Phi_old, Ptot_old, Pf_old, Rho_t_old, Eta, Lam, Rho_s, Rho_f, X_s, Phi, Ptot, Pf, η_m, ϕ_exp, ϕ_ini, λ_η, n_v, Rho_s_amb, X_s_amb) - end - kin_time = Kin_time_vec[itp] - # PT loop - it_tstep=0; err_evo1=[]; err_evo2=[]; err_pl=[] - dt_Stokes, dt_Pf = cfl*max_dxdy2, cfl*max_dxdy2 - dt_Pt = maximum(Eta)/(lx/dx) - while err_M>tol && it_tstep 1) @parallel compute_5!(X_s, Rho_s, X_s_old, X_s_eq, Rho_s_old, Rho_s_eq, dtp, kin_time) end - # Porosity evolution - @parallel compute_6!(dPfdτ, Pf, Rho_X_ϕ, Res_Phi, Phi, Res_Pf, Rho_s, X_s, Phi_old, Rho_X_old, ∇V_ρ_X, dampPf, dt_Pf, dtp) - @parallel (1:size(Pf,1)) bc_y!(Pf) - @parallel (1:size(Pf,2)) bc_x!(Pf) - # Stokes - @parallel swell2_x!(TmpX, Rho_X_ϕ) - @parallel swell2_y!(TmpY, Rho_X_ϕ) - @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) - @parallel laplace!(∇V_ρ_X, TmpX, TmpY, dx, dy) - @parallel swell2_x!(TmpX, Rho_t) - @parallel swell2_y!(TmpY, Rho_t) - @parallel cum_mult2!(TmpX, TmpY, Vx, Vy) - @parallel laplace!(∇V_ρ_t, TmpX, TmpY, dx, dy) - @parallel compute_7!(Eta, Lam, ∇V, ε_xx, ε_yy, ε_xy, Ptot, Vx, Vy, Phi, Ptot_old, Pf, Pf_old, dt_Pt, η_m, ϕ_exp, ϕ_ini, λ_η, dtp, K_d, η_min, α, dx, dy, n_v) - @parallel compute_8!(τ_xx, τ_yy, τ_xy, Eta, ε_xx, ε_yy, ε_xy) - @parallel swell2_x!(TmpS1, τ_xy) - @parallel swell2_y!(τ_xyn, TmpS1) - # Plastic starts - @parallel compute_plast_1!(τII, LamP, τ_xx, τ_yy, τ_xyn, σ_y) - @parallel compute_plast_2!(τ_xx, τ_yy, τ_xy, LamP) - @parallel swell2_x!(TmpS1, τ_xy) - @parallel swell2_y!(τ_xyn, TmpS1) - @parallel compute_plast_3!(τII, LamP2, τ_xx, τ_yy, τ_xyn, LamP) - # Plastic ends - @parallel compute_9!(Res_Vx, Res_Vy, τ_xx, τ_yy, τ_xyn, Ptot, τ_xy, dx, dy) - @parallel compute_10!(dVxdτ, dVydτ, Vx, Vy, Res_Vx, Res_Vy, dampV, dt_Stokes) - if it_tstep % nout == 0 && it_tstep > 250 - err_R_Mx = maximum(abs.(Res_Vx)) # Error horizontal force balance - err_R_My = maximum(abs.(Res_Vy)) # Error vertical force balance - err_R_Pf = maximum(abs.(Res_Pf[2:end-1,2:end-1])) # Error total mass conservation - err_R_Phi= maximum(abs.(Res_Phi[2:end-1,2:end-1])) # Error MgO mass conservation - err_M = maximum([err_R_Pf, err_R_Mx, err_R_My, err_R_Phi]) # Error total - if isnan(err_M) error("NoNs - stopping simulation.") end - err_evo1 = push!(err_evo1, it_tstep); err_evo2 = push!(err_evo2, err_M) - err_pl = push!(err_pl, maximum(τII)/σ_y - 1.0) - @printf("iter = %d, error = %1.3e \n", it_tstep, err_M) - end - (run_test && it_tstep>=1e3) && break - end # end PT loop - println("it = $(itp), time = $(round(timeP, sigdigits=3)) (time_tot = $(round(time_tot, sigdigits=3)))") - if do_save && (itp % nsave == 0 || itp==1) - @parallel postprocess!(dRhoT_dt, dRhosPhi_dt, dRhofPhi_dt, dRhoXPhi_dt, dPf_dt, dPt_dt, dPhi_dt, dRhos_dt, Rho_s, Rho_f, X_s, Phi, Rho_s_old, Rho_f_old, Rho_X_old, Phi_old, Rho_t, Rho_t_old, Pf, Pf_old, Ptot, Ptot_old, dtp) - matwrite(joinpath(@__DIR__, dirname, "dehy_") * @sprintf("%04d", itp) * ".mat", - Dict("Ptot"=> Array(Ptot), - "Pf"=> Array(Pf), - "divV"=> Array(∇V), - "X_s"=> Array(X_s), - "Rho_s"=> Array(Rho_s), - "Phi"=> Array(Phi), - "Rho_f"=> Array(Rho_f), - "TauII"=> Array(τII), - "Eta"=> Array(Eta), - "Tauxx"=> Array(τ_xx), - "Tauyy"=> Array(τ_yy), - "Tauxy"=> Array(τ_xy), - "Vx"=> Array(Vx), - "Vy"=> Array(Vy), - "Vx_f"=> Array(Vx_f), - "Vy_f"=> Array(Vy_f), - "Ellipse_x"=> Array(X_elli), - "Ellipse_y"=> Array(Y_elli), - "Time_vec"=> Array(Time_vec), - "LamP2"=> Array(LamP2), - "Rho_s_old"=> Array(Rho_s_old), - "Rho_f_old"=> Array(Rho_f_old), - "X_s_old"=> Array(X_s_old), - "Rho_X_old"=> Array(Rho_X_old), - "Phi_old"=> Array(Phi_old), - "Ptot_old"=> Array(Ptot_old), - "Pf_old"=> Array(Pf_old), - "Rho_t_old"=> Array(Rho_t_old), - "Lam"=> Array(Lam), - "dRhoT_dt"=> Array(dRhoT_dt), - "dRhosPhi_dt"=> Array(dRhosPhi_dt), - "dRhofPhi_dt"=> Array(dRhofPhi_dt), - "dRhoXPhi_dt"=> Array(dRhoXPhi_dt), - "dPf_dt"=> Array(dPf_dt), - "dPt_dt"=> Array(dPt_dt), - "dPhi_dt"=> Array(dPhi_dt), - "dRhos_dt"=> Array(dRhos_dt), - "Res_pf"=> Array(Res_Pf), - "div_qf"=> Array(∇q_f), - "div_rhoTvs"=> Array(∇V_ρ_t), - "div_rhoXvs"=> Array(∇V_ρ_X), - "Ch_ti_fluid_dif_phi"=> τ_f_dif_ϕ, - "Ch_ti_kinetic"=> τ_kinetic, - "Ch_ti_relaxation"=> τ_relax, - "rho_0"=> ρ_0, - "Pini_Pappl"=> Pini_Pappl, - "itp"=> itp, - "timeP"=> timeP, - "it_tstep"=> it_tstep, - "xc"=> Array(xc), "yc"=> Array(yc)); compress = true) - end - (run_test && itp==1) && break - end - return (run_test ? (xc, yc, Pf, Phi) : nothing) -end - -@static if !run_test - PT_HMC(; nx=500, ny=500, do_save=true, run_test) -else - xc, yc, Pf, Phi = PT_HMC(; nx=500, ny=500, do_save=false, run_test) -end \ No newline at end of file diff --git a/scripts_2023/LOOK_UP_atg.mat b/scripts_2023/LOOK_UP_atg.mat deleted file mode 100644 index 721c25d..0000000 Binary files a/scripts_2023/LOOK_UP_atg.mat and /dev/null differ diff --git a/scripts_2023/lapaz.mat b/scripts_2023/lapaz.mat deleted file mode 100644 index 0f021f3..0000000 Binary files a/scripts_2023/lapaz.mat and /dev/null differ diff --git a/scripts_2023/vizme_DeHy.m b/scripts_2023/vizme_DeHy.m deleted file mode 100644 index 741ae43..0000000 --- a/scripts_2023/vizme_DeHy.m +++ /dev/null @@ -1,74 +0,0 @@ -function [ ] = VISU_Julia(); -clear variables, close all, clc -% Colormap lapaz from https://www.fabiocrameri.ch/colourmaps/ -load lapaz.mat; colormap(flipud(lapaz)) -axx = [-1 1 -1 1]*7; -% Change to output directory -cd ../output_dehy_500x500 -FileNum = [1 800 2000 4000]; % Four result files to be loaded -pcount = 0; -for ilo=1:length(FileNum) - pcount = pcount+1; - string_number = num2str(FileNum(ilo),['%',num2str(4),'.',num2str(4),'d']); - file_name = {['DEHY_', string_number,'.mat']}; - load(char(file_name)) - % Scales - rho_0 = rho_0; % Density scale [kg/m^3] - Pini_Pappl = Pini_Pappl; % Stress scale [1/Pa] - t_char = Ch_ti_fluid_dif_phi; % Characteristc time - [X2Dc,Y2Dc ] = ndgrid(xc, yc); % Mesh coordinates - nx = size(X2Dc,1); - step = 16; - Ii = [1:step:nx]; - VX_C = (Vx(1:end-1,:)+Vx(2:end,:))/2; % Solid velocities X - VY_C = (Vy(:,1:end-1)+Vy(:,2:end))/2; % Solid velocities Y - %%% DENSITY %%% - cax = [2550 3000]; % Color axis - if pcount==1 - subplot('position',[0.075 0.7 0.2 0.25]) - elseif pcount==2 - subplot('position',[0.075+0.21 0.7 0.2 0.25]) - elseif pcount==3 - subplot('position',[0.075+0.21*2 0.7 0.2 0.25]) - elseif pcount==4 - subplot('position',[0.075+0.21*3 0.7 0.2 0.25]) - end - hold on - [c,h] = contour(X2Dc,Y2Dc,Pf/Pini_Pappl/1e8,[12.7 12.7],'-k','linewidth',0.5); - [cl,hl]=contour(X2Dc,Y2Dc,Phi,[0.15 0.15],'-r'); - pcolor(X2Dc,Y2Dc,Rho_s*rho_0), shading interp - caxis(cax) - [c,h] = contour(X2Dc,Y2Dc,Pf/Pini_Pappl/1e8,[12.7 12.7],'-k','linewidth',0.5); - [cl,hl]=contour(X2Dc,Y2Dc,Phi,[0.15 0.15],'-r'); - quiver(X2Dc(Ii,Ii),Y2Dc(Ii,Ii),(VX_C(Ii,Ii)),(VY_C(Ii,Ii)),1.5,'color',[1 1 1]*0.3); - axis equal - axis(axx) - if pcount==1 - le = legend('12.7 kbar','0.15'); - set(le,'fontsize',8,'orientation','horizontal') - set(le,'Position',[0.125 0.9225 0.1 0.015]) - ylabel('y / r') - title('A) Solid density') - text(-6.5,-6.5,['Time: ',num2str(timeP/t_char,4)]) - elseif pcount==4 - col=colorbar; - set(col,'position',[0.91 0.7 0.03 0.25]) - text(7,8.25,'[kg/m^3]') - title('D) Solid density') - text(-6.5,-6.5,['Time: ',num2str(timeP/t_char,4)]) - end - if pcount==2 - title('B) Solid density') - text(-6.5,-6.5,['Time: ',num2str(timeP/t_char,4)]) - elseif pcount==3 - title('C) Solid density') - text(-6.5,-6.5,['Time: ',num2str(timeP/t_char,4)]) - end - if pcount>1 - set(gca,'yticklabel',[]) - end - set(gca,'box','on','FontSize',10) - xlabel('x / r') -end -set(gcf,'position',[186.6000 72.2000 892.8000 690.8000]) -cd .. diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..b31ed99 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,9 @@ +[deps] +BSON = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MAT = "23992714-dd62-5051-b70f-ba57cb901cac" +ParallelStencil = "94395366-693c-11ea-3b26-d9b7aac5d958" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +ReferenceTests = "324d217c-45ce-50fc-942e-d289b448e8cf" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" diff --git a/test/reftest-files/test_DeHy.bson b/test/reftest-files/test_DeHy.bson deleted file mode 100644 index b598ff1..0000000 Binary files a/test/reftest-files/test_DeHy.bson and /dev/null differ diff --git a/test/reftest-files/test_PT_HMC_atg.bson b/test/reftest-files/test_PT_HMC_atg.bson deleted file mode 100644 index e870a1e..0000000 Binary files a/test/reftest-files/test_PT_HMC_atg.bson and /dev/null differ diff --git a/test/reftest-files/test_PT_HMC_bru.bson b/test/reftest-files/test_PT_HMC_bru.bson deleted file mode 100644 index 34db642..0000000 Binary files a/test/reftest-files/test_PT_HMC_bru.bson and /dev/null differ diff --git a/test/reftest-files/test_PT_HMC_bru_analytical.bson b/test/reftest-files/test_PT_HMC_bru_analytical.bson deleted file mode 100644 index 98c14bf..0000000 Binary files a/test/reftest-files/test_PT_HMC_bru_analytical.bson and /dev/null differ diff --git a/test/reftest-files/test_dehy.bson b/test/reftest-files/test_dehy.bson new file mode 100644 index 0000000..c6a669e Binary files /dev/null and b/test/reftest-files/test_dehy.bson differ diff --git a/test/runtests.jl b/test/runtests.jl index 65fb689..6d12600 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,5 @@ # NOTE: This file contains many parts that are copied from the file runtests.jl from the Package ParallelStencil.jl. -push!(LOAD_PATH, "../src") - +using Test using PseudoTransientHMC function runtests() @@ -14,7 +13,7 @@ function runtests() for f in testfiles try - run(`$exename -O3 --startup-file=no --check-bounds=no $(joinpath(testdir, f))`) + run(`$exename --startup-file=no $(joinpath(testdir, f))`) catch ex nfail += 1 end diff --git a/test/shared.jl b/test/shared.jl index 7801add..f48a123 100644 --- a/test/shared.jl +++ b/test/shared.jl @@ -1,5 +1,7 @@ -using Test, ReferenceTests, BSON -using ParallelStencil +using Test +using PseudoTransientHMC + +using ReferenceTests, BSON import ParallelStencil: @reset_parallel_stencil ENV["USE_GPU"] = false diff --git a/test/test_2020.jl b/test/test_2020.jl deleted file mode 100644 index 266d1ea..0000000 --- a/test/test_2020.jl +++ /dev/null @@ -1,24 +0,0 @@ -## 2D tests -include("./shared.jl") - -ENV["NX"] = 63 -ENV["NY"] = 63 - -include("../scripts_2020/PT_HMC_bru.jl") -@reset_parallel_stencil() -indsx = Int.(ceil.(LinRange(1, length(xc), 12))) -indsy = Int.(ceil.(LinRange(1, length(yc), 12))) -d2d1 = Dict(:X=> xc[indsx], :Pf=>Pf[indsx,indsy], :Phi=>Phi[indsx,indsy]) - -include("../scripts_2020/PT_HMC_bru_analytical.jl") -@reset_parallel_stencil() -indsx = Int.(ceil.(LinRange(1, length(xc), 12))) -indsy = Int.(ceil.(LinRange(1, length(yc), 12))) -d2d2 = Dict(:X=> xc[indsx], :Pf=>Pf[indsx,indsy], :Phi=>Phi[indsx,indsy]) - -@testset "Reference-tests PT HMC Brucite 2D" begin - @test_reference "reftest-files/test_PT_HMC_bru.bson" d2d1 by=comp - @test_reference "reftest-files/test_PT_HMC_bru_analytical.bson" d2d2 by=comp -end - -@reset_parallel_stencil() diff --git a/test/test_2022.jl b/test/test_2022.jl deleted file mode 100644 index 4980e1b..0000000 --- a/test/test_2022.jl +++ /dev/null @@ -1,17 +0,0 @@ -## 2D tests -include("./shared.jl") - -ENV["NX"] = 159 -ENV["NY"] = 159 - -include("../scripts_2022/PT_HMC_atg.jl") -@reset_parallel_stencil() -indsx = Int.(ceil.(LinRange(1, length(xc), 12))) -indsy = Int.(ceil.(LinRange(1, length(yc), 12))) -d2d1 = Dict(:X=> xc[indsx], :Pf=>Pf[indsx,indsy], :Phi=>Phi[indsx,indsy]) - -@testset "Reference-tests PT HMC Antigorite 2D" begin - @test_reference "reftest-files/test_PT_HMC_atg.bson" d2d1 by=comp -end - -@reset_parallel_stencil() diff --git a/test/test_2023.jl b/test/test_dehy.jl similarity index 63% rename from test/test_2023.jl rename to test/test_dehy.jl index 75bf0ed..481d816 100644 --- a/test/test_2023.jl +++ b/test/test_dehy.jl @@ -1,14 +1,16 @@ ## 2D tests include("./shared.jl") -include("../scripts_2023/DeHy.jl") +include("../scripts/DeHy.jl") + @reset_parallel_stencil() + indsx = Int.(ceil.(LinRange(1, length(xc), 12))) indsy = Int.(ceil.(LinRange(1, length(yc), 12))) d2d1 = Dict(:X=> xc[indsx], :Pf=>Pf[indsx,indsy], :Phi=>Phi[indsx,indsy]) -@testset "Reference-tests PT HMC Antigorite 2D" begin - @test_reference "reftest-files/test_DeHy.bson" d2d1 by=comp +@testset "Reference-tests PT HMC DeHy 2D" begin + @test_reference "reftest-files/test_dehy.bson" d2d1 by=comp end @reset_parallel_stencil()