Skip to content

Commit f2307eb

Browse files
authored
Tricks section of the documentation (#46)
1 parent 8a70345 commit f2307eb

14 files changed

Lines changed: 220 additions & 12 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
>
55
> -- *Michael Gambon - Layer Cake (2004)*
66
7+
[![Documentation Status](https://img.shields.io/badge/docs-passing-green.svg)](https://climdyn.github.io/LayerCake/)
8+
79
## General Information
810

911
LayerCake is a framework to design models based on systems of partial differential equations (PDEs),
@@ -69,5 +71,5 @@ developed.
6971

7072
## Contributing
7173

72-
LayerCake is in betaa development phase, bug reports and tests of the features are welcome.
74+
LayerCake is in beta development phase, bug reports and tests of the features are welcome.
7375
Please simply raise an issue on [Github](https://github.com/Climdyn/LayerCake/issues).

documentation/source/files/general_information.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ Examples
6868
A few examples are available in the `examples <../../../../examples>`_ folder. More examples will be provided as the code is
6969
developed.
7070

71-
Forthcoming development
72-
-----------------------
71+
Contributing
72+
------------
7373

74-
LayerCake is in alpha development phase, with many new functionalities planned over the next few months.
75-
Stay tuned !
74+
LayerCake is in beta development phase, bug reports and tests of the features are welcome.
75+
Please simply raise an issue on `Github <https://github.com/Climdyn/LayerCake/issues>`_.

documentation/source/files/technical/utils.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ Module with various submodules with useful functions used throughout the code.
1919

2020
.. automodule:: layercake.utils.integration
2121
:members:
22+
23+
.. automodule:: layercake.utils.matrix
24+
:members:
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
2+
Various tricks
3+
==============
4+
5+
On this page, we list several tricks on how to do this or that, related to particular aspects
6+
of the modelling based on systems of partial differential equations.
7+
8+
Spatially varying parameters
9+
----------------------------
10+
11+
It is possible in LayerCake to add parameters varying as a function of the coordinates.
12+
To illustrate this, we are going to modify a spatially uniform parameter in one of the
13+
`examples <../../../../examples/>`_, namely the
14+
`Reinhold & Pierrehumber model <https://github.com/Climdyn/LayerCake/blob/main/examples/atmospheric/baroclinic_one_layer.py>`_ one.
15+
16+
In this model, two terms are representing the friction of the bottom layer with the ground:
17+
18+
* :math:`-\frac{k_d}{2} \nabla^2 (\psi - \theta)` for the equation involving the barotropic streamfunction :math:`\psi`
19+
* :math:`+\frac{k_d}{2} \nabla^2 (\psi - \theta)` for the equation involving the baroclinic streamfunction :math:`\theta`
20+
21+
where the parameter controlling the friction is :math:`k_d`. The full equations of the model can be found `here <https://qgs.readthedocs.io/en/latest/files/model/oro_model.html#mid-layer-equations-and-the-thermal-wind-relation>`_.
22+
23+
Running the `LayerCake code <../../../../examples/atmospheric/baroclinic_one_layer.py>`_ produces the following figure:
24+
25+
.. figure:: tricks/RP1982.png
26+
:scale: 100%
27+
:align: center
28+
29+
which is a section of the model's attractor in the :math:`\psi_2, \psi_3` plane.
30+
31+
Now we can modify the original model's equations by making the parameter :math:`k_d` varies as
32+
33+
.. math::
34+
35+
k_{d,0} + 2 \, k_{d,2} \cos(n x) \sin(y)
36+
37+
This can be done by using the :class:`~layercake.arithmetic.terms.operations.ProductOfTerms` objects to do the product of
38+
a :class:`~layercake.arithmetic.terms.linear.LinearTerm` term involving a :class:`~layercake.variables.field.ParameterField` field representing
39+
the spatial variation of the parameter, and the Laplacian terms representing :math:`\nabla^2 (\psi - \theta)`.
40+
It can be implemented with a few lines added to the `Reinhold & Pierrehumber model code <https://github.com/Climdyn/LayerCake/blob/main/examples/atmospheric/baroclinic_one_layer.py>`_:
41+
42+
.. code:: ipython3
43+
44+
dfriction = ProductOfTerms(LinearTerm(Dk), OperatorTerm(psi, Laplacian, atmospheric_basis.coordinate_system, sign=-1))
45+
dofriction = ProductOfTerms(LinearTerm(Dk), OperatorTerm(theta, Laplacian, atmospheric_basis.coordinate_system))
46+
barotropic_equation.add_rhs_terms([dfriction, dofriction])
47+
48+
in the barotropic equation and
49+
50+
.. code:: ipython3
51+
52+
dfriction = ProductOfTerms(LinearTerm(Dk), OperatorTerm(psi, Laplacian, atmospheric_basis.coordinate_system, sign=1))
53+
dofriction = ProductOfTerms(LinearTerm(Dk), OperatorTerm(theta, Laplacian, atmospheric_basis.coordinate_system, sign=-1))
54+
baroclinic_equation.add_rhs_terms([dfriction, dofriction])
55+
56+
in the baroclinic equation, where :code:`Dk` is the :class:`~layercake.variables.field.ParameterField` object defining the spatial
57+
variation of :math:`k_d`
58+
59+
.. code:: ipython3
60+
61+
# Variable bottom friction
62+
dk = np.zeros(len(atmospheric_basis))
63+
dk[1] = 0.1 * kdp_deriv
64+
Dk = ParameterField('D_k', u'D_k', dk, atmospheric_basis, inner_products_definition)
65+
66+
with :math:`k_{d,2} = D_{k,1} = 0.1 \, k_d` (note the difference of index because of the Python-specific indexing starting from zero).
67+
The equations LaTeX representation now clearly shows the new terms:
68+
69+
.. figure:: tricks/mod_eqs.png
70+
:align: center
71+
72+
with the appearance of the :math:`D_k \nabla^2` terms.
73+
74+
The impact of this spatial variation of the bottom friction coefficient on the model's dynamics
75+
is clearly visible on the 2-dimensional section of the attractor:
76+
77+
.. figure:: tricks/RP1982mod.png
78+
:scale: 100%
79+
:align: center
80+
81+
(Compare with the first figure above.)
82+
83+
Usage of mathematical expressions in the PDEs
84+
---------------------------------------------
85+
86+
Mathematical function can appear in some models PDEs. In general, these are functions of the model's domain coordinates.
87+
Modelling terms involving mathematical functions (of the coordinates) can be implemented in LayerCake using the
88+
:class:`~layercake.arithmetic.symbolic.expressions.Expression` class. In this section, we recycle the example of the
89+
previous one by modifying again the friction with the bottom layer in
90+
the `Reinhold & Pierrehumber model <https://github.com/Climdyn/LayerCake/blob/main/examples/atmospheric/baroclinic_one_layer.py>`_:
91+
92+
.. math::
93+
94+
k_{d} \to k_{d} + F(y) = k_d + k_{d,y} \, \sin(y)
95+
96+
which means that the friction is higher in the higher latitude.
97+
98+
To implement this, we simply need to create an :class:`~layercake.arithmetic.symbolic.expressions.Expression` object to
99+
represent :math:`F(y)` as follow:
100+
101+
.. code:: ipython3
102+
103+
# Variable bottom friction
104+
from sympy import sin
105+
kd_deriv_y = Parameter(0.1 * kd_deriv, symbol=Symbol('k_dy'), latex='k_{d,y}')
106+
F = Expression(kd_deriv_y.symbol * sin(y), expression_parameters=[kd_deriv_y,], latex=r'k_{d,y} \sin(y)')
107+
108+
where we set :math:`k_{d,y} = 0.1 \, k_d`.
109+
Then the variable friction with the bottom can be added like in the previous section, involving the expression
110+
:code:`F` as prefactor:
111+
112+
.. code:: ipython3
113+
114+
dfriction = OperatorTerm(psi, Laplacian, atmospheric_basis.coordinate_system, prefactor=F, sign=-1)
115+
dofriction = OperatorTerm(theta, Laplacian, atmospheric_basis.coordinate_system, prefactor=F)
116+
barotropic_equation.add_rhs_terms([dfriction, dofriction])
117+
118+
dfriction = OperatorTerm(psi, Laplacian, atmospheric_basis.coordinate_system, prefactor=F, sign=1)
119+
dofriction = OperatorTerm(theta, Laplacian, atmospheric_basis.coordinate_system, prefactor=F, sign=-1)
120+
baroclinic_equation.add_rhs_terms([dfriction, dofriction])
121+
122+
and this result in the following equations in LayeCake:
123+
124+
.. figure:: tricks/mod_eqs_siny.png
125+
:align: center
126+
127+
where the terms involving :math:`\sin(y)` are appearing.
128+
129+
Constructing this model and then integrating it then yield:
130+
131+
.. figure:: tricks/RP1982mod_siny.png
132+
:scale: 100%
133+
:align: center
134+
135+
(Again, you can compare with the first figure above.)
136+
137+
Free-threading
138+
--------------
139+
140+
Since Python 3.14, a `free-threaded version of Python is available <https://docs.python.org/3/howto/free-threading-python.html>`_.
141+
LayerCake has been tested for it and seems so far to run smoothly.
142+
143+
This feature is particularly useful if you try to derive complicate, big models with a
144+
large number of modes. LayerCake will then use multiple threads to perform |Sympy| symbolic evaluations,
145+
while the integration of the inner products will still be done using multiple processes.
146+
When being used in a free-threading environment, this is the default behavior, but this can be controlled by environment
147+
variables:
148+
149+
* The :code:`LAYERCAKE_PARALLEL_METHOD` environment variable defines how the Sympy symbolic evaluations are done. It can take two different values:
150+
+ :code:`threads`: the evaluations will be done using threads
151+
+ :code:`processes`: the evaluations will be done using processes. In some complicate cases, it might lead to wrong answers or even crash. This mode is thus not recommended unless you know what you are doing.
152+
153+
If this environment variable is not defined, then LayerCake default behavior is to use threads.
154+
* The :code:`LAYERCAKE_PARALLEL_INTEGRATION` environment variable controls the Sympy symbolic integration parallelization. If set to :code:`none`, the parallelization will be deactivated.
155+
Otherwise, it will parallelized using processes.
156+
If this environment variable is not defined, then LayerCake default behavior is to parallelize using processes.
157+
158+
For example,
159+
160+
.. code:: bash
161+
162+
LAYERCAKE_PARALLEL_METHOD=processes python examples/atmospheric/barotropic_one_layer.py
163+
164+
will launch the `barotropic one layer <https://github.com/Climdyn/LayerCake/blob/main/examples/atmospheric/barotropic_one_layer.py>`_
165+
script with Sympy symbolic evaluation being done using processes.
166+
167+
.. warning::
168+
169+
Launching the previous line with symbolic evaluation being done in processes with a free-threaded Python will result in
170+
a crash. Use the free-threaded Python only if :code:`LAYERCAKE_PARALLEL_METHOD` is set to :code:`threads`.
171+
172+
Installing the free-threaded version of Python can be done using Anaconda, by typing:
173+
174+
.. code:: bash
175+
176+
conda env create -f environment_freethreading.yml
177+
178+
which will create a conda environment :code:`layercake_ft`.
179+
Upon activation:
180+
181+
.. code:: bash
182+
183+
conda activate layercake_ft
184+
185+
any Python code will be run in `free-threading` mode.
186+
187+
.. warning::
188+
189+
Python free-threading mode is still somewhat experimental, and
190+
the obtained models and results must be
191+
scrutinized with care and double-checked.
192+
128 KB
Loading
137 KB
Loading
112 KB
Loading
14.4 KB
Loading
14.5 KB
Loading

documentation/source/files/user_guide.rst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
User guide
22
==========
33

4-
This guide explains how the LayerCake framework can be used to transform a set of two-dimensional partial differential
4+
This guide explains how the LayerCake framework can be used to transform a set of two-dimensional partial differential equations (PDEs)
55

66
.. math::
77
8-
\partial_t \mathcal{F}^{\mathrm LHS}_i (\psi_1, \ldots, \psi_N) = \mathcal{F}^{\mathrm{RHS}}_i (\psi_1, \ldots, \psi_N) \qquad , \quad i = 1,\ldots,N
8+
\partial_t \mathcal{F}^{\mathrm LHS}_i \left[\psi_1, \ldots, \psi_N\right] = \mathcal{F}^{\mathrm{RHS}}_i \left[\psi_1, \ldots, \psi_N\right] \qquad , \quad i = 1,\ldots,N
99
10-
equations (PDEs) defined on a particular domain into a system of ordinary differential equations (ODEs)
10+
defined on a particular domain into a system of ordinary differential equations (ODEs)
1111
with an automated `Galerkin method`_. This method projects all the fields :math:`\psi_j` on given function basis :math:`\phi_{j,k}`:
1212

1313
.. math::
@@ -197,7 +197,7 @@ If one type :code:`atmospheric_basis` in a terminal after defining it way above,
197197
[sqrt(2)*cos(y), 2*sin(y)*cos(n*x), 2*sin(y)*sin(n*x), sqrt(2)*cos(2*y), 2*sin(2*y)*cos(n*x), 2*sin(2*y)*sin(n*x), 2*sin(y)*cos(2*n*x), 2*sin(y)*sin(2*n*x), 2*sin(2*y)*cos(2*n*x), 2*sin(2*y)*sin(2*n*x)]
198198
199199
We also need to create an inner product definition so that LayerCake knows how you want your PDEs to be projected.
200-
In general, using the :class:`~layercake.inner_products.definition.StandardSymbolicInnerProductDefinition` definition is sufficient for most model:
200+
In general, using the :class:`~layercake.inner_products.definition.StandardSymbolicInnerProductDefinition` definition is sufficient for most models:
201201

202202
.. code:: ipython3
203203
@@ -809,6 +809,11 @@ This functionality is thus particularly useful to get the tendencies and Jacobia
809809
involving the model's parameters. For example, this enables the study of the models with bifurcation analysis
810810
tools such as AUTO-07p :cite:`user-doedel2007` and auto-AUTO :cite:`user-DH2025`.
811811

812+
.. note::
813+
814+
As a final note, you can also take a look at the other examples in the `examples <../../../examples/>`_ folder.
815+
You can also find specific LayerCake tricks on the :ref:`files/tricks:Various tricks` page.
816+
812817

813818
References
814819
----------

0 commit comments

Comments
 (0)