Source code for taurex.data.profiles.pressure.pressureprofile

from taurex.log import Logger
from taurex.data.fittable import fitparam, Fittable
import numpy as np
from taurex.output.writeable import Writeable
import math
from taurex.data.citation import Citable

[docs]class PressureProfile(Fittable, Logger, Writeable, Citable): """ *Abstract Class* Base pressure class. Simple. Defines the layering of the atmosphere. Only requires implementation of: - :func:`compute_pressure_profile` - :func:`profile` Parameters ---------- name: str Name used in logging nlayers: int Number of layers in atmosphere """ def __init__(self, name, nlayers): Fittable.__init__(self) Logger.__init__(self, name) if nlayers <= 0: self.error('Number of layers: [%s] should be greater than 0', nlayers) raise ValueError('Number of layers should be at least 1') self._nlayers = int(nlayers) @property def nLayers(self): """ Number of layers Returns ------- int """ return self._nlayers @property def nLevels(self): return self.nLayers + 1
[docs] def compute_pressure_profile(self): """ **Requires implementation** Compute pressure profile and generate pressure array in Pa Returns ------- pressure_profile: :obj:`array` Pressure profile array in Pa """ raise NotImplementedError
@property def profile(self): """ Returns pressure at each atmospheric layer (Pascal) Returns ------- pressure_profile : :obj:`array` """ raise NotImplementedError
[docs] def write(self, output): pressure = output.create_group('Pressure') pressure.write_string('pressure_type', self.__class__.__name__) pressure.write_scalar('nlayers', self._nlayers) pressure.write_array('profile', self.profile) return pressure
[docs]class SimplePressureProfile(PressureProfile): """ A basic pressure profile. Parameters ---------- nlayers : int Number of layers in atmosphere atm_min_pressure : float minimum pressure in Pascal (top of atmosphere) atm_max_pressure : float maximum pressure in Pascal (surface of planet) """ def __init__(self, nlayers=100, atm_min_pressure=1e-4, atm_max_pressure=1e6): super().__init__('pressure_profile', nlayers) self.pressure_profile = None if atm_max_pressure < atm_min_pressure: self.error('Max pressure %1.2e should be greater ' 'than min pressure %1.2e', atm_max_pressure, atm_min_pressure) raise ValueError('Max pressure is less than minimum pressure') self._atm_min_pressure = atm_min_pressure self._atm_max_pressure = atm_max_pressure
[docs] def compute_pressure_profile(self): """ Sets up the pressure profile for the atmosphere model """ # set pressure profile of layer boundaries # press_exp = np.linspace(np.log(self._atm_min_pressure), # np.log(self._atm_max_pressure), # self.nLevels) # self.pressure_profile_levels = np.exp(press_exp)[::-1] self.pressure_profile_levels = \ np.logspace(math.log10(self._atm_min_pressure), math.log10(self._atm_max_pressure), self.nLevels)[::-1] # get mid point pressure between levels (i.e. get layer pressure) # computing geometric # average between pressure at n and n+1 level self.pressure_profile = self.pressure_profile_levels[:-1] * \ np.sqrt(self.pressure_profile_levels[1:] / self.pressure_profile_levels[:-1])
@fitparam(param_name='atm_min_pressure', param_latex='$P_\mathrm{min}$', default_mode='log', default_fit=False, default_bounds=[0.1, 1.0]) def minAtmospherePressure(self): """Minimum pressure of atmosphere (top layer) in Pascal""" return self._atm_min_pressure @minAtmospherePressure.setter def minAtmospherePressure(self, value): self._atm_min_pressure = value @fitparam(param_name='atm_max_pressure', param_latex='$P_\\mathrm{max}$', default_mode='log', default_fit=False, default_bounds=[0.1, 1.0]) def maxAtmospherePressure(self): """Maximum pressure of atmosphere (surface) in Pascal""" return self._atm_max_pressure @maxAtmospherePressure.setter def maxAtmospherePressure(self, value): self._atm_max_pressure = value @property def profile(self): return self.pressure_profile
[docs] def write(self, output): pressure = super().write(output) pressure.write_scalar('atm_max_pressure', self._atm_max_pressure) pressure.write_scalar('atm_min_pressure', self._atm_min_pressure) return pressure
[docs] @classmethod def input_keywords(self): return ['simple', 'hydrostatic', ]