Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Note that the Jupyter notebooks are not concerned by this recommendation and wor
#### Activating DifferentialEquations.jl optional support

In addition to the qgs builtin Runge-Kutta integrator, the qgs model can alternatively be integrated with a package called [DifferentialEquations.jl](https://github.com/SciML/DifferentialEquations.jl) written in [Julia](https://julialang.org/), and available through the
[diffeqpy](https://github.com/SciML/diffeqpy) python package.
[diffeqpy](https://github.com/SciML/diffeqpy) Python package.
The diffeqpy package first installation step is done by Anaconda in the qgs environment but then you must [install Julia](https://julialang.org/downloads/) and follow the final manual installation instruction found in the [diffeqpy README](https://github.com/SciML/diffeqpy).

These can be summed up as opening a terminal and doing:
Expand Down Expand Up @@ -208,7 +208,7 @@ Non-exhaustive list:

* [Q-GCM](http://q-gcm.org/): A mid-latitude grid based ocean-atmosphere model like MAOOAM. Code in Fortran,
interface is in Python.
* [pyqg](https://github.com/pyqg/pyqg): A pseudo-spectral python solver for quasi-geostrophic systems.
* [pyqg](https://github.com/pyqg/pyqg): A pseudo-spectral Python solver for quasi-geostrophic systems.
* [Isca](https://execlim.github.io/IscaWebsite/index.html): Research GCM written in Fortran and largely
configured with Python scripts, with internal coding changes required for non-standard cases.

Expand Down
4 changes: 2 additions & 2 deletions documentation/source/files/general_information.rst
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ A review of your pull request will follow with possibly suggestions of changes b
Please consider the following guidelines before submitting:

* Before submitting a pull request, double check that the branch to be merged contains only changes you wish to add to the master branch. This will save time in reviewing the code.
* For any changes to the core model files, please check your submission by running the tests found in the folder `model_test <../../../../model_test>`_ to ensure that the model tensors are still valid (see the section :ref:`files/user_guide:5. Developers information` of the :ref:`files/user_guide:User guide`). Please do not make changes to existing test cases.
* For any changes to the core model files, please check your submission by running the tests found in the folder `model_test <../../../../model_test>`_ to ensure that the model tensors are still valid (see the section :ref:`files/user_guide:6. Developers information` of the :ref:`files/user_guide:User guide`). Please do not make changes to existing test cases.
* For substantial additions of code, including a test case (using `unittest`_) in the folder `model_test <../../../../model_test>`_ is recommended.
* Please document the new functionalities in the documentation. Code addition without documentation addition will not be accepted. The documentation is done with `sphinx`_ and follows the Numpy conventions. Please take a look to the actual code to get an idea about how to document the code.
* If your addition can be considered as a tool not directly related to the core of the model, please develop it in the toolbox folder.
Expand All @@ -182,7 +182,7 @@ Non-exhaustive list:

* `Q-GCM <http://q-gcm.org/>`_: A mid-latitude grid based ocean-atmosphere model like MAOOAM. Code in Fortran,
interface is in Python.
* `pyqg <https://github.com/pyqg/pyqg>`_: A pseudo-spectral python solver for quasi-geostrophic systems.
* `pyqg <https://github.com/pyqg/pyqg>`_: A pseudo-spectral Python solver for quasi-geostrophic systems.
* `Isca <https://execlim.github.io/IscaWebsite/index.html>`_: Research GCM written in Fortran and largely
configured with Python scripts, with internal coding changes required for non-standard cases.

Expand Down
6 changes: 6 additions & 0 deletions documentation/source/files/technical/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ The functions module contains utility functions used by the model, as well as so
.. automodule:: qgs.functions.tendencies
:members:

.. automodule:: qgs.functions.symbolic_mul
:members:

.. automodule:: qgs.functions.symbolic_tendencies
:members:

.. automodule:: qgs.functions.util
:members:
4 changes: 4 additions & 0 deletions documentation/source/files/technical/tensors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ Module holding the model's tendencies tensor encoding each of their additive ter
.. automodule:: qgs.tensors.atmo_thermo_tensor
:show-inheritance:
:members:

.. automodule:: qgs.tensors.symbolic_qgtensor
:show-inheritance:
:members:
13 changes: 8 additions & 5 deletions documentation/source/files/technical_description.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ Using `Sympy`_ qgs offers the functionality to return the ordinary differential

* Python
* Julia
* Fortran-90
* Mathematica
* AUTO-p07 continuation software
* Fortran 90
* `AUTO-p07 <https://github.com/auto-07p/auto-07p>`_ continuation software
* `Mathematica <https://www.wolfram.com/mathematica/>`_ (still being tested)

This also allows the user to specify their own integration method for solving the model equations in python.
This also allows the user to specify their own integration method for solving the model equations in Python.


Additional technical information
Expand All @@ -117,7 +117,9 @@ Additional technical information
* qgs has a `tangent linear model`_ optimized to run ensembles of initial conditions as well, with a broadcast
integration of the tangent model thanks to `Numpy`_.

* The symbolic output functionality of the qgs model relies on `Sympy`_ to perform the tensor calculations. This library is significantly slower than the numerical equivilent and as a result it is currently only feasible to generate the symbolic model equations for model resolutions up to :math:`4x4`.
* The symbolic output functionality of the qgs model relies on `Sympy`_ to perform the tensor calculations.
This library is significantly slower than the numerical equivalent and as a result it is currently only feasible to
generate the symbolic model equations for model resolutions up to :math:`4x4`.

References
----------
Expand All @@ -131,3 +133,4 @@ References
.. _multiprocessing: https://docs.python.org/3.7/library/multiprocessing.html#module-multiprocessing
.. _tangent linear model: http://glossary.ametsoc.org/wiki/Tangent_linear_model
.. _ordinary differential equations: https://en.wikipedia.org/wiki/Ordinary_differential_equation
.. _Sympy: https://www.sympy.org/
34 changes: 21 additions & 13 deletions documentation/source/files/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This guide provides:

1. The different ways to configure qgs in order to obtain the function :math:`\boldsymbol{f}` are explained in the section :ref:`files/user_guide:2. Configuration of qgs`.
2. Some specific ways to configure qgs detailed in the section :ref:`files/user_guide:3. Using user-defined symbolic basis`.
3. Examples of usages of the model's tendencies function :math:`\boldsymbol{f}` are given in the section :ref:`files/user_guide:4. Using qgs (once configured)`.
3. Examples of usages of the model's tendencies function :math:`\boldsymbol{f}` are given in the section :ref:`files/user_guide:5. Using qgs (once configured)`.

2. Configuration of qgs
-----------------------
Expand Down Expand Up @@ -227,7 +227,7 @@ Jacobian matrix :math:`\boldsymbol{\mathrm{Df}}`. Just pass it to the function :
f, Df = create_tendencies(model_parameters)

The function :meth:`f` hence produced can be used to generate the model's trajectories.
See the section :ref:`files/user_guide:4. Using qgs (once configured)` for the possible usages.
See the section :ref:`files/user_guide:5. Using qgs (once configured)` for the possible usages.

2.5 Saving your model
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -466,29 +466,37 @@ See also the following section for the possible usages.
4. Symbolic outputs
-------------------

If the user wants to generate the model tendencies with non-fixed parameters, use the tendencies in another programming language, or use their own integrator in python, the qgs framework can use `Sympy`_ to proform the above calculations symbolically rather than numerically.
If the user wants to generate the model tendencies with non-fixed parameters, or use the tendencies in another programming language,
the qgs framework can use `Sympy`_ to perform the above calculations symbolically rather than numerically.

To return the tendencies including specified parameter values, or to format the tendencies in another programming language, the qgs model is configured as shown in section :ref:`files/user_guide:Configuration of qgs`, however the **Symbolic** inner product is always used in this pipeline. To create the symbolic tendencies, the instance of :class:`.QgParams` is passed to the function :func:`.create_symbolic_tendencies`:
To return the tendencies including specified parameter values, or to format the tendencies in another programming language,
the qgs model is configured as shown in section :ref:`files/user_guide:2. Configuration of qgs`, however the **Symbolic** inner
product is always used in this pipeline.
To create the symbolic tendencies, the instance of :class:`.QgParams` is passed to the function :func:`.create_symbolic_tendencies`:

.. code:: ipython3

from qgs.functions.symbolic_tendencies import create_symbolic_equations
from qgs.functions.symbolic_tendencies import create_symbolic_tendencies

parameters = [model_parameters.par1, model_parameters.par2, model_parameters.par3]

f = create_symbolic_equations(model_parameters, continuation_variables=parameters, language='python')
f = create_symbolic_tendencies(model_parameters, continuation_variables=parameters, language='python')

The varibale :meth:`f` is a string of the model tendencies, formatted in the programming language specified by the keyword :meth:`language`. The model tendencies will contain the specified :meth:`continuation_variables` as free parameters.
The variable :code:`f` is a string of the model tendencies, formatted in the programming language specified by the
keyword :code:`language`. The model tendencies will contain the specified :code:`continuation_variables` as free parameters.

Currently the framework can format the equations in the following programming languages:
* :meth:`python`
* :meth:`julia`
* :meth:`fortran`
* :meth:`mathematica`
* :meth:`auto`

* :code:`python`
* :code:`julia`
* :code:`fortran`
* :code:`auto`
* :code:`mathematica` (still under test)

1. Using qgs (once configured)
Some example on how to use this functionality are provided in the
`notebooks/symbolic_outputs <../../../../notebooks/symbolic_outputs>`_ folder.

5. Using qgs (once configured)
---------------------------------

Once the function :math:`\boldsymbol{f}` giving the model's tendencies has been obtained, it is possible to use it with
Expand Down
3 changes: 3 additions & 0 deletions model_test/test_aotensor_sym_dynT.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

real_eps = np.finfo(np.float64).eps


class TestSymbolicAOTensorDynT(TestBaseSymbolic):
'''
Test class for the Dynamic T Symbolic Tensor
Expand Down Expand Up @@ -85,6 +86,7 @@ def numerical_outputs(self, output_func=None):
for coo, val in zip(num_aotensor.tensor.coords.T, num_aotensor.tensor.data):
_ip_string_format(tfunc, 'num_aotensor', coo, val)


def _ip_string_format(func, symbol, indices, value):
if abs(value) >= real_eps:
s = symbol
Expand All @@ -93,5 +95,6 @@ def _ip_string_format(func, symbol, indices, value):
s += " = % .5E" % value
func(s)


if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions model_test/test_base_symbolic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

real_eps = np.finfo(np.float64).eps


class TestBaseSymbolic(unittest.TestCase):

reference = list()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"outputs": [],
"source": [
"import sys, os\n",
"sys.path.extend([os.path.abspath('../')])"
"sys.path.extend([os.path.abspath('../../')])"
]
},
{
Expand Down Expand Up @@ -114,7 +114,7 @@
"metadata": {},
"outputs": [],
"source": [
"from qgs.functions.symbolic_tendencies import create_symbolic_equations"
"from qgs.functions.symbolic_tendencies import create_symbolic_tendencies"
]
},
{
Expand Down Expand Up @@ -238,7 +238,7 @@
"metadata": {},
"outputs": [],
"source": [
"funcs, = create_symbolic_equations(model_parameters, continuation_variables=[model_parameters.gotemperature_params.C[0], model_parameters.atemperature_params.C[0], model_parameters.atmospheric_params.kd, model_parameters.atmospheric_params.kdp], language='auto')"
"funcs, = create_symbolic_tendencies(model_parameters, continuation_variables=[model_parameters.gotemperature_params.C[0], model_parameters.atemperature_params.C[0], model_parameters.atmospheric_params.kd, model_parameters.atmospheric_params.kdp], language='auto')"
]
},
{
Expand Down
23 changes: 14 additions & 9 deletions notebooks/symbolic_outputs/symbolic_output_land_atmosphere.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"outputs": [],
"source": [
"import sys, os\n",
"sys.path.extend([os.path.abspath('../')])"
"sys.path.extend([os.path.abspath('../../')])"
]
},
{
Expand Down Expand Up @@ -113,7 +113,7 @@
"metadata": {},
"outputs": [],
"source": [
"from qgs.functions.symbolic_tendencies import create_symbolic_equations\n",
"from qgs.functions.symbolic_tendencies import create_symbolic_tendencies\n",
"from qgs.functions.tendencies import create_tendencies"
]
},
Expand Down Expand Up @@ -141,7 +141,7 @@
"outputs": [],
"source": [
"# Time parameters\n",
"dt = 0.1\n"
"dt = 0.1"
]
},
{
Expand Down Expand Up @@ -260,7 +260,15 @@
"outputs": [],
"source": [
"%%time\n",
"funcs, = create_symbolic_equations(model_parameters, continuation_variables=[model_parameters.gotemperature_params.C[0], model_parameters.atemperature_params.C[0], model_parameters.atmospheric_params.kd, model_parameters.atmospheric_params.kdp], language='python')"
"funcs, = create_symbolic_tendencies(\n",
" model_parameters, \n",
" continuation_variables=[\n",
" model_parameters.gotemperature_params.C[0],\n",
" model_parameters.atemperature_params.C[0],\n",
" model_parameters.atmospheric_params.kd,\n",
" model_parameters.atmospheric_params.kdp\n",
" ], \n",
" language='python')"
]
},
{
Expand Down Expand Up @@ -476,10 +484,7 @@
" plt.ylabel('$'+model_parameters.latex_var_string[vary]+'$');\n",
"\n",
" plt.legend()\n",
" k+=1\n",
"\n",
"\n",
"\n"
" k+=1"
]
}
],
Expand All @@ -499,7 +504,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.16"
"version": "3.8.10"
}
},
"nbformat": 4,
Expand Down
21 changes: 4 additions & 17 deletions qgs/functions/symbolic_mul.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,16 @@
"""

from sympy import tensorproduct, tensorcontraction


def add_to_dict(dic, loc, value):
"""Adds `value` to dictionary `dic`, with the dictionary key of `loc`.
If the dictionary did not have a key of `loc` before, a new key is made.

# Jonathan: Add parameters descriptions
"""

try:
dic[loc] += value
except:
dic[loc] = value
return dic
from qgs.functions.util import add_to_dict


def symbolic_tensordot(a, b, axes=2):
"""Compute tensor dot product along specified axes of two sympy symbolic arrays

This is based on `Numpy`_ :meth:`~numpy.tensordot` .

.. _Numpy: https://numpy.org/

Parameters
----------
a, b: ~sympy.tensor.array.DenseNDimArray or ~sympy.tensor.array.SparseNDimArray
Expand All @@ -40,11 +29,9 @@ def symbolic_tensordot(a, b, axes=2):

Returns
-------
output: sympy tensor
output: Sympy tensor
The tensor dot product of the input.

.. _Numpy: https://numpy.org/

"""
as_ = a.shape
nda = len(as_)
Expand Down
Loading