Skip to content

Commit

Permalink
First release of the user guide
Browse files Browse the repository at this point in the history
  • Loading branch information
jodemaey committed Mar 7, 2021
1 parent cc2d91c commit 4a232d7
Show file tree
Hide file tree
Showing 21 changed files with 736 additions and 143 deletions.
28 changes: 7 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Usage

qgs can be used by editing and running the script `qgs_rp.py` and `qgs_maooam.py` found in the main folder.

For more advanced usages, please read the User Guides (TODO).
For more advanced usages, please read the [User Guides](https://qgs.readthedocs.io/en/latest/files/user_guide.html).

Examples
--------
Expand Down Expand Up @@ -130,36 +130,22 @@ Forthcoming developments
* Technical mid-term developments
+ Dimensionally robust Parameter class operation
+ Windows OS support
+ Symbolic inner products (using e.g. [Sympy](https://www.sympy.org/))
- Arbitrary spatial mode basis of functions
- Automatic on-the-fly inner product calculation (numeric or analytic if possible)
- Symbolic PDE equation specification
+ Numerical basis of function
+ Visualisation tools, e.g. based on the [movie-script](https://github.com/jodemaey/movie-script) package
* Long-term development track
+ Active advection
+ True quasi-geostrophic ocean when using ocean model version
+ Salinity in the ocean

+ Salinity in the ocean
+ Symbolic PDE equation specification

Contributing to qgs
-------------------

If you want to contribute actively to the roadmap detailed above, please contact the authors.
If you want to contribute actively to the roadmap detailed above, please contact the main authors.

In addition, if you have made changes that you think will be useful to others, please feel free to suggest these as a pull request on the [qgs Github repository](https://github.com/Climdyn/qgs).

A review of your pull request will follow with possibly suggestions of changes before merging it in the master branch.
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 run the tests found in the folder [model_test](./model_test) to ensure that the model tensors are still valid.
* For substantial additions of code, including a test case in the folder [model_test](./model_test) is recommended.
* Please do not make changes to existing test cases.
* Please document the new functionalities in the documentation. Code addition without documentation addition will not be accepted.
The documentation is done with [sphinx](https://www.sphinx-doc.org/en/master/) 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.
* The team presently maintaining qgs is not working full-time on it, so please be patient as the review of the submission may take some time.

For more information about git, Github and the pull request framework, a good source of information is the [contributing guide](https://mitgcm.readthedocs.io/en/latest/contributing/contributing.html) of the [MITgcm](https://github.com/MITgcm/MITgcm).

More information and guidance about how to do a pull request for qgs can be found in the documentation [here](https://qgs.readthedocs.io/en/latest/files/general_information.html#contributing-to-qgs).

Other atmospheric models in Python
----------------------------------
Expand Down
4 changes: 4 additions & 0 deletions basis/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
.. _abstract base class: https://docs.python.org/3/glossary.html#term-abstract-base-class
"""

# TODO: define setters and init arguments
# TODO: define NumericBasis class

import sys

from abc import ABC
Expand Down
2 changes: 1 addition & 1 deletion basis/fourier.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from sympy import symbols, sin, cos, sqrt

_x, _y = symbols('x y')
_n = symbols('n')
_n = symbols('n', real=True, nonnegative=True)


class ChannelFourierBasis(SymbolicBasis):
Expand Down
34 changes: 5 additions & 29 deletions documentation/source/files/general_information.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ or ::

python qgs_maooam.py

For more advanced usages, please read the User Guide.

.. TODO: add more details and a link to it when the User Guide is ready.
For more advanced usages, please read the :ref:`files/user_guide:User guide`.

Examples
--------
Expand Down Expand Up @@ -129,56 +127,35 @@ Forthcoming developments

+ Dimensionally robust Parameter class operation
+ Windows OS support
+ Symbolic inner products (using e.g. `Sympy`_)

- Arbitrary spatial mode basis of functions
- Automatic on-the-fly inner product calculation (numeric or analytic if possible)
- Symbolic PDE equation specification

+ Numerical basis of function
+ Visualisation tools, e.g. based on the `movie-script`_ package

* Long-term development track

+ Active advection
+ True quasi-geostrophic ocean when using ocean model version
+ Salinity in the ocean
+ Symbolic PDE equation specification

Contributing to qgs
-------------------

If you want to contribute actively to the roadmap detailed above, please contact the authors.
If you want to contribute actively to the roadmap detailed above, please contact the main authors.

In addition, if you have made changes that you think will be useful to others, please feel free to suggest these as a pull request on the `qgs Github repository <https://github.com/Climdyn/qgs>`_.

A review of your pull request will follow with possibly suggestions of changes before merging it in the master branch.
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 :ref:`files/general_information:Running the tests` found in the folder `model_test <../../../../model_test>`_ to ensure that the model tensors are still valid. 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:5. 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.
* The team presently maintaining qgs is not working full-time on it, so please be patient as the review of the submission may take some time.

For more information about git, Github and the pull request framework, a good source of information is the `contributing guide <https://mitgcm.readthedocs.io/en/latest/contributing/contributing.html>`_ of the `MITgcm <https://github.com/MITgcm/MITgcm>`_.

Running the tests
-----------------

.. TODO: move this to the user guide later.
The model core tensors can be tested by running `pytest`_: ::

pytest

This will run all the tests and return a report. The test cases are written using `unittest`_. Additionally, test cases can be executed separately by running: ::

python -m unittest model_test/test_name.py

E.g., testing the MAOOAM inner products can be done by running: ::

python -m unittest model_test/test_inner_products.py

Reporting issues with the software and getting support
------------------------------------------------------

Expand Down Expand Up @@ -217,5 +194,4 @@ References
.. _beta-plane: https://en.wikipedia.org/wiki/Beta_plane
.. _sparse: https://sparse.pydata.org/
.. _sphinx: https://www.sphinx-doc.org/en/master/
.. _pytest: https://docs.pytest.org/en/stable/
.. _unittest: https://docs.python.org/3/library/unittest.html
10 changes: 5 additions & 5 deletions documentation/source/files/model/atmosphere.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ the vertical velocity :math:`\omega = \text{d}p/\text{d}t`, read
& = +k'_d \nabla^2 (\psi^1_{\rm a}-\psi^3_{\rm a}) - \quad \ \frac{f_0}{\Delta p} \omega \nonumber \\
where :math:`\nabla^2` is the horizontal Laplacian.
The Coriolis parameter :math:`f` is linearized around a value :math:`f_0` (:attr:`~params.params.ScaleParams.f0`) evaluated at
latitude :math:`\phi_0` (:attr:`~params.params.ScaleParams.phi0_npi`), :math:`f = f_0 + \beta y`, with
:math:`\beta=\text{d}f/\text{d}y` (:attr:`~params.params.ScaleParams.beta`). The parameter :math:`k'_d`
(:attr:`~params.params.AtmosphericParams.kdp`) quantify the friction between the two atmospheric layers,
and :math:`\Delta p = 500` hPa (:attr:`~params.params.ScaleParams.deltap`) is the pressure difference between the atmospheric layers.
The Coriolis parameter :math:`f` is linearized around a value :math:`f_0` (:attr:`~.params.ScaleParams.f0`) evaluated at
latitude :math:`\phi_0` (:attr:`~.params.ScaleParams.phi0_npi`), :math:`f = f_0 + \beta y`, with
:math:`\beta=\text{d}f/\text{d}y` (:attr:`~.params.ScaleParams.beta`). The parameter :math:`k'_d`
(:attr:`~.params.AtmosphericParams.kdp`) quantify the friction between the two atmospheric layers,
and :math:`\Delta p = 500` hPa (:attr:`~.params.ScaleParams.deltap`) is the pressure difference between the atmospheric layers.
Finally, :math:`J` is the Jacobian :math:`J(S, G) = \partial_x S\, \partial_y G - \partial_y S\, \partial_x G`.


Expand Down
24 changes: 12 additions & 12 deletions documentation/source/files/model/li_model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Model with an orography and heat exchanges
==========================================

In the :ref:`files/model/oro_model:Model with an orography and a temperature profile`, the radiative equilibrium temperature field at the middle of the atmosphere
is specified by a given profile :math:`\theta^\star` (:attr:`~params.params.AtmosphericTemperatureParams.thetas`) and the system relaxes to
is specified by a given profile :math:`\theta^\star` (:attr:`~.params.AtmosphericTemperatureParams.thetas`) and the system relaxes to
this profile due to the `Newtonian cooling`_.

In Li et al. :cite:`li-LHHBD2018`, another scheme for the temperature is proposed, based on the
Expand Down Expand Up @@ -51,8 +51,8 @@ All the modes of this model version are expanded on the set of Fourier modes :ma
and as in MAOOAM, the fields, parameters and variables are non-dimensionalized
by dividing time by :math:`f_0^{-1}` (:attr:`~params.params.ScaleParams.f0`), distance by
the characteristic length scale :math:`L` (:attr:`~params.params.ScaleParams.L`), pressure by the difference :math:`\Delta p` (:attr:`~params.params.ScaleParams.deltap`),
by dividing time by :math:`f_0^{-1}` (:attr:`~.params.ScaleParams.f0`), distance by
the characteristic length scale :math:`L` (:attr:`~.params.ScaleParams.L`), pressure by the difference :math:`\Delta p` (:attr:`~.params.ScaleParams.deltap`),
temperature by :math:`f_0^2 L^2/R`, and streamfunction by :math:`L^2 f_0`. As a result of this non-dimensionalization, the
fields :math:`\theta_{\rm a}` and :math:`\delta T_{\rm a}` can be identified: :math:`2 \theta_{\rm a} \equiv \delta T_{\rm a}`.

Expand All @@ -68,15 +68,15 @@ The equations of the system of ordinary differential equations for this model th
\dot\delta T_{{\rm g},i} & = & - \left(\lambda'_{\rm g}+ s_{B,{\rm g}}\right) \, \delta T_{{\rm g},i} + \left(2 \,\lambda'_{\rm g} + s_{B,{\rm a}}\right) \, \theta_{{\rm a},i} + C'_{{\rm g},i}
where the parameters values have been replaced by their non-dimensional ones and we have also defined
:math:`G = - L^2/L_R^2` (:attr:`~params.params.QgParams.G`),
:math:`\lambda'_{{\rm a}} = \lambda/(\gamma_{\rm a} f_0)` (:attr:`~params.params.QgParams.Lpa`),
:math:`\lambda'_{{\rm g}} = \lambda/(\gamma_{\rm g} f_0)` (:attr:`~params.params.QgParams.Lpgo`),
:math:`S_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~params.params.QgParams.LSBpa`),
:math:`S_{B,{\rm g}} = 2\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~params.params.QgParams.LSBpgo`),
:math:`s_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm g} f_0)` (:attr:`~params.params.QgParams.sbpa`),
:math:`s_{B,{\rm g}} = 4\,\sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm g} f_0)` (:attr:`~params.params.QgParams.sbpgo`),
:math:`C'_{{\rm a},i} = R C_{{\rm a},i} / (2 \gamma_{\rm a} L^2 f_0^3)` (:attr:`~params.params.QgParams.Cpa`),
:math:`C'_{{\rm g},i} = R C_{{\rm g},i} / (\gamma_{\rm g} L^2 f_0^3)` (:attr:`~params.params.QgParams.Cpgo`).
:math:`G = - L^2/L_R^2` (:attr:`~.params.QgParams.G`),
:math:`\lambda'_{{\rm a}} = \lambda/(\gamma_{\rm a} f_0)` (:attr:`~.params.QgParams.Lpa`),
:math:`\lambda'_{{\rm g}} = \lambda/(\gamma_{\rm g} f_0)` (:attr:`~.params.QgParams.Lpgo`),
:math:`S_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~.params.QgParams.LSBpa`),
:math:`S_{B,{\rm g}} = 2\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~.params.QgParams.LSBpgo`),
:math:`s_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm g} f_0)` (:attr:`~.params.QgParams.sbpa`),
:math:`s_{B,{\rm g}} = 4\,\sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm g} f_0)` (:attr:`~.params.QgParams.sbpgo`),
:math:`C'_{{\rm a},i} = R C_{{\rm a},i} / (2 \gamma_{\rm a} L^2 f_0^3)` (:attr:`~.params.QgParams.Cpa`),
:math:`C'_{{\rm g},i} = R C_{{\rm g},i} / (\gamma_{\rm g} L^2 f_0^3)` (:attr:`~.params.QgParams.Cpgo`).

The coefficients :math:`a_{i,j}`, :math:`g_{i, j, m}`, :math:`b_{i, j, m}` and :math:`c_{i, j}` are the inner products of the Fourier modes :math:`F_i`:

Expand Down
30 changes: 15 additions & 15 deletions documentation/source/files/model/maooam_model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ The evolution equations for the atmospheric and oceanic streamfunctions defined
\frac{\partial}{\partial t} \left( \nabla^2 \psi_\text{o} - \frac{\psi_\text{o}}{L_\text{R}^2} \right) + J(\psi_\text{o}, \nabla^2 \psi_\text{o}) + \beta \frac{\partial \psi_\text{o}}{\partial x}
& = -r \nabla^2 \psi_\text{o} +\frac{C}{\rho_{\rm o} h} \nabla^2 (\psi^3_\text{a}-\psi_\text{o}).\nonumber
where :math:`\rho_{\rm o}` is the density of the ocean's water and :math:`h` is the depth of its layer (:attr:`~params.params.OceanicParams.h`).
where :math:`\rho_{\rm o}` is the density of the ocean's water and :math:`h` is the depth of its layer (:attr:`~.params.OceanicParams.h`).
The rightmost term of the last equation represents the impact of the wind stress on the ocean, and is modulated
by the coefficient of the mechanical ocean-atmosphere coupling, :math:`d = C/(\rho_{\rm o} h)` (:attr:`~params.params.OceanicParams.d`).
by the coefficient of the mechanical ocean-atmosphere coupling, :math:`d = C/(\rho_{\rm o} h)` (:attr:`~.params.OceanicParams.d`).

As we did for the :ref:`files/model/oro_model:Model with an orography and a temperature profile`, we rewrite these equations in terms of the `barotropic`_ streamfunction :math:`\psi_{\rm a}` and `baroclinic`_ streamfunction :math:`\theta_{\rm a}`:

Expand Down Expand Up @@ -57,7 +57,7 @@ where :math:`\gamma_\text{a}` (:attr:`.AtmosphericTemperatureParams.gamma`) and
(:attr:`.OceanicTemperatureParams.gamma`) are the heat capacities of the
atmosphere and the active ocean layer. :math:`\lambda` (:attr:`~.AtmosphericTemperatureParams.hlambda`) is the heat transfer coefficient at the
ocean-atmosphere interface.
:math:`\sigma` (:attr:`~params.params.AtmosphericParams.sigma`) is the static stability of the atmosphere, taken to be constant.
:math:`\sigma` (:attr:`~.params.AtmosphericParams.sigma`) is the static stability of the atmosphere, taken to be constant.
The quartic terms represent the long-wave
radiation fluxes between the ocean, the atmosphere, and outer space, with
:math:`\epsilon_\text{a}` (:attr:`~.AtmosphericTemperatureParams.eps`) the emissivity of the grey-body atmosphere and
Expand Down Expand Up @@ -120,7 +120,7 @@ Again, :math:`x` and :math:`y` are the horizontal adimensionalized coordinates d
To easily manipulate these functions and the coefficients of the fields
expansion, we number the basis functions along increasing values of :math:`H_{\rm o}` and then :math:`P_{\rm o}`.
It allows to write the set as :math:`\left\{ \phi_i(x,y); 1 \leq i \leq n_\text{o}\right\}` where :math:`n_{\mathrm{o}}`
(:attr:`~params.params.QgParams.nmod` [1]) is the number of modes of the spectral expansion in the ocean.
(:attr:`~.params.QgParams.nmod` [1]) is the number of modes of the spectral expansion in the ocean.

For example, the model derived in :cite:`mao-VDDG2015` can be specified by setting :math:`H_{\rm o} \in \{1,4\}`; :math:`P_{\rm o} \in \{1,2\}` and the set of basis functions is

Expand Down Expand Up @@ -205,8 +205,8 @@ Ordinary differential equations
-------------------------------

The fields, parameters and variables are non-dimensionalized
by dividing time by :math:`f_0^{-1}` (:attr:`~params.params.ScaleParams.f0`), distance by
the characteristic length scale :math:`L` (:attr:`~params.params.ScaleParams.L`), pressure by the difference :math:`\Delta p` (:attr:`~params.params.ScaleParams.deltap`),
by dividing time by :math:`f_0^{-1}` (:attr:`~.params.ScaleParams.f0`), distance by
the characteristic length scale :math:`L` (:attr:`~.params.ScaleParams.L`), pressure by the difference :math:`\Delta p` (:attr:`~.params.ScaleParams.deltap`),
temperature by :math:`f_0^2 L^2/R`, and streamfunction by :math:`L^2 f_0`. As a result of this non-dimensionalization, the
fields :math:`\theta_{\rm a}` and :math:`\delta T_{\rm a}` can be identified: :math:`2 \theta_{\rm a} \equiv \delta T_{\rm a}`.

Expand All @@ -225,15 +225,15 @@ The ordinary differential equations of the truncated model are:
\dot\delta T_{{\rm o},i} & = & - \sum_{j,m = 1}^{n_{\mathrm{o}}} \, O_{i,j,k} \, \psi_{{\rm o},j} \, \delta T_{{\rm o},k} - \left(\lambda'_{\rm o}+ s_{B,{\rm o}}\right) \, \delta T_{{\rm o},i} + \left(2 \,\lambda'_{\rm o} + s_{B,{\rm a}}\right) \, \sum_{j=1}^{n_{\mathrm{a}}} \, W_{i,j} \, \theta_{{\rm a},j} + \sum_{j=1}^{n_{\mathrm{a}}} \, W_{i,j} \, C'_{{\rm o},j}
where the parameters values have been replaced by their non-dimensional ones and we have also defined
:math:`G = - L^2/L_R^2` (:attr:`~params.params.QgParams.G`),
:math:`\lambda'_{{\rm a}} = \lambda/(\gamma_{\rm a} f_0)` (:attr:`~params.params.QgParams.Lpa`),
:math:`\lambda'_{{\rm o}} = \lambda/(\gamma_{\rm o} f_0)` (:attr:`~params.params.QgParams.Lpgo`),
:math:`S_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~params.params.QgParams.LSBpa`),
:math:`S_{B,{\rm o}} = 2\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~params.params.QgParams.LSBpgo`),
:math:`s_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm o} f_0)` (:attr:`~params.params.QgParams.sbpa`),
:math:`s_{B,{\rm o}} = 4\,\sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm o} f_0)` (:attr:`~params.params.QgParams.sbpgo`),
:math:`C'_{{\rm a},i} = R C_{{\rm a},i} / (2 \gamma_{\rm a} L^2 f_0^3)` (:attr:`~params.params.QgParams.Cpa`),
:math:`C'_{{\rm o},i} = R C_{{\rm o},i} / (\gamma_{\rm o} L^2 f_0^3)` (:attr:`~params.params.QgParams.Cpgo`).
:math:`G = - L^2/L_R^2` (:attr:`~.params.QgParams.G`),
:math:`\lambda'_{{\rm a}} = \lambda/(\gamma_{\rm a} f_0)` (:attr:`~.params.QgParams.Lpa`),
:math:`\lambda'_{{\rm o}} = \lambda/(\gamma_{\rm o} f_0)` (:attr:`~.params.QgParams.Lpgo`),
:math:`S_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~.params.QgParams.LSBpa`),
:math:`S_{B,{\rm o}} = 2\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm a} f_0)` (:attr:`~.params.QgParams.LSBpgo`),
:math:`s_{B,{\rm a}} = 8\,\epsilon_{\rm a}\, \sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm o} f_0)` (:attr:`~.params.QgParams.sbpa`),
:math:`s_{B,{\rm o}} = 4\,\sigma_B \, T_{{\rm a},0}^3 / (\gamma_{\rm o} f_0)` (:attr:`~.params.QgParams.sbpgo`),
:math:`C'_{{\rm a},i} = R C_{{\rm a},i} / (2 \gamma_{\rm a} L^2 f_0^3)` (:attr:`~.params.QgParams.Cpa`),
:math:`C'_{{\rm o},i} = R C_{{\rm o},i} / (\gamma_{\rm o} L^2 f_0^3)` (:attr:`~.params.QgParams.Cpgo`).

The coefficients :math:`a_{i,j}`, :math:`g_{i, j, m}`, :math:`b_{i, j, m}` and :math:`c_{i, j}` are the inner products of the Fourier modes :math:`F_i`:

Expand Down
Loading

0 comments on commit 4a232d7

Please sign in to comment.