Variables, equations and forcing terms

This demo notebook summarizes the variables, equations and forcings that can be used in PlesioGeostroPy.

It is assumed that readers are already familiar with the collection interface (see Demo_Collections).

import os, sys
root_dir = "."

# The following 2 lines are a hack to import from parent directory
# If the notebook is run in the root directory, comment out these 2 lines
sys.path.append(os.path.dirname(os.getcwd()))
root_dir = ".."

from pg_utils.pg_model import core, base
from sympy import *

Core variables

The core variables that are concerned in the model are constructed in pg_model.core module. These first include the coordinates \(s\), \(\phi\), \(z\); Cartesian coordinates \(x\), \(y\); as well as spherical coordinates \(r\), \(\theta\).

print("Cylindrical oordinates:")
display(*[core.cyl[i_comp] for i_comp in range(3)])
Cylindrical oordinates:
\[\displaystyle s\]
\[\displaystyle \phi\]
\[\displaystyle z\]

Next, we have the 3-D vector fields. These include

  • magnetic field: in cylindrical coordinates: B_vec, background field B0_vec; in spherical coordinates B_sph, background field B0_sph;

  • velocity field: in cylindrical coordinates: U_vec, background field U0_vec; in spherical coordinates U_sph, background field U0_sph;

we can take a look at one of these variables.

display(*[core.B_vec[i_comp] for i_comp in range(3)])
\[\displaystyle B_{s}{\left(s,\phi,z,t \right)}\]
\[\displaystyle B_{\phi}{\left(s,\phi,z,t \right)}\]
\[\displaystyle B_{z}{\left(s,\phi,z,t \right)}\]

The variables that represent quantities under PG formulation can be divided into two classes. The first class contains the PG variables; the second class contains the transformed variables. Please refer to formulation PDF for details. Each of these two sets of variables have their own total field, background field and perturbation field:

Type

PG

Transformed

Total

core.pgvar

core.cgvar

Background

core.pgvar_bg

core.cgvar_bg

Perturbation

core.pgvar_ptb

core.cgvar_ptb

Within the collection of all PG fields, we have in all 21 variables.

core.pgvar._field_names
['Psi',
 'Mss',
 'Mpp',
 'Msp',
 'Msz',
 'Mpz',
 'zMss',
 'zMpp',
 'zMsp',
 'Bs_e',
 'Bp_e',
 'Bz_e',
 'dBs_dz_e',
 'dBp_dz_e',
 'Br_b',
 'Bs_p',
 'Bp_p',
 'Bz_p',
 'Bs_m',
 'Bp_m',
 'Bz_m']

The first is the stream function; the second to the eight are magnetic moments; then we have the fields in the equatorial plane (ones with _e suffix). Finally, we have the boundary terms.

Note that in standard PG, only Br_b = “radial magnetic field at the boundary” is used; however, for many problems such as the eigenvalue problem, we can use Bs_p (s-magnetic field at \(z=+H\)) - Bz_m (z-magnetic field at \(z=-H\)) instead of Br_b. Here is an overview of all available fields:

display(*[field_symb for field_symb in core.pgvar])
\[\displaystyle \Psi{\left(s,\phi,t \right)}\]
\[\displaystyle \overline{M_{ss}}{\left(s,\phi,t \right)}\]
\[\displaystyle \overline{M_{\phi\phi}}{\left(s,\phi,t \right)}\]
\[\displaystyle \overline{M_{s\phi}}{\left(s,\phi,t \right)}\]
\[\displaystyle \widetilde{M_{sz}}{\left(s,\phi,t \right)}\]
\[\displaystyle \widetilde{M_{\phi z}}{\left(s,\phi,t \right)}\]
\[\displaystyle \widetilde{zM_{ss}}{\left(s,\phi,t \right)}\]
\[\displaystyle \widetilde{zM_{\phi\phi}}{\left(s,\phi,t \right)}\]
\[\displaystyle \widetilde{zM_{s\phi}}{\left(s,\phi,t \right)}\]
\[\displaystyle B_{s}^e{\left(s,\phi,t \right)}\]
\[\displaystyle B_{\phi}^e{\left(s,\phi,t \right)}\]
\[\displaystyle B_{z}^e{\left(s,\phi,t \right)}\]
\[\displaystyle B_{s, z}^e{\left(s,\phi,t \right)}\]
\[\displaystyle B_{\phi, z}^e{\left(s,\phi,t \right)}\]
\[\displaystyle B_{r1}{\left(\theta,\phi,t \right)}\]
\[\displaystyle B^{+}_{s}{\left(s,\phi,t \right)}\]
\[\displaystyle B^{+}_{\phi}{\left(s,\phi,t \right)}\]
\[\displaystyle B^{+}_{z}{\left(s,\phi,t \right)}\]
\[\displaystyle B^{-}_{s}{\left(s,\phi,t \right)}\]
\[\displaystyle B^{-}_{\phi}{\left(s,\phi,t \right)}\]
\[\displaystyle B^{-}_{z}{\left(s,\phi,t \right)}\]

The same thing holds for pgvar_bg and pgvar_ptb. The background fields are denoted with an additional \(0\) superscript, and the perturbed fields are denoted with lower-case letters.

display(core.pgvar_bg.Mss, core.pgvar_ptb.Mss)
\[\displaystyle \overline{M_{ss}}^0{\left(s,\phi \right)}\]
\[\displaystyle \overline{m_{ss}}{\left(s,\phi,t \right)}\]

We can also inspect the fields for transformed quantities:

display(core.cgvar.M_1, core.cgvar_bg.M_1, core.cgvar_ptb.M_1)
\[\displaystyle \overline{M_1}{\left(s,\phi,t \right)}\]
\[\displaystyle \overline{M_1}^0{\left(s,\phi,t \right)}\]
\[\displaystyle \overline{m_1}{\left(s,\phi,t \right)}\]

Last but not least, the core module also stores the PG ansatz of the velocity, which can be invoked whenever necessary:

display(*[core.U_pg[i_comp] for i_comp in range(3)])
\[\displaystyle \frac{\frac{\partial}{\partial \phi} \Psi{\left(s,\phi,t \right)}}{s H{\left(s \right)}}\]
\[\displaystyle - \frac{\frac{\partial}{\partial s} \Psi{\left(s,\phi,t \right)}}{H{\left(s \right)}}\]
\[\displaystyle \frac{z \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \Psi{\left(s,\phi,t \right)}}{s H^{2}{\left(s \right)}}\]

Equations

With all the variables defined, we can now introduce the equations.

The 15 original PG equations (see Jackson and Maffei 2020 or Holdenried-Chernoff 2021) have been typed in manually in the equations module. There these equations undergo two operations.

  • First, they are converted to their counterparts in transformed variables using core.conjugate_to_PG and core.PG_to_conjugate (see Demo_Collections).

  • Then, these equations are linearized around a background field.

The linearization procedure, borrowed from Daria’s Mathematica notebook, is as follows:

  • each fields are expanded as the background state + \(\epsilon\cdot\) a perturbation state.

  • all the terms that are linear in \(\epsilon\) are collected to yields the linearized form.

The fields in equations module are summarized as follows

Type

PG

Transformed

Total

equations.eqs_pg

equations.eqs_cg

Linearized

equations.eqs_pg_lin

equations.eqs_cg_lin

These equations are similarly constructed as base.CollectionPG or base.CollectionConjugate objects.

Since these equations are constructed when the module is imported, the first import of equations is slow. Loading the equations now may take 20-30s (tested on my laptop, AMD R5-4500U). The reason is that it takes a while to compile the equations, as they are not all written out in explicit forms in the code. In linearization especially, the program needs to simplify the expressions to a form where the perturbation \(\epsilon\) is taken out of all brackets. Another problem is that so far, compilation and derivation of equations is done sequentially, not in parallel.

While the compilation of equations is not expected to be the bottleneck of the program in the end, it would still be desirable if it can be loaded faster. A method is to compute the equations and store them in a string that can be quickly loaded. This has already been done, and loading the precomputed equations are now the recommended method.

The precomputed equations are stored as follows

Type

PG

Transformed

Total

/out/symbolic/eqs_pg.json

/out/symbolic/eqs_cg.json

Linearized

/out/symbolic/eqs_pg_lin.json

/out/symbolic/eqs_cg_lin.json

These can be loaded using the deserialize methods:

with open(os.path.join(root_dir, 'out/symbolic/eqs_pg.json'), 'r') as fread:
    eqs_pg = base.CollectionPG.load_json(fread, parser=parse_expr)

We can take a look at the vorticity equation

eqs_pg.Psi.doit().expand()
\[\displaystyle \frac{s \frac{\partial^{3}}{\partial t\partial s^{2}} \Psi{\left(s,\phi,t \right)}}{H{\left(s \right)}} - \frac{s \frac{d}{d s} H{\left(s \right)} \frac{\partial^{2}}{\partial t\partial s} \Psi{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}} + \frac{\frac{\partial^{2}}{\partial t\partial s} \Psi{\left(s,\phi,t \right)}}{H{\left(s \right)}} - \frac{\frac{d}{d s} H{\left(s \right)} \frac{\partial^{3}}{\partial t\partial \phi^{2}} \Psi{\left(s,\phi,t \right)}}{2 H^{2}{\left(s \right)}} + \frac{\frac{\partial^{3}}{\partial t\partial \phi^{2}} \Psi{\left(s,\phi,t \right)}}{s H{\left(s \right)}} = \frac{s f_{\phi}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{s \frac{\partial}{\partial s} \overline{f_\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\overline{f_\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \widetilde{f_z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\frac{\partial}{\partial \phi} \overline{f_s}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{2 \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \Psi{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}}\]

We can similarly load the vorticity equation for transformed variables

with open(os.path.join(root_dir, 'out/symbolic/eqs_cg.json'), 'r') as fread:
    eqs_cg = base.CollectionConjugate.load_json(fread, parser=parse_expr)

eqs_cg.Psi
\[\displaystyle \frac{s \frac{\partial^{3}}{\partial t\partial s^{2}} \Psi{\left(s,\phi,t \right)}}{H{\left(s \right)}} - \frac{s \frac{d}{d s} H{\left(s \right)} \frac{\partial^{2}}{\partial t\partial s} \Psi{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}} + \frac{\frac{\partial^{2}}{\partial t\partial s} \Psi{\left(s,\phi,t \right)}}{H{\left(s \right)}} - \frac{\frac{d}{d s} H{\left(s \right)} \frac{\partial^{3}}{\partial t\partial \phi^{2}} \Psi{\left(s,\phi,t \right)}}{2 H^{2}{\left(s \right)}} + \frac{\frac{\partial^{3}}{\partial t\partial \phi^{2}} \Psi{\left(s,\phi,t \right)}}{s H{\left(s \right)}} = \frac{s f_{\phi}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{s \frac{\partial}{\partial s} \overline{f_\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\overline{f_\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \widetilde{f_z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\frac{\partial}{\partial \phi} \overline{f_s}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{2 \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \Psi{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}}\]

or the magnetic induction equation

eqs_pg.Mss.doit().expand()
\[\displaystyle \frac{\partial}{\partial t} \overline{M_{ss}}{\left(s,\phi,t \right)} = - U_{s}{\left(s,\phi,z,t \right)} \frac{\partial}{\partial s} \overline{M_{ss}}{\left(s,\phi,t \right)} + 2 \overline{M_{ss}}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} U_{s}{\left(s,\phi,z,t \right)} + \frac{U_{s}{\left(s,\phi,z,t \right)} \overline{M_{ss}}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{U_{\phi}{\left(s,\phi,z,t \right)} \frac{\partial}{\partial \phi} \overline{M_{ss}}{\left(s,\phi,t \right)}}{s} + \frac{2 \overline{M_{s\phi}}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} U_{s}{\left(s,\phi,z,t \right)}}{s}\]

Note that the induction equations are already closed. However, vorticity equations contain \(\overline{f_s}\), \(\overline{f_\phi}\), \(\widetilde{f_z}\) and \(f_{e\phi}\), which are the vertically evenly integrated \(s\)-component, \(\phi\)-component, vertically oddly integrated \(z\)-component and the equatorial \(\phi\)-component of body force \(\mathbf{f}\), respectively.

We do not yet know what constitutes these body force. This allows some flexibility regarding which forces are included in the system. Currently, only the forms of the Lorentz force are compiled in the package, but adding viscous diffusion as well as buoyancy force will be straightforward.


Forcing

As mentioned, the forcing in the vorticity equation is only given by placeholder functions. It remains to be defined what forces are involved in the system. This is the task for the forcing module.

The forcing in PlesioGeostroPy are arranged into three layers:

  1. The placeholder functions for general body forces. We have seen these variables above, they are core.fs_sym, core.fp_sym, core.fz_asym and core.fe_p;

  2. The placeholder functions for specific forces. For Lorentz force, we have forcing.Ls_sym, forcing.Lp_sym, forcing.Lz_asym and forcing.Le_p

  3. Expressions for specific forces in terms of PG/transformed variables. This include

    • expressions of the forcing terms in full PG equation, e.g. forcing.Ls_sym_expr, forcing.Lp_sym_expr, forcing.Lz_asym_expr and forcing.Le_p_expr

    • expressions of the forcing terms in linearized PG equation, e.g. forcing.Ls_sym_lin, forcing.Lp_sym_lin, forcing.Lz_asym_lin and forcing.Le_p_lin

    • expressions of the forcing terms in transformed equation, e.g. forcing.Ls_sym_cg, forcing.Lp_sym_cg, forcing.Lz_asym_cg and forcing.Le_p_cg

    • expressions of the forcing terms in linearized transformed equation, e.g. forcing.Ls_sym_lin_cg, forcing.Lp_sym_lin_cg, forcing.Lz_asym_lin_cg and forcing.Le_p_lin_cg

To assemble the desired forcing in the system, one only needs to replace the placeholder functions in the first layer with a combination of placeholder functions of the second layer:

from pg_utils.pg_model import forcing, params

cf_lorentz = params.Le**2

forcing_map = {
    core.fs_sym: cf_lorentz*forcing.Ls_sym,
    core.fp_sym: cf_lorentz*forcing.Lp_sym,
    core.fz_asym: cf_lorentz*forcing.Lz_asym,
    core.fe_p: cf_lorentz*forcing.Le_p,
}

eqs_pg_lorentz = eqs_pg.subs(forcing_map)
eqs_pg_lorentz.Psi.rhs.doit().expand()
\[\displaystyle \frac{\mathrm{Le}^{2} s L_{\phi}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{\mathrm{Le}^{2} s \frac{\partial}{\partial s} \overline{L_\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\mathrm{Le}^{2} \overline{L_\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \widetilde{L_z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{\partial}{\partial \phi} \overline{L_s}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{2 \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \Psi{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}}\]

The expression above is the right hand side of the vorticity equation. Pay attention that we used the rotation period as timescale, and ended up with \(Le^2\) as a prefactor for the Lorentz force (see formulation PDF for details). Next, we simply invoke a predefined dictionary to substitute the explicit forcing expressions (3rd layer) for the placeholder functions (2nd layer). These dictionaries are summarized as follows

Type

PG

Transformed

Total

forcing.force_explicit

forcing.force_explicit_cg

Linearized

forcing.force_explicit_lin

forcing.force_explicit_lin_cg

As we are currently working with total field PG equation, we just do

eqs_pg_explicit = eqs_pg_lorentz.subs(forcing.force_explicit)

The resulting formula is massively complicated already

eqs_pg_explicit.Psi.rhs.doit().expand()
\[\displaystyle \frac{\mathrm{Le}^{2} s^{2} B^{+}_{\phi}{\left(s,\phi,t \right)} B^{+}_{s}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{2 H^{3}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s^{2} B^{+}_{\phi}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{+}_{s}{\left(s,\phi,t \right)}}{2 H^{2}{\left(s \right)}} + \frac{\mathrm{Le}^{2} s^{2} B^{-}_{\phi}{\left(s,\phi,t \right)} B^{-}_{s}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{2 H^{3}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s^{2} B^{-}_{\phi}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{-}_{s}{\left(s,\phi,t \right)}}{2 H^{2}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s^{2} B^{+}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{+}_{\phi}{\left(s,\phi,t \right)}}{2 H^{2}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s^{2} B^{-}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{-}_{\phi}{\left(s,\phi,t \right)}}{2 H^{2}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s B^{+}_{\phi}{\left(s,\phi,t \right)} B^{+}_{s}{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s B^{+}_{\phi}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{+}_{z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\mathrm{Le}^{2} s B^{-}_{\phi}{\left(s,\phi,t \right)} B^{-}_{s}{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B^{-}_{\phi}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{-}_{z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B^{+}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{+}_{s}{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B^{+}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{+}_{z}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{2 H^{2}{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B^{-}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{-}_{s}{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s B^{-}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{-}_{z}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{2 H^{2}{\left(s \right)}} - \frac{\mathrm{Le}^{2} s B^{+}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{+}_{\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B^{+}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{+}_{s}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{2 H^{2}{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B^{-}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B^{-}_{\phi}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\mathrm{Le}^{2} s B^{-}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{-}_{s}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{2 H^{2}{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B_{\phi, z}^e{\left(s,\phi,t \right)} B_{z}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} + \frac{\mathrm{Le}^{2} s B_{s}^e{\left(s,\phi,t \right)} \frac{\partial}{\partial s} B_{\phi}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{\mathrm{Le}^{2} s \frac{\partial^{2}}{\partial s^{2}} \overline{M_{s\phi}}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\mathrm{Le}^{2} B^{+}_{\phi}{\left(s,\phi,t \right)} B^{+}_{z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B^{-}_{\phi}{\left(s,\phi,t \right)} B^{-}_{z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B^{+}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{+}_{z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\mathrm{Le}^{2} B^{-}_{s}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{-}_{z}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B^{+}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{+}_{s}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B^{+}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{+}_{z}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{\mathrm{Le}^{2} B^{-}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{-}_{s}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B^{-}_{z}{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B^{-}_{z}{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B_{\phi}^e{\left(s,\phi,t \right)} B_{s}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} + \frac{\mathrm{Le}^{2} B_{\phi}^e{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B_{\phi}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} - \frac{2 \mathrm{Le}^{2} B_{z}^e{\left(s,\phi,t \right)} \frac{\partial}{\partial \phi} B_{z}^e{\left(s,\phi,t \right)} \frac{d}{d s} H{\left(s \right)}}{H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{d}{d s} H{\left(s \right)} \frac{\partial^{2}}{\partial s\partial \phi} \widetilde{M_{sz}}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{3 \mathrm{Le}^{2} \frac{\partial}{\partial s} \overline{M_{s\phi}}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} - \frac{\mathrm{Le}^{2} \frac{\partial^{2}}{\partial s\partial \phi} \overline{M_{\phi\phi}}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{\partial^{2}}{\partial s\partial \phi} \overline{M_{ss}}{\left(s,\phi,t \right)}}{2 H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{d}{d s} H{\left(s \right)} \frac{\partial^{2}}{\partial \phi^{2}} \widetilde{M_{\phi z}}{\left(s,\phi,t \right)}}{2 s H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \widetilde{M_{sz}}{\left(s,\phi,t \right)}}{2 s H{\left(s \right)}} - \frac{\mathrm{Le}^{2} \frac{\partial}{\partial \phi} \overline{M_{\phi\phi}}{\left(s,\phi,t \right)}}{2 s H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{\partial^{2}}{\partial \phi^{2}} \overline{M_{s\phi}}{\left(s,\phi,t \right)}}{2 s H{\left(s \right)}} + \frac{\mathrm{Le}^{2} \frac{\partial}{\partial \phi} \overline{M_{ss}}{\left(s,\phi,t \right)}}{2 s H{\left(s \right)}} - \frac{2 \frac{d}{d s} H{\left(s \right)} \frac{\partial}{\partial \phi} \Psi{\left(s,\phi,t \right)}}{H^{2}{\left(s \right)}}\]

Carry on!

We have now finished with the fundamentals of the symbolic part in PlesioGeostroPy. There are many modules we haven’t talked about yet, such as the entire spectral expansion module, and the entire numerics module. However, those will require a concrete problem to demonstrate how they actually work. Therefore, we are now ready to (and have to) dive into actually solving problems!