Subduction Zone Setup

Subduction Zone Setup#

Author: Cian Wilson

Implementation#

Our implementation will follow a similar workflow to that seen repeatedly in the background examples section.

  1. we will describe the subduction zone geometry and tesselate it intro non-overlapping triangles to create a mesh

  2. we will declare function spaces for the temperature, wedge velocity and pressure, and slab velocity and pressure

  3. using these function space we will declare trial and test functions

  4. we will define Dirichlet boundary conditions at the boundaries as described in the introduction

  5. we will use the crustal heat sources in the right hand side forcing function for the temperature

  6. we will describe discrete weak forms for temperature and each of the coupled velocity-pressure systems that will be used to assemble the matrices (and vectors) to be solved

  7. we will solve the matrix problems using a linear algebra back-end repeatedly in a Picard iteration to find the root of the residuals and return the non-linear solution

The only difference in a subduction zone problem is that each of these steps is more complicated than in the earlier examples. Here we split steps 1-7 up across three notebooks. In the first we implement a function to describe the slab surface using a spline. The remaining details of the geometry are constructed in a function defined in the next notebook. Finally we implement a python class to describe the remaining steps, 2-7, of the problem.

Geometry#

Throughout our implementation, in the following notebooks, we will demonstrate its functionality using the simplified geometry previously laid out and repeated below in Figure 1. However our implementation will be applicable to a broader range of geometries and setups.

Figure 8a of Wilson & van Keken, 2023 Figure 1: Geometry and coefficients for a simplified 2D subduction zone model. All coefficients and parameters are nondimensional. The decoupling point is indicated by the star.

Parameters#

We also recall the default parameters repeated below in Table 1.

Quantity

Symbol

Nominal value

Nondimensional value

Reference temperature scale

\( T_0\)

1 K=1\(^\circ\)C

-

Surface temperature

\(T^*_s\)

273 K=0\(^\circ\)C

\(T_s\)=0

Mantle temperature

\(T^*_m\)

1623 K=1350\(^\circ\)C

\(T_m\)=1350

Surface heat flow note{c}

\(q^*_s\)

\(^\S\) W/m\(^2\)

\(q_s\)\(^\S\)

Reference density

\(\rho_0\)

3300 kg/m\(^3\)

-

Crustal density\(^\text{c}\)

\(\rho^*_c\)

2750 kg/m\(^3\)

\(\rho_c\)=0.833333

Mantle density

\(\rho^*_m\)

3300 kg/m\(^3\)

\(\rho_m\)=1

Reference thermal conductivity

\(k_0\)

3.1 W/(m K)

-

Crustal thermal conductivity\(^\text{c}\)

\(k^*_c\)

2.5 W/(m K)

\(k_c\)=0.8064516

Mantle thermal conductivity

\(k^*_m\)

3.1 W/(m K)

\(k_m\)=1

Volumetric heat production (upper crust)\(^\text{c}\)

\(H^*_1\)

1.3 \(\mu\)W/m\(^3\)

\(H_1\)=0.419354

Volumetric heat production (lower crust)\(^\text{c}\)

\(H_2^*\)

0.27 \(\mu\)W/m\(^3\)

\(H_2\)=0.087097

Age of overriding crust\(^\text{o}\)

\(A_c^*\)

\(^\S\) Myr

\(A_c\)\(^\S\)

Age of subduction\(^\text{t}\)

\(A_s^*\)

\(^\S\) Myr

\(A_s\)\(^\S\)

Age of subducting slab

\(A^*\)

\(^\S\) Myr

\(A\)\(^\S\)

Reference length scale

\(h_0\)

1 km

-

Depth of base of upper crust\(^\text{c}\)

\(z_1^*\)

15 km

\(z_1\)=15

Depth of base of lower crust (Moho)

\(z_2^*\)

\(^\S\) km

\(z_2\)\(^\S\)

Trench depth

\(z_\text{trench}^*\)

\(^\S\) km

\(z_\text{trench}\)\(^\S\)

Position of the coast line

\(x_\text{coast}^*\)

\(^\S\) km

\(x_\text{coast}\)\(^\S\)

Wedge inflow/outflow transition depth

\(z_\text{io}^*\)

\(^\S\) km

\(z_\text{io}\)\(^\S\)

Depth of domain

\(D^*\)

\(^\S\) km

\(D\)\(^\S\)

Width of domain

\(L^*\)

\(^\S\) km

\(L\)\(^\S\)

Depth of change from decoupling to coupling

\(d_c^*\)

80 km

\(d_c\)=80

Reference heat capacity

\({c_p}_0\)

1250 J/(kg K)

-

Reference thermal diffusivity

\(\kappa_0\)

0.7515\(\times\)10\(^{\textrm{-6}}\) m\(^2\)/s

-

Activation energy

\(E\)

540 kJ/mol

-

Powerlaw exponent

\(n\)

3.5

-

Pre-exponential constant

\(A^*_\eta\)

28968.6 Pa s\(^{1/n}\)

-

Reference viscosity scale

\(\eta_0\)

10\(^{\textrm{21}}\) Pa s

-

Viscosity cap

\(\eta^*_\text{max}\)

10\(^{\textrm{25}}\) Pa s

-

Gas constant

\(R^*\)

8.3145 J/(mol K)

-

Derived velocity scale

\({v}_0\)

23.716014 mm/yr

-

Convergence velocity

\(V_s^*\)

\(^\S\) mm/yr

\(V_s\)\(^\S\)

\(^\text{c}\)

ocean-continent subduction only

\(^\text{o}\)

ocean-ocean subduction only

\(^\text{t}\)

time-dependent simulations only

\(^\S\)

varies between models

Table 1: Nomenclature and reference values

Most of these are available for us to use through a file in ../data/default_params.json

import os
basedir = ''
if "__file__" in globals(): basedir = os.path.dirname(__file__)
params_filename = os.path.join(basedir, os.pardir, "data", "default_params.json")

Loading this file

import json
with open(params_filename, "r") as fp:
    default_params = json.load(fp)

This contains default parameters required to define the geometry. Keys ending in _sid and _rid are surface and region IDs respectively that we use to identify boundaries and regions of the mesh (these are unlikely to need to be changed). *_res_fact are resolution factors scaled by a factor to set the resolution at various points in the mesh. Finally, those ending in _depth are depths (in km) of various important points along the slab surface or boundaries (as defined in Table 1).

from mpi4py import MPI
if __name__ == "__main__":
    if MPI.COMM_WORLD.rank == 0:
        print("{:<35} {:<10}".format('Key','Value'))
        print("-"*45)
        for k, v in default_params.items():
            print("{:<35} {:<10}".format(k, v))
Key                                 Value     
---------------------------------------------
slab_sid                            1         
slab_side_sid                       2         
wedge_side_sid                      3         
upper_wedge_side_sid                4         
lc_side_sid                         5         
uc_side_sid                         6         
slab_base_sid                       7         
wedge_base_sid                      8         
lc_base_sid                         9         
uc_base_sid                         10        
coast_sid                           11        
top_sid                             12        
fault_sid                           13        
slab_diag_sid                       14        
slab_rid                            1         
wedge_rid                           2         
lc_rid                              3         
uc_rid                              4         
wedge_diag_rid                      5         
slab_det_depth                      100.0     
partial_coupling_depth              80.0      
full_coupling_depth                 82.5      
slab_diag1_depth                    70.0      
slab_diag2_depth                    120.0     
partial_coupling_depth_res_fact     1.0       
full_coupling_depth_res_fact        1.0       
io_depth_res_fact                   4.0       
coast_res_fact                      1.0       
lc_side_res_fact                    2.0       
lc_slab_res_fact                    1.0       
slab_side_base_res_fact             8.0       
uc_side_res_fact                    2.0       
uc_slab_res_fact                    1.0       
wedge_side_top_res_fact             4.0       
wedge_side_base_res_fact            4.0       
slab_diag1_res_fact                 1.0       
slab_diag2_res_fact                 1.0       

We will additionally use parameters from the benchmark proposed in Wilson & van Keken, PEPS, 2023 as defined in Table 2 below.

case

type

\(\eta\)

\(q_s^*\)

\(A^*\)

\(z_2\)

\(z_\text{io}\)

\(z_\text{trench}\)

\(x_\text{coast}\)

\(D\)

\(L\)

\(V_s^*\)

(W/m\(^2\))

(Myr)

(mm/yr)

1

continental

1

0.065

100

40

139

0

0

200

400

100

2

continental

\(\eta_\text{disl}\)

0.065

100

40

154

0

0

200

400

100

Table 2: Benchmark parameter values

Since these benchmark parameters are so few we will simply enter them as needed. For the global suite all parameters marked as varying between models in Table 1 will change between cases. An additional database of these parameters is provided in ../data/all_sz.json, which we also load here

allsz_filename = os.path.join(basedir, os.pardir, "data", "all_sz.json")
with open(allsz_filename, "r") as fp:
    allsz_params = json.load(fp)

The allsz_params dictionary contains parameters for all 56 subduction zones organized by name.

if __name__ == "__main__":
    if MPI.COMM_WORLD.rank == 0:
        print("{}".format('Name'))
        print("-"*30)
        for k in allsz_params.keys():
            print("{}".format(k,))
Name
------------------------------
01_Alaska_Peninsula
02_Alaska
03_British_Columbia
04_Cascadia
05_Mexico
06_GuatElSal
07_Nicaragua
08_Costa_Rica
09_Colombia_Ecuador
10_N_Peru_Gap
11_C_Peru_Gap
12_Peru
13_N_Chile
14_NC_Chile
15_C_Chile_Gap
16_C_Chile
17_SC_Chile
18_S_Chile
19_N_Antilles
20_S_Antilles
21_Scotia
22_Aegean
23_N_Sumatra
24_C_Sumatra
25_S_Sumatra
26_Sunda_Strait
27_Java
28_Bali_Lombok
29_W_Banda_Sea
30_E_Banda_Sea
31_New_Britain
32_Solomon
33_N_Vanuatu
34_S_Vanuatu
35_Tonga
36_Kermadec
37_New_Zealand
38_S_Philippines
39_N_Philippines
40_S_Marianas
41_N_Marianas
42_Bonin
43_Izu
44_Kyushu
45_Ryukyu
46_Nankai
47_C_Honshu
48_N_Honshu
49_Hokkaido
50_S_Kurile
51_N_Kurile
52_Kamchatka
53_W_Aleutians
54_C_Aleutians
55_E_Aleutians
56_Calabria

Taking two examples (one continental-oceanic, “01_Alaska_Peninsula”, and one oceanic-oceanic, “19_N_Antilles”) we can examine the contents of allsz_params.

if __name__ == "__main__":
    names = ['01_Alaska_Peninsula', '19_N_Antilles']
    if MPI.COMM_WORLD.rank == 0:
        for name in names:
            print("{}:".format(name))
            print("{:<35} {:<10}".format('Key','Value'))
            print("-"*100)
            for k, v in allsz_params[name].items():
                if v is not None: print("{:<35} {}".format(k, v))
            print("="*100)
01_Alaska_Peninsula:
Key                                 Value     
----------------------------------------------------------------------------------------------------
coast_distance                      260
extra_width                         20
lc_depth                            35
io_depth                            185
uc_depth                            15
dirname                             01_Alaska_Peninsula
As                                  40.0
qs                                  0.065
A                                   52.2
sztype                              continental
Vs                                  59.0
z0                                  0.8
z15                                 0.4
xs                                  [0, 68.2, 154.2, 235.0, 248.0, 251.0, 270.0, 358.0, 392.0]
ys                                  [-6, -15.0, -35.0, -70.0, -80.0, -82.5, -100.0, -200.0, -240.0]
====================================================================================================
19_N_Antilles:
Key                                 Value     
----------------------------------------------------------------------------------------------------
coast_distance                      185
extra_width                         19
lc_depth                            30
io_depth                            172
dirname                             19_N_Antilles
As                                  40.0
Ac                                  90.0
A                                   85
sztype                              oceanic
Vs                                  17.6
z0                                  0.5
z15                                 0.25
xs                                  [0, 50.0, 102.2, 166.0, 176.5, 179.0, 195.0, 271.0, 301.0]
ys                                  [-6, -15.0, -30.0, -70.0, -80.0, -82.5, -100.0, -200.0, -240.0]
====================================================================================================

Finish up#

Convert this notebook to a python script (making sure to save first) so that we can access it in subsequent notebooks.

if __name__ == "__main__" and "__file__" not in globals():
    from ipylab import JupyterFrontEnd
    app = JupyterFrontEnd()
    app.commands.execute('docmanager:save')
    !jupyter nbconvert --NbConvertApp.export_format=script --ClearOutputPreprocessor.enabled=True sz_base.ipynb
[NbConvertApp] Converting notebook sz_base.ipynb to script
[NbConvertApp] Writing 11776 bytes to sz_base.py