def __init__(self, scale_params, dic=None): Params.__init__(self, dic) self._scale_params = scale_params self.gamma = Parameter(2.e8, units='[J][m^-2][K^-1]', scale_object=scale_params, return_dimensional=True, description='specific heat capacity of the ground') self.C = None self.T0 = Parameter(285.0, units='[K]', scale_object=scale_params, return_dimensional=True, description="stationary solution for the 0-th order ground temperature") self.set_params(dic)
def __init__(self, scale_params, dic=None): Params.__init__(self, dic) self._scale_params = scale_params # Parameters for the atmosphere self.kd = Parameter(0.1, input_dimensional=False, scale_object=scale_params, units='[s^-1]', description="atmosphere bottom friction coefficient") self.kdp = Parameter(0.01, input_dimensional=False, scale_object=scale_params, units='[s^-1]', description="atmosphere internal friction coefficient") self.sigma = Parameter(0.2e0, input_dimensional=False, scale_object=scale_params, units='[m^2][s^-2][Pa^-2]', description="static stability of the atmosphere") self.set_params(dic)
def __init__(self, scale_params, dic=None): Params.__init__(self, dic) self._scale_params = scale_params self.gp = Parameter(3.1e-2, units='[m][s^-2]', return_dimensional=True, scale_object=scale_params, description='reduced gravity') self.r = Parameter(1.e-8, units='[s^-1]', scale_object=scale_params, description="frictional coefficient at the bottom of the ocean") self.h = Parameter(5.e2, units='[m]', return_dimensional=True, scale_object=scale_params, description="depth of the water layer of the ocean") self.d = Parameter(1.e-8, units='[s^-1]', scale_object=scale_params, description="strength of the ocean-atmosphere mechanical coupling") self.set_params(dic)
def goblocks(self, value): self._goms = value if self.atemperature_params is not None: # disable the Newtonian cooling self.atemperature_params.thetas = None # np.zeros(self.nmod[0]) self.atemperature_params.hd = None # Parameter(0.0, input_dimensional=False) self.atemperature_params.gamma = Parameter(1.e7, units='[J][m^-2][K^-1]', scale_object=self.scale_params, description='specific heat capacity of the atmosphere', return_dimensional=True) self.atemperature_params.C = np.array(self.nmod[0] * [Parameter(0.e0, units='[W][m^-2]', scale_object=self.scale_params, description="spectral components of the short-wave radiation of the atmosphere", return_dimensional=True)], dtype=object) self.atemperature_params.set_insolation(100.0, 0) self.atemperature_params.eps = Parameter(0.76e0, input_dimensional=False, description="emissivity coefficient for the grey-body atmosphere") self.atemperature_params.T0 = Parameter(270.0, units='[K]', scale_object=self.scale_params, return_dimensional=True, description="stationary solution for the 0-th order atmospheric temperature") self.atemperature_params.sc = Parameter(1., input_dimensional=False, description="ratio of surface to atmosphere temperature") self.atemperature_params.hlambda = Parameter(20.00, units='[W][m^-2][K^-1]', scale_object=self.scale_params, return_dimensional=True, description="sensible+turbulent heat exchange between ocean and atmosphere") if self.gotemperature_params is not None: # if setting an ocean, then disable the orography if self.gotemperature_params._name == "Oceanic Temperature": self._number_of_ground_modes = 0 self._number_of_oceanic_modes = self.goblocks.shape[0] self._number_of_dimensions = 2 * (self._number_of_oceanic_modes + self._number_of_atmospheric_modes) self.ground_params.hk = None self.gotemperature_params.C = np.array(self.nmod[1] * [Parameter(0.e0, units='[W][m^-2]', scale_object=self.scale_params, return_dimensional=True, description="spectral components of the short-wave radiation of the ocean")], dtype=object) else: nomod = 0 for i in range(self.goblocks.shape[0]): if self.ablocks[i, 0] == 1: nomod += 3 else: nomod += 2 self._number_of_ground_modes = nomod self._number_of_oceanic_modes = 0 self._number_of_dimensions = 2 * self._number_of_atmospheric_modes + self._number_of_ground_modes self.gotemperature_params.C = np.array(self.nmod[1] * [Parameter(0.e0, units='[W][m^-2]', scale_object=self.scale_params, return_dimensional=True, description="spectral components of the short-wave radiation of the ground")], dtype=object) self.gotemperature_params.set_insolation(350.0, 0)
def ablocks(self, value): self._ams = value namod = 0 for i in range(self.ablocks.shape[0]): if self.ablocks[i, 0] == 1: namod += 3 else: namod += 2 self._number_of_atmospheric_modes = namod self._number_of_dimensions = 2 * (namod + self._number_of_oceanic_modes) self.ground_params.hk = np.array(namod * [Parameter(0.e0, scale_object=self.scale_params, description="spectral components of the orography", return_dimensional=False, input_dimensional=False)], dtype=object) self.ground_params.set_orography(0.1, 1) if self.atemperature_params is not None: self.atemperature_params.thetas = np.array(namod * [Parameter(0.e0, scale_object=self.scale_params, description="spectral components of the temperature profile", return_dimensional=False, input_dimensional=False)], dtype=object) self.atemperature_params.set_thetas(0.1, 0)
def __init__(self, scale_params, dic=None): Params.__init__(self, dic) self._scale_params = scale_params self.hd = Parameter(0.045, input_dimensional=False, units='[s]', scale_object=scale_params, description="Newtonian cooling coefficient") self.thetas = None # Radiative equilibrium mean temperature decomposition on the model's modes self.gamma = None self.C = None self.eps = None self.T0 = None self.sc = None self.hlambda = None self.set_params(dic)
def set_insolation(self, value, pos=None): """Function to define the decomposition of the constant short-wave radiation of the ground (insolation) :math:`C_{{\\rm g}, i}` (:attr:`~.GroundTemperatureParams.C`). Parameters ---------- value: float, int or ~numpy.ndarray(Parameter) Value to set. If a scalar is given, the `pos` parameter should be provided to indicate which component to set. pos: int Indicate in which component to set the `value`. """ if isinstance(value, (float, int)) and pos is not None and self.C is not None: self.C[pos] = Parameter(value, units='[W][m^-2]', scale_object=self._scale_params, description="spectral component "+str(pos+1)+" of the short-wave radiation of the ground", return_dimensional=True) elif isinstance(value, np.ndarray): self.C = value
def set_orography(self, value, pos=None): """Function to define the spectral decomposition of the orography profile :math:`h_k` (:attr:`~.GroundParams.hk`). Parameters ---------- value: float, int or ~numpy.ndarray(Parameter) Value to set. If a scalar is given, the `pos` parameter should be provided to indicate which component to set. pos: int Indicate in which component to set the `value`. """ if isinstance(value, (float, int)) and pos is not None and self.hk is not None: self.hk[pos] = Parameter(value, scale_object=self._scale_params, description="spectral components "+str(pos+1)+" of the orography", return_dimensional=False, input_dimensional=False) elif isinstance(value, np.ndarray): self.hk = value
def set_thetas(self, value, pos=None): """Function to define the spectral decomposition of the Newtonian cooling. :math:`\\theta^\\star` (:attr:`~.AtmosphericTemperatureParams.thetas`). Parameters ---------- value: float, int or ~numpy.ndarray(Parameter) Value to set. If a scalar is given, the `pos` parameter should be provided to indicate which component to set. pos: int Indicate in which component to set the `value`. """ if isinstance(value, (float, int)) and pos is not None and self.thetas is not None: self.thetas[pos] = Parameter(value, scale_object=self._scale_params, description="spectral components "+str(pos+1)+" of the temperature profile", return_dimensional=False, input_dimensional=False) elif isinstance(value, np.ndarray): self.thetas = value
def set_params(self, dic): """Set the specified parameters values. Parameters ---------- dic: dict(float or Parameter) A dictionary with the parameters names and values to be assigned. """ if dic is not None: for key, val in zip(dic.keys(), dic.values()): if key in self.__dict__.keys(): if isinstance(self.__dict__[key], Parameter): if isinstance(val, Parameter): self.__dict__[key] = val else: d = self.__dict__[key].__dict__ self.__dict__[key] = Parameter(val, input_dimensional=d['_input_dimensional'], units=d['_units'], description=d['_description'], scale_object=d['_scale_object'], return_dimensional=d['_return_dimensional']) else: self.__dict__[key] = val
def __init__(self, dic=None): Params.__init__(self, dic) # ----------------------------------------------------------- # Scale parameters for the ocean and the atmosphere # ----------------------------------------------------------- self.scale = Parameter(5.e6, units='[m]', description="characteristic space scale (L*pi)", return_dimensional=True) self.f0 = Parameter(1.032e-4, units='[s^-1]', description="Coriolis parameter at the middle of the domain", return_dimensional=True) self.n = Parameter(1.3e0, input_dimensional=False, description="aspect ratio (n = 2 L_y / L_x)") self.rra = Parameter(6370.e3, units='[m]', description="earth radius", return_dimensional=True) self.phi0_npi = Parameter(0.25e0, input_dimensional=False, description="latitude exprimed in fraction of pi") self.deltap = Parameter(5.e4, units='[Pa]', description='pressure difference between the two atmospheric layers', return_dimensional=True) self.set_params(dic)
def set_oceanic_modes(self, nxmax, nymax, auto=True): """Function to configure contiguous spectral blocks of oceanic modes. Parameters ---------- nxmax: int Maximum x-wavenumber to fill the spectral block up to. nymax: int Maximum y-wavenumber to fill the spectral block up to. auto: bool Automatically instantiate or not the parameters container needed to describe the oceanic models parameters. Default is True. Examples -------- >>> from params.params import QgParams >>> q = QgParams() >>> q.set_atmospheric_modes(2,2) >>> q.set_oceanic_modes(2,4) >>> q.goblocks array([[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4]]) """ if self._ams is None: print('Atmosphere modes not set up. Add an atmosphere before adding an ocean!') print('Oceanic setup aborted.') return res = np.zeros((nxmax * nymax, 2), dtype=np.int) i = 0 for nx in range(1, nxmax + 1): for ny in range(1, nymax+1): res[i, 0] = nx res[i, 1] = ny i += 1 if auto: if self.gotemperature_params is None or isinstance(self.gotemperature_params, GroundTemperatureParams): self.gotemperature_params = OceanicTemperatureParams(self.scale_params) if self.oceanic_params is None: self.oceanic_params = OceanicParams(self.scale_params) self.goblocks = res # if setting an ocean, then disable the orography self.ground_params.hk = None self.gotemperature_params.C = np.array(self.nmod[0] * [Parameter(0.e0, units='[W][m^-2]', scale_object=self.scale_params, return_dimensional=True, description="spectral components of the short-wave radiation of the ocean")], dtype=object) self.gotemperature_params.set_insolation(350.0, 0) else: self.goblocks = res self._oceanic_latex_var_string = list() self._oceanic_var_string = list() self._ground_latex_var_string = list() self._ground_var_string = list() for i in range(self.nmod[1]): self._oceanic_latex_var_string.append(r'psi_{\rm o,' + str(i + 1) + "}") self._oceanic_var_string.append(r'psi_o_' + str(i + 1)) for i in range(self.nmod[1]): self._oceanic_latex_var_string.append(r'theta_{\rm o,' + str(i + 1) + "}") self._oceanic_var_string.append(r'theta_o_' + str(i + 1))
def __init__(self, dic=None, scale_params=None, atmospheric_params=True, atemperature_params=True, oceanic_params=None, otemperature_params=None, ground_params=True, gtemperature_params=None): Params.__init__(self, dic) # General scale parameters object (Mandatory param block) if scale_params is None: self.scale_params = ScaleParams(dic) else: self.scale_params = scale_params # Atmospheric parameters object if atmospheric_params is True: self.atmospheric_params = AtmosphericParams(self.scale_params, dic=dic) else: self.atmospheric_params = atmospheric_params # Atmospheric temperature parameters object if atmospheric_params is True: self.atemperature_params = AtmosphericTemperatureParams(self.scale_params, dic=dic) else: self.atemperature_params = atemperature_params if oceanic_params is True: self.oceanic_params = OceanicParams(self.scale_params, dic) else: self.oceanic_params = oceanic_params if ground_params is True: self.ground_params = GroundParams(self.scale_params, dic) else: self.ground_params = ground_params if otemperature_params is True: self.gotemperature_params = OceanicTemperatureParams(self.scale_params, dic) else: self.gotemperature_params = otemperature_params if gtemperature_params is True: self.gotemperature_params = GroundTemperatureParams(self.scale_params, dic) else: self.gotemperature_params = gtemperature_params self._number_of_dimensions = 0 self._number_of_atmospheric_modes = 0 self._number_of_oceanic_modes = 0 self._number_of_ground_modes = 0 self._ams = None self._goms = None self._atmospheric_latex_var_string = list() self._atmospheric_var_string = list() self._oceanic_latex_var_string = list() self._oceanic_var_string = list() self._ground_latex_var_string = list() self._ground_var_string = list() self.time_unit = 'days' # Physical constants self.rr = Parameter(287.058e0, return_dimensional=True, units='[J][kg^-1][K^-1]', scale_object=self.scale_params, description="gas constant of dry air") self.sb = Parameter(5.67e-8, return_dimensional=True, units='[J][m^-2][s^-1][K^-4]', scale_object=self.scale_params, description="Stefan-Boltzmann constant") self.set_params(dic)
def L(self): """Parameter: Typical length scale :math:`L` of the model, in meters [:math:`m`].""" return Parameter(self.scale / np.pi, units=self.scale.units, description='Typical length scale L', return_dimensional=True)
def L_y(self): """Parameter: The meridional extent :math:`L_y = \pi \, L` of the model's domain, in meters [:math:`m`].""" return Parameter(self.scale, units=self.scale.units, description='The meridional extent of the model domain', return_dimensional=True)
def set_ground_modes(self, nxmax=None, nymax=None, auto=True): """Function to automatically configure contiguous spectral blocks of ground modes based on the atmospheric modes. Parameters ---------- nxmax: int or None Maximum x-wavenumber to fill the spectral block up to. If None, use the atmospheric blocks instead. nymax: int or None Maximum y-wavenumber to fill the spectral block up to. If None, use the atmospheric blocks instead. auto: bool Automatically instantiate or not the parameters container needed to describe the ground models parameters. Default is True. Examples -------- >>> from params.params import QgParams >>> q = QgParams() >>> q.set_atmospheric_modes(2,4) >>> q.set_ground_modes() >>> q.goblocks array([[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4]]) """ if self._ams is None: print('Atmosphere modes not set up. Add an atmosphere before adding the ground!') print('Ground setup aborted.') return if nxmax is None or nymax is None: res = self._ams.copy() else: res = np.zeros((nxmax * nymax, 2), dtype=np.int) i = 0 for nx in range(1, nxmax + 1): for ny in range(1, nymax+1): res[i, 0] = nx res[i, 1] = ny i += 1 if auto: if self.gotemperature_params is None or isinstance(self.gotemperature_params, OceanicTemperatureParams): self.gotemperature_params = GroundTemperatureParams(self.scale_params) if self.ground_params is None: self.ground_params = GroundParams(self.scale_params) self.oceanic_params = None self.goblocks = res self.gotemperature_params.C = np.array(self.nmod[0] * [Parameter(0.e0, units='[W][m^-2]', scale_object=self.scale_params, return_dimensional=True, description="spectral components of the short-wave radiation of the ocean")], dtype=object) self.gotemperature_params.set_insolation(350.0, 0) # if orography is disabled, enable it! if self.ground_params.hk is None: self.ground_params.hk = np.array(self.nmod[0] * [Parameter(0.e0, scale_object=self.scale_params, description="spectral components of the orography", return_dimensional=False, input_dimensional=False)], dtype=object) self.ground_params.set_orography(0.1, 1) else: self.goblocks = res self._oceanic_var_string = list() self._oceanic_latex_var_string = list() self._ground_latex_var_string = list() self._ground_var_string = list() for i in range(self.nmod[1]): self._ground_latex_var_string.append(r'theta_{\rm g,' + str(i + 1) + "}") self._ground_var_string.append(r'theta_g_' + str(i + 1))
def sig0(self): return Parameter(self.sigma / 2, input_dimensional=False, scale_object=self._scale_params, units='[m^2][s^-2][Pa^-2]', description="0.5 * static stability of the atmosphere")
def L_x(self): """Parameter: The zonal extent :math:`L_x = 2 \pi \, L / n` of the model's domain, in meters [:math:`m`].""" return Parameter(2 * self.scale / self.n, units=self.scale.units, description='The zonal extent of the model domain', return_dimensional=True)
def beta(self): """Parameter: The meridional gradient of the Coriolis parameter at :math:`\phi_0`, expressed in [:math:`m^{-1} s^{-1}`]. """ return Parameter(self.L / self.rra * np.cos(self.phi0) / np.sin(self.phi0), input_dimensional=False, units='[m^-1][s^-1]', scale_object=self, description="Meridional gradient of the Coriolis parameter at phi_0")
def phi0(self): """Parameter: The reference latitude :math:`\phi_0` at the center of the domain, expressed in radians [:math:`rad`].""" return Parameter(self.phi0_npi * np.pi, units='[rad]', description="The reference latitude of the center of the domain", return_dimensional=True)