Unverified Commit 1d5acd38 authored by Dion Häfner's avatar Dion Häfner Committed by GitHub

Merge pull request #72 from team-ocean/plugin

Implement a plugin system for Veros
parents e73ca620 a20acb25
......@@ -6,11 +6,11 @@
<a href="http://veros.readthedocs.io/?badge=latest">
<img src="https://readthedocs.org/projects/veros/badge/?version=latest" alt="Documentation status">
</a>
<a href="https://travis-ci.org/dionhaefner/veros">
<img src="https://travis-ci.org/dionhaefner/veros.svg?branch=master" alt="Build status">
<a href="https://travis-ci.org/team-ocean/veros">
<img src="https://travis-ci.org/team-ocean/veros.svg?branch=master" alt="Build status">
</a>
<a href="https://codecov.io/gh/dionhaefner/veros">
<img src="https://codecov.io/gh/dionhaefner/veros/branch/master/graph/badge.svg" alt="Code Coverage">
<a href="https://codecov.io/gh/team-ocean/veros">
<img src="https://codecov.io/gh/team-ocean/veros/branch/master/graph/badge.svg" alt="Code Coverage">
</a>
<a href="https://zenodo.org/badge/latestdoi/87419383">
<img src="https://zenodo.org/badge/87419383.svg" alt="DOI">
......@@ -110,7 +110,7 @@ As soon as you have a working environment, installing Veros is simple:
1. Clone the repository to your hard-drive:
```bash
$ git clone https://github.com/dionhaefner/veros.git
$ git clone https://github.com/team-ocean/veros.git
```
2. Install it, preferably with
......@@ -134,7 +134,7 @@ and model domain you want to use. This is done by subclassing the
should have a look at the pre-implemented model setups in the
repository\'s `setup` folder, or use the `veros copy-setup` command to
copy one into your current folder. A good place to start is the [ACC
model](https://github.com/dionhaefner/veros/blob/master/setup/acc/acc.py):
model](https://github.com/team-ocean/veros/blob/master/setup/acc/acc.py):
```bash
$ veros copy-setup acc
......@@ -159,13 +159,13 @@ nice setup, fixed a bug, or even extended Veros\' core mechanics. There
are two ways to contribute:
- If you want to report a bug or request a missing feature, please
[open an issue](https://github.com/dionhaefner/veros/issues). If you
[open an issue](https://github.com/team-ocean/veros/issues). If you
are reporting a bug, make sure to include all relevant information
for reproducing it (ideally through a *minimal* code sample).
- If you want to fix the issue yourself, or wrote an extension for
Veros - great! You are welcome to submit your code for review by
committing it to a repository and opening a [pull
request](https://github.com/dionhaefner/veros/pulls). However,
request](https://github.com/team-ocean/veros/pulls). However,
before you do so, please check [the contribution
guide](http://veros.readthedocs.io/quickstart/get-started.html#enhancing-veros)
for some tips on testing and benchmarking, and to make sure that
......
......@@ -40,9 +40,10 @@ extensions = [
'sphinx.ext.viewcode',
'sphinx.ext.mathjax',
'sphinx.ext.napoleon',
'sphinx.ext.intersphinx',
'sphinxcontrib.programoutput',
'sphinx_fontawesome',
]
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
......@@ -174,6 +175,9 @@ texinfo_documents = [
autodoc_member_order = "bysource"
autodoc_default_options = {"show-inheritance": None}
# -- Options for intersphinx ----------------------------------------------
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
# -- Custom exec directive ------------------------------------------------
from os.path import basename
......@@ -205,7 +209,7 @@ class ExecDirective(Directive):
self.state_machine.insert_input(lines, source)
return []
except Exception:
return [nodes.error(None, nodes.paragraph(text, "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1])))]
return [nodes.error(None, nodes.paragraph(text="Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1])))]
finally:
sys.stdout = oldStdout
......
......@@ -6,7 +6,7 @@
Versatile Ocean Simulation in Pure Python
=========================================
Veros, *the versatile ocean simulator*, aims to be the swiss army knife of ocean modeling. It is a full-fledged :abbr:`GCM (general circulation model)` that supports anything between highly idealized configurations and realistic set-ups, targeting students and seasoned researchers alike. Thanks to its seamless interplay with `Bohrium <https://github.com/bh107/bohrium>`_, Veros runs efficiently on your laptop, gaming PC (with experimental GPU support through OpenCL & CUDA), and small cluster. Veros has a clear focus on simplicity, usability, and adaptability - *because the Baroque is over*.
Veros, *the versatile ocean simulator*, aims to be the swiss army knife of ocean modeling. It is a full-fledged :abbr:`GCM (general circulation model)` that supports anything between highly idealized configurations and realistic set-ups. Thanks to its interplay with `Bohrium <https://github.com/bh107/bohrium>`_, Veros runs efficiently on your laptop, gaming PC (with experimental GPU support through OpenCL & CUDA), and small cluster. In short, we want to enable ocean modelling with a clear focus on simplicity, usability, and adaptability.
If you want to learn more about the background and capabilities of Veros, you should check out :doc:`quickstart/introduction`. If you are already convinced, you can jump right into action, and :doc:`learn how to get started <quickstart/get-started>` instead!
......@@ -36,6 +36,14 @@ If you want to learn more about the background and capabilities of Veros, you sh
reference/cli
reference/public-api
.. toctree::
:maxdepth: 1
:caption: Plug-ins
plugins/user-guide
Biogeochemistry plug-in (Veros-BGC) <https://readthedocs.io/veros-bgc>
plugins/developer-guide
.. toctree::
:maxdepth: 2
:caption: More Information
......@@ -44,4 +52,4 @@ If you want to learn more about the background and capabilities of Veros, you sh
more/benchmarks
more/publications
more/contact
Visit us on GitHub <https://github.com/dionhaefner/veros>
Visit us on GitHub <https://github.com/team-ocean/veros>
Contact
=======
If you want to report a bug in Veros, have a technical inquiry, or want to ask for a missing feature, please use our `issue tracker <https://github.com/dionhaefner/veros/issues>`_ on GitHub.
If you want to report a bug in Veros, have a technical inquiry, or want to ask for a missing feature, please use our `issue tracker <https://github.com/team-ocean/veros/issues>`_ on GitHub.
In case you have general questions about Veros, please contact `the maintainer <https://github.com/dionhaefner>`_ of the Veros repository.
In case you have general questions about Veros, please contact `the maintainer <https://github.com/team-ocean>`_ of the Veros repository.
How to write a Veros plug-in
============================
Writing a plug-in for Veros is relatively simple.
A plug-in can be any Python package that accepts a :class:`VerosState <veros.state.VerosState>` object.
The plug-in is then free to modify the model state in any way it pleases.
The only requirement for the plug-in to be usable in Veros setups is that it declares a special object in its top :file:`__init__.py` file:
::
__VEROS_INTERFACE__ = dict(
name='my-plugin',
setup_entrypoint=my_setup_function,
run_entrypoint=my_main_function
)
The functions passed in :obj:`setup_entrypoint` and :obj:`run_entrypoint` are then called by Veros during model set-up and after each time step, respectively, with the model state as the sole argument.
An example for these functions could be:
::
from veros import veros_method
@veros_method
def my_setup_function(vs):
pass
@veros_method
def my_main_function(vs):
# apply simple ice mask
mask = np.logical_and(vs.temp[:, :, -1, vs.tau] * vs.maskT[:, :, -1] < -1.8,
vs.forc_temp_surface < 0.)
vs.forc_temp_surface[mask] = 0.0
vs.forc_salt_surface[mask] = 0.0
In this case, the setup function does nothing, while the main function sets temperature and salinity forcing to 0 where the surface temperature is smaller than -1.8 degrees (a very crude sea ice model).
Custom settings, variables, and diagnostics
-------------------------------------------
In real-world applications, you probably want to use custom settings, variables, and/or diagnostics in your plug-in.
You can specify those as additional arguments to :obj:`__VEROS_INTERFACE__`:
::
__VEROS_INTERFACE__ = dict(
name='my-plugin',
setup_entrypoint=my_setup_function,
run_entrypoint=my_main_function,
settings=my_settings,
variables=my_variables,
conditional_variables=my_conditional_variables,
diagnostics=[MyDiagnostic]
)
In this case, :obj:`my_settings` is a :class:`dict` mapping the name of the setting to a :class:`Setting <veros.settings.Setting>` object:
::
from collections import OrderedDict # to preserve order
from veros.settings import Setting
my_settings = OrderedDict([
('enable_my_plugin', Setting(False, bool, 'Enable my plugin')),
('temperature_cutoff', Setting(-1.8, float, 'Cut-off surface temperature')),
])
Similarly, for variables and conditional variables:
::
from collections import OrderedDict # to preserve order
from veros.variables import Variable, T_GRID
my_variables = OrderedDict([
('my_variable', Variable('Description', T_GRID, 'unit', 'Long description')),
])
my_conditional_variables = OrderedDict([
('enable_my_plugin', # condition
OrderedDict([
('my_conditional_variable', Variable(
'description', T_GRID, 'unit', 'Long description'
)),
])),
])
The so-defined settings and variables are then available as attributes of the Veros state object, as usual:
::
@veros_method
def my_function(vs):
if vs.enable_my_plugin:
vs.my_variable[...] = 0.
.. seealso::
For more inspiration on how to specify settings and variables, have a look at the built-in :file:`settings.py` and :file:`variables.py` files.
Diagnostics are defined similarly, but they have to be a subclass of :class:`VerosDiagnostic <veros.diagnostics.diagnostic.VerosDiagnostic>`.
Shipping custom model setups
----------------------------
You can use a special entrypoint in the :file:`setup.py` file of your plug-in to inform the Veros command-line interface of your custom setups:
::
from setuptools import setup
setup(
name='my-plugin',
packages='my_plugin',
entry_points={
'veros.setup_dirs': [
'my_plugin = my_plugin.setup'
]
}
)
This assumes, that your custom setups are located in the folder :file:`my_plugin/setup`.
Then, `veros copy-setup` will automatically find your custom setups if the plug-in is installed:
::
$ veros copy-setup --help
Usage: veros copy-setup [OPTIONS] SETUP
Copy a standard setup to another directory.
Available setups:
acc, acc_sector, eady, global_1deg, global_4deg,
global_flexible, my_setup, north_atlantic, wave_propagation
Example:
$ veros copy-setup global_4deg --to ~/veros-setups/4deg-lowfric
Further directories containing setup templates can be added to this
command via the VEROS_SETUP_DIR environment variable.
Options:
--to PATH Target directory, must not exist (default: copy to current
working directory)
--help Show this message and exit.
In this case, the custom setup is located in the folder :file:`my_plugin/setup/my_setup`, and thus shows up as :obj:`my_setup`.
How to use plug-ins
===================
A plug-in is an optional extension for Veros that you can use to enable additional physics, outputs, or diagnostics.
.. note::
Plug-ins do not necessarily meet the same quality standards as the Veros core, and not all plug-ins are directly affiliated with Veros or the Veros developers. You should carefully check whether a given plug-in fits your needs.
As a first step, install the plug-in you want to use, e.g. :obj:`veros-bgc` via
::
$ pip install veros-bgc
You can then immediately use any custom setups included in the plug-in:
::
$ veros copy-setup bgc_global_4deg
To use a plug-in in a Veros setup, all you need to do is to import it and add it to the :obj:`__veros_plugins__` attribute of your setup class:
::
import veros_bgc
class MySetup(VerosSetup):
__veros_plugins__ = (veros_bgc,)
# - rest of the setup definition -
This step is probably not necessary if you use a setup that was shipped with the plug-in, but in doubt you should double-check that the plug-in is activated properly.
.. seealso::
For more information, refer to the documentation of the plug-in in question. You can find some suggestions in the contents of this section.
......@@ -33,7 +33,7 @@ Using Anaconda (multi-platform, recommended)
2. Clone the Veros repository: ::
$ git clone https://github.com/dionhaefner/veros.git
$ git clone https://github.com/team-ocean/veros.git
2. Create a new conda environment for Veros, and install all relevant dependencies,
by running ::
......@@ -60,7 +60,7 @@ On bare metal (Ubuntu / Debian)
2. Clone our repository: ::
$ git clone https://github.com/dionhaefner/veros.git
$ git clone https://github.com/team-ocean/veros.git
3. Install Veros (preferably in a virtual environment) via::
......@@ -209,7 +209,7 @@ We believe that the best way to learn how Veros works is to read its source code
In case you want to add additional output capabilities or compute additional quantities without changing the main solution of the simulation, you should consider :doc:`adding a custom diagnostic </reference/diagnostics>`.
A convenient way to implement your modifications is to create your own fork of Veros on GitHub, and submit a `pull request <https://github.com/dionhaefner/veros/pulls>`_ if you think your modifications could be useful for the Veros community.
A convenient way to implement your modifications is to create your own fork of Veros on GitHub, and submit a `pull request <https://github.com/team-ocean/veros/pulls>`_ if you think your modifications could be useful for the Veros community.
.. seealso::
......
......@@ -14,7 +14,7 @@ They are available as attributes of all instances of the :class:`Veros state cla
for key, sett in SETTINGS.items():
print(".. _setting-{}:".format(key))
print("")
print(".. data:: {} = {}".format(key, sett.default))
print(".. py:attribute:: VerosState.{} = {}".format(key, sett.default))
print("")
print(" {}".format(sett.description))
print("")
.. _variables:
Model variables
---------------
===============
The variable meta-data (i.e., all instances of :class:`veros.variables.Variable`)
are available in a dictionary as the attribute :attr:`Veros.variables`. The actual
......@@ -18,12 +18,12 @@ are time dependent and should be added to the output, while ``var_data`` is a di
with the same keys containing the corresponding data arrays.
Variable class
++++++++++++++
--------------
.. autoclass:: veros.variables.Variable
Available variables
+++++++++++++++++++
-------------------
There are two kinds of variables in Veros. Main variables are always present in a
simulation, while conditional variables are only available if their respective
......@@ -40,16 +40,18 @@ Attributes:
from veros.variables import MAIN_VARIABLES, CONDITIONAL_VARIABLES
first_condition = True
for condition, vardict in [(None, MAIN_VARIABLES)] + list(CONDITIONAL_VARIABLES.items()):
if not vardict:
continue
if condition:
if first_condition:
print("Conditional variables")
print("=====================")
print("+++++++++++++++++++++")
first_condition = False
print(condition)
print(len(condition) * "#")
else:
print("Main variables")
print("==============")
print("++++++++++++++")
print("")
for key, var in vardict.items():
flags = ""
......@@ -59,7 +61,7 @@ Attributes:
flags += ":fa:`download` "
if var.write_to_restart:
flags += ":fa:`repeat` "
print(".. py:attribute:: Veros.{}".format(key))
print(".. py:attribute:: VerosState.{}".format(key))
print("")
print(" :units: {}".format(var.units))
print(" :dimensions: {}".format(", ".join(var.dims)))
......
Running Veros on a cluster
==========================
This tutorial walks you through some of the most common challenges that are specific to large, shared architectures like clusters and supercomputers. In case you are still having trouble setting up or running Veros on a large architecture after reading it, you should first contact the administrator of your cluster. Otherwise, you should of course feel free to `open an issue <https://github.com/dionhaefner/veros/issues>`_.
This tutorial walks you through some of the most common challenges that are specific to large, shared architectures like clusters and supercomputers. In case you are still having trouble setting up or running Veros on a large architecture after reading it, you should first contact the administrator of your cluster. Otherwise, you should of course feel free to `open an issue <https://github.com/team-ocean/veros/issues>`_.
Installation
++++++++++++
......
......@@ -85,4 +85,4 @@ If your changes to Veros turn out to have a negative effect on the runtime of th
vs.u[...] = np.asarray(external_function(u_np))
- If you are still having trouble, don't hesitate to ask for help (e.g. `on GitHub <https://github.com/dionhaefner/veros/issues>`_).
- If you are still having trouble, don't hesitate to ask for help (e.g. `on GitHub <https://github.com/team-ocean/veros/issues>`_).
......@@ -26,6 +26,7 @@ Operating System :: MacOS
INSTALL_REQUIRES = [
'click',
'entrypoints',
'requests>=2.18',
'numpy>=1.13',
'scipy',
......@@ -77,9 +78,13 @@ setup(
extras_require=EXTRAS_REQUIRE,
entry_points={
'console_scripts': CONSOLE_SCRIPTS,
'veros.setup_dirs': [
'base = veros.setup'
]
},
package_data={
'veros': PACKAGE_DATA
},
classifiers=[c for c in CLASSIFIERS.split('\n') if c]
classifiers=[c for c in CLASSIFIERS.split('\n') if c],
zip_safe=False,
)
......@@ -28,5 +28,7 @@ def test_veros_copy_setup(runner):
ignore = [f for f in os.listdir(srcpath) if any(
fnmatch.fnmatch(f, pattern) for pattern in veros.cli.veros_copy_setup.IGNORE_PATTERNS
)]
ignore.append('version.txt')
comparer = filecmp.dircmp(outpath, srcpath, ignore=ignore)
assert not comparer.left_only and not comparer.right_only and not comparer.diff_files
......@@ -186,17 +186,17 @@ class VerosPyOMUnitTest:
for a, (v1, v2) in differing_arrays.items():
print('{}, {!r}, {!r}'.format(a, np.max(v1), np.max(v2)))
veros_timers = {k: Timer('veros ' + k) for k in self.test_routines}
veros_legacy_timers = {k: Timer('veros legacy ' + k) for k in self.test_routines}
veros_timers = {k: Timer() for k in self.test_routines}
veros_legacy_timers = {k: Timer() for k in self.test_routines}
for routine in self.test_routines.keys():
veros_args, veros_legacy_args = self.test_routines[routine]
with veros_timers[routine]:
getattr(self.test_module, routine)(*veros_args)
veros_timers[routine].print_time()
print('[{}]: {:.3f}s'.format(routine, veros_timers[routine].get_last_time()))
with veros_legacy_timers[routine]:
self.veros_legacy.call_fortran_routine(routine, **veros_legacy_args)
veros_legacy_timers[routine].print_time()
print('[legacy {}]: {:.3f}s'.format(routine, veros_legacy_timers[routine].get_last_time()))
self.test_passed(routine)
self.initialize()
......
......@@ -2,16 +2,20 @@
import os
import shutil
import pkg_resources
import functools
import click
import entrypoints
SETUPDIR_ENVVAR = 'VEROS_SETUP_DIR'
IGNORE_PATTERNS = ['__init__.py', '*.pyc', '__pycache__/']
SETUPS = {}
setup_dirs = [pkg_resources.resource_filename('veros', 'setup')]
setup_dirs = [
os.path.dirname(e.load().__file__)
for e in entrypoints.get_group_all('veros.setup_dirs')
]
for setup_dir in os.environ.get(SETUPDIR_ENVVAR, '').split(';'):
if os.path.isdir(setup_dir):
......@@ -30,10 +34,23 @@ for setup_dir in setup_dirs:
SETUP_NAMES = sorted(SETUPS.keys())
def write_version_file(target_dir, origin):
from veros import __version__ as veros_version
with open(os.path.join(target_dir, 'version.txt'), 'w') as f:
f.write(
'Veros v{veros_version}\n'
'{origin}\n'
.format(origin=origin, veros_version=veros_version)
)
def copy_setup(setup, to=None):
"""Copy a standard setup to another directory.
Argument must be one of: {setups}
Available setups:
{setups}
Example:
......@@ -58,6 +75,8 @@ def copy_setup(setup, to=None):
SETUPS[setup], to, ignore=ignore
)
write_version_file(to, SETUPS[setup])
copy_setup.__doc__ = copy_setup.__doc__.format(
setups=', '.join(SETUP_NAMES), setup_envvar=SETUPDIR_ENVVAR
......
This diff is collapsed.
......@@ -98,21 +98,18 @@ def _calc_implicit_part(vs, tr):
@veros_method
def isoneutral_diffusion(vs, tr, istemp, iso=True, skew=False):
def isoneutral_diffusion_tracer(vs, tr, dtracer_iso, iso=True, skew=False):
"""
Isopycnal diffusion for tracer,
following functional formulation by Griffies et al
Dissipation is calculated and stored in P_diss_iso
T/S changes are added to dtemp_iso/dsalt_iso
Isoneutral diffusion for general tracers
"""
if iso:
K_iso = vs.K_iso
else:
K_iso = 0
K_iso = np.zeros_like(vs.K_iso)
if skew:
K_skew = vs.K_gm
else:
K_skew = 0
K_skew = np.zeros_like(vs.K_gm)
_calc_tracer_fluxes(vs, tr, K_iso, K_skew)
......@@ -120,10 +117,7 @@ def isoneutral_diffusion(vs, tr, istemp, iso=True, skew=False):
add explicit part
"""
aloc = _calc_explicit_part(vs)
if istemp:
vs.dtemp_iso[...] += aloc[...]
else:
vs.dsalt_iso[...] += aloc[...]
dtracer_iso[...] += aloc[...]
tr[2:-2, 2:-2, :, vs.taup1] += vs.dt_tracer * aloc[2:-2, 2:-2, :]
"""
......@@ -132,10 +126,23 @@ def isoneutral_diffusion(vs, tr, istemp, iso=True, skew=False):
if iso:
aloc[...] = tr[:, :, :, vs.taup1]
_calc_implicit_part(vs, tr)
if istemp:
vs.dtemp_iso += (tr[:, :, :, vs.taup1] - aloc) / vs.dt_tracer
else:
vs.dsalt_iso += (tr[:, :, :, vs.taup1] - aloc) / vs.dt_tracer
dtracer_iso[...] += (tr[:, :, :, vs.taup1] - aloc) / vs.dt_tracer
@veros_method
def isoneutral_diffusion(vs, tr, istemp, iso=True, skew=False):
"""
Isopycnal diffusion for tracer,
following functional formulation by Griffies et al
Dissipation is calculated and stored in P_diss_iso
T/S changes are added to dtemp_iso/dsalt_iso
"""
if istemp:
dtracer_iso = vs.dtemp_iso
else:
dtracer_iso = vs.dsalt_iso
isoneutral_diffusion_tracer(vs, tr, dtracer_iso, iso=iso, skew=skew)
"""
dissipation by isopycnal mixing
......
......@@ -68,7 +68,7 @@ def _veros_method(function, inline=False, dist_safe=True, local_vars=None,
def veros_method_wrapper(*args, **kwargs):
from . import runtime_settings as rs, runtime_state as rst
from .backend import flush, get_backend
from .state import VerosState
from .state import VerosStateBase
from .state_dist import DistributedVerosState
from .distributed import broadcast
......@@ -83,8 +83,8 @@ def _veros_method(function, inline=False, dist_safe=True, local_vars=None,
veros_state = args[narg]
if not isinstance(veros_state, VerosState):
raise TypeError('first argument to a veros_method must be subclass of VerosState')
if not isinstance(veros_state, VerosStateBase):
raise TypeError('first argument to a veros_method must be a veros state object')
reset_dist_safe = False
if not CONTEXT.is_dist_safe:
......
......@@ -6,10 +6,10 @@ from .io_tools import hdf5 as h5tools
@veros_method
def create_diagnostics(vs):
def create_default_diagnostics(vs):
return {Diag.name: Diag(vs) for Diag in (averages.Averages, cfl_monitor.CFLMonitor,
energy.Energy, overturning.Overturning,
snapshot.Snapshot, tracer_monitor.TracerMonitor)}
energy.Energy, overturning.Overturning,
snapshot.Snapshot, tracer_monitor.TracerMonitor)}
@veros_method
......
......@@ -40,8 +40,8 @@ class CFLMonitor(VerosDiagnostic):
if np.isnan(cfl) or np.isnan(wcfl):
raise RuntimeError('CFL number is NaN at iteration {}'.format(vs.itt))
logger.warning(' Maximal hor. CFL number = {}'.format(float(cfl)))
logger.warning(' Maximal ver. CFL number = {}'.format(float(wcfl)))
logger.diagnostic(' Maximal hor. CFL number = {}'.format(float(cfl)))
logger.diagnostic(' Maximal ver. CFL number = {}'.format(float(wcfl)))
if vs.enable_eke or vs.enable_tke or vs.enable_idemix:
cfl = global_max(vs, max(
......@@ -55,8 +55,8 @@ class CFLMonitor(VerosDiagnostic):
np.abs(vs.w_wgrid[2:-2, 2:-2, :]) * vs.maskW[2:-2, 2:-2, :]
/ vs.dzt[np.newaxis, np.newaxis, :] * vs.dt_tracer
))
logger.warning(' Maximal hor. CFL number on w grid = {}'.format(float(cfl)))
logger.warning(' Maximal ver. CFL number on w grid = {}'.format(float(wcfl)))
logger.diagnostic(' Maximal hor. CFL number on w grid = {}'.format(float(cfl)))
logger.diagnostic(' Maximal ver. CFL number on w grid = {}'.format(float(wcfl)))
def read_restart(self, vs, infile):
pass
......
......@@ -37,14 +37,14 @@ class TracerMonitor(VerosDiagnostic):
vtemp = global_sum(vs, np.sum(cell_volume * vs.temp[2:-2, 2:-2, :, vs.tau]**2))
vsalt = global_sum(vs, np.sum(cell_volume * vs.salt[2:-2, 2:-2, :, vs.tau]**2))
logger.warning(' Mean temperature {} change to last {}'
.format(float(tempm / volm), float((tempm - self.tempm1) / volm)))
logger.warning(' Mean salinity {} change to last {}'
.format(float(saltm / volm), float((saltm - self.saltm1) / volm)))
logger.warning(' Temperature var. {} change to last {}'
.format(float(vtemp / volm), float((vtemp - self.vtemp1) / volm)))
logger.warning(' Salinity var. {} change to last {}'
.format(float(vsalt / volm), float((vsalt - self.vsalt1) / volm)))
logger.diagnostic(' Mean temperature {} change to last {}'
.format(float(tempm / volm), float((tempm - self.tempm1) / volm)))
logger.diagnostic(' Mean salinity {} change to last {}'
.format(float(saltm / volm), float((saltm - self.saltm1) / volm)))
logger.diagnostic(' Temperature var. {} change to last {}'
.format(float(vtemp / volm), float((vtemp - self.vtemp1) / volm)))
logger.diagnostic(' Salinity var. {} change to last {}'
.format(float(vsalt / volm), float((vsalt - self.vsalt1) / volm)))
self.tempm1 = tempm
self.vtemp1 = vtemp
......
......@@ -7,10 +7,6 @@ from loguru import logger
def setup_logging(loglevel='info', stream_sink=sys.stdout):
from . import runtime_state
if runtime_state.proc_rank != 0:
logger.disable('veros')
return
kwargs = {}
if sys.stdout.isatty():
kwargs.update(
......@@ -26,6 +22,7 @@ def setup_logging(loglevel='info', stream_sink=sys.stdout):