Parametrizations
In this chapter, we will see how to use parametrizations in MOAI. Parametrizations are at the heart of MOAI’s philosophy: they are what makes it modular. They can be used for pretty much anything. They are also recursive, i.e. a parametrization can call another one, which can itself call another one… etc. When it comes to parametrizations in MOAI, your imagination is the only limit!
What are parametrizations?
We have already used parametrizations in this tutorial (every time we called the setParametrization method of the magma ocean object), although we haven’t spent much time explaining in detail what we were doing. A parametrization is simply a quantity that you want to track which is not included in the built in traced quantities of the magma ocean (like the bottom pressure or the density). You simply need to tell the magma ocean object how to calculate this quantity (what’s the formula), and which other quantities you need to do the calculation. Then, this new quantity will be made available to calculate yet other new ones. Let’s take an example:
\[\log f_{{\rm O}_2}=a(p)+b(p)T+c(p)T\ln T+d(p)/T\]where the parameters \(a\), \(b\), \(c\) and \(d\) are each proportional to a different 3\(^{\rm rd}\) order polynomial in \(p\) plus a square root term. So the \(f_{{\rm O}_2}\) depends on the temperature and pressure, which are both built-in accessible quantities of the magma ocean object. You can calculate the \(f_{{\rm O}_2}\) at the surface of the MO, using the \(p_{\rm sfc}\) and \(T_{\rm pot}\) attributes, but you can also calculate the complete \(f_{{\rm O}_2}\) profile through the MO, using the temperature profile along the adiabat. Let’s now see how to implement either of these possibilities.
Setting a new parametrization
As usual, we first need a MO:
[2]:
from MO_lib.eq_basic import MO
MO.updateT_pot(3000)
No file found: calculating lookups, be patient it can take some time!
Surface \(f_{{\rm O}_2}\)
The only method you need to call to set up a parametrization is setParametrization:
[7]:
from chemistry.redox import fO2_buffers_H22 # this is the function implementing equation (1)
MO.setParametrization('fO2_surface', # name of the parametrization
lambda var:10**fO2_buffers_H22(var['p_sfc'],var['T_pot']), # the function itself; notice that it needs to be defined as a function of a dictionnary ("var")
['p_sfc','T_pot'], # the list of variables you need to include in the argument dictionnary var
is_profile=False) # does th eparametrization calculate a profile? No (by default yes)
# The value is store in MO.averages (for scalar parametrizations):
print(MO.averages['fO2_surface'])
0.0027389957633508484
Each time you update the internal state of the MO, either by calling RK4_step or simply updateT_pot (or updateState if know what you’re doing), the value of fO2_surface will be updated according to the new \(T_{\rm pot}\) and \(p_{\rm sfc}\).
\(f_{{\rm O}_2}\) profile
If we want to know the whole profile of \(f_{{\rm O}_2}\), it is very similar: we just need to ask the parametrization to read the pressure and temperature profiles rather than their surface value:
[12]:
# we just need to vectorize fO2_buffers_H22 so that it can read p and T as vector rather than scalars
import numpy as np
fO2_buffers_H22_vec = np.vectorize(fO2_buffers_H22)
MO.setParametrization('fO2_profile',
lambda var:10**fO2_buffers_H22_vec(var['pressures'],var['temperatures']),
['pressures','temperatures'], # The pressures and temperature profiles are simply called... "pressures" and "temperatures"
is_profile=True) # This time it is a profile.
# The value is store in MO.profiles (for profile parametrizations):
import matplotlib.pyplot as plt
plt.semilogx(MO.profiles['fO2_profile'],MO.profiles['pressures']*1e-9)
plt.ylim(135,0)
plt.xlabel(r'$f_{{\rm O}_2}$')
plt.ylabel('pressure [GPa]')
[12]:
Text(0, 0.5, 'pressure [GPa]')
[13]:
print(MO.averages['fO2_profile'])
22484932081.460506
Of course, for the \(F_{{\rm O}_2}\), it is not very insightful, but for other things, it might be useful!
The MO address book
[15]:
from chemistry.equilibria import eq_H
from chemistry.redox import equilibrium_constant_NATAF
def set_K_H(T,fO2):
eq_H.constant = equilibrium_constant_NATAF[eq_H.expression](T) * np.sqrt(fO2)
return eq_H.constant
MO.setParametrization('K_H',lambda var:set_K_H(var['T_pot'],var['fO2_surface']),['T_pot','fO2_surface'],is_profile=False) # here we call fO2_surface, but we could also use fO2_profile_sfc
# since we have two different parametrizations for fO2
print(MO.averages['K_H'])
25.46519933449377
Parametrizations channels
You may want to have some control on when, during the update of the internal state of the MO, a parametrization is going to be updated. For example, if one of your parametrization depends on the partial pressures in an atmosphere where speciation is solved, like in the previous chapter, you want the update to be made after the speciation has been solved for, while the effective equilibrium constant needs to be updated before. This can be done by specifying th eparametrization channel, which decides when the parametrization will be updated. There are 7 built-in parametrization channels:
eos: for the equatoins of state (in general only for density, thermal expansivity and heat capacity, used to calculate the adiabat)
pre-update: parametrizations in this channel are updated before the internal state is updated (i.e. before even the temperature is updated)
pre-frac: parametrizations in this channel are updated just before calling the fractionation function
pre-spec: parametrizations in this channel are updated just before calling the sepeciation function
post-spec: parametrizations in this channel are updated just after calling the sepeciation function
time-dep: parametrizations in this channel are updated during RK4_step, and are integrated to the RK4 time-stepping
internal heating: parametrizations in this channel are updated when calculating the heat-conservation equation
The default parametrization channel is “pre-spec”. Another parametrization channel can be specified using the keyword “param_channel” in the setParametrization method.