Source code for fridom.nonhydro.model_settings
from fridom.framework.grid.grid_base import GridBase
import fridom.nonhydro as nh
from functools import partial
# Import external modules
from typing import TYPE_CHECKING
# Import internal modules
from fridom.framework import config, utils
from fridom.framework.field_variable import FieldVariable
from fridom.framework.model_settings_base import ModelSettingsBase
# Import type information
if TYPE_CHECKING:
from fridom.framework.grid.grid_base import GridBase
from numpy import ndarray
[docs]
@partial(utils.jaxify, dynamic=("f_coriolis", "N2", "dsqr", "Ro"))
class ModelSettings(ModelSettingsBase):
"""
Model settings for the 3D non-hydrostatic model.
Parameters
----------
`grid` : `Grid`
The grid object.
"""
model_name = "3D - Nonhydrostatic model"
[docs]
def __init__(self, grid: GridBase, **kwargs) -> None:
super().__init__(grid)
# Set standard parameters
self.tendencies = nh.modules.MainTendency()
self._f0 = 1 # constant coriolis parameter f0
self._beta = 0 # beta term d(f)/dy
self._f_coriolis = None # the coriolis parameter field
self._N2 = 1 # stratification N²
self._N2_field = None # stratification N² field
self._dsqr = 1 # aspect ratio
self._Ro = 1 # Rossby number
# Finally, set attributes from keyword arguments
self.set_attributes(**kwargs)
[docs]
def setup_settings_parameters(self):
# Coriolis parameter
f_coriolis = FieldVariable(
self,
name="f",
long_name="Coriolis parameter",
units="1/s",
position=self.grid.cell_center,
topo=[False, True, False],
)
f_coriolis[:] = self._f0 + self._beta * self.grid.X[1][None,0,:,0,None]
self._f_coriolis = f_coriolis
# make sure that the advection term is scaled by the Rossby number
self.tendencies.advection.scaling = self.Ro
return
[docs]
def state_constructor(self):
from fridom.nonhydro.state import State
return State(self, is_spectral=self.grid.spectral_grid)
[docs]
def diagnostic_state_constructor(self):
from fridom.nonhydro.state import DiagnosticState
return DiagnosticState(self, is_spectral=self.grid.spectral_grid)
# ================================================================
# Properties
# ================================================================
@property
def parameters(self) -> dict:
res = super().parameters
res["coriolis parameter f0"] = f"{self.f0} 1/s"
res["beta term"] = f"{self.beta} 1/(m*s)"
res["Stratification N²"] = f"{self.N2} 1/s^2"
res["Aspect ratio dsqr"] = f"{self.dsqr}"
res["Rossby number Ro"] = f"{self.Ro}"
return res
@property
def f0(self) -> 'float':
"""The constant term of the Coriolis parameter (f=f0 + beta*y)."""
return self._f0
@f0.setter
def f0(self, value: 'float'):
self._f0 = value
if self._f_coriolis is not None:
self.f_coriolis[:] = self._f0 + self._beta * self.grid.X[1][None,:,None]
return
@property
def beta(self) -> 'float':
"""The beta term of the Coriolis parameter (f=f0 + beta*y)."""
return self._beta
@beta.setter
def beta(self, value: 'float'):
self._beta = value
if self._f_coriolis is not None:
self.f_coriolis[:] = self._f0 + self._beta * self.grid.X[1][None,:,None]
return
@property
def f_coriolis(self) -> 'FieldVariable':
"""The Coriolis parameter (f=f0 + beta*y)."""
return self._f_coriolis
@f_coriolis.setter
def f_coriolis(self, value: 'FieldVariable | float | ndarray'):
if isinstance(value, FieldVariable):
self._f_coriolis = value
else:
self._f_coriolis[:] = value
return
@property
def N2(self) -> 'float':
"""The stratification N²."""
return self._N2
@N2.setter
def N2(self, value: 'float'):
self._N2 = value
return
@property
def Ro(self) -> 'float':
"""The Rossby number."""
return self._Ro
@Ro.setter
def Ro(self, value: 'float'):
self._Ro = value
# scale the advection term
self.tendencies.advection.scaling = value
return
@property
def dsqr(self) -> 'float':
r"""The aspect ratio. :math:`\delta^2`."""
return self._dsqr
@dsqr.setter
def dsqr(self, value: 'float'):
self._dsqr = value
return