PySDM_examples.Lowe_et_al_2019.settings
1import numpy as np 2from PySDM_examples.Lowe_et_al_2019.constants_def import LOWE_CONSTS 3from pystrict import strict 4 5from PySDM import Formulae 6from PySDM.initialisation.aerosol_composition import DryAerosolMixture 7from PySDM.initialisation.sampling import spectral_sampling as spec_sampling 8from PySDM.physics import si 9 10 11@strict 12class Settings: 13 def __init__( 14 self, 15 dz: float, 16 n_sd_per_mode: int, 17 aerosol: DryAerosolMixture, 18 model: str, 19 spectral_sampling: type(spec_sampling.SpectralSampling), 20 w: float = 0.32 * si.m / si.s, 21 ): 22 assert model in ("Constant", "CompressedFilmOvadnevaite") 23 self.model = model 24 self.n_sd_per_mode = n_sd_per_mode 25 self.formulae = Formulae( 26 surface_tension=model, 27 constants=LOWE_CONSTS, 28 diffusion_kinetics="LoweEtAl2019", 29 diffusion_thermics="LoweEtAl2019", 30 latent_heat="Lowe2019", 31 saturation_vapour_pressure="Lowe1977", 32 optical_albedo="Bohren1987", 33 optical_depth="Stephens1978", 34 ) 35 const = self.formulae.constants 36 self.aerosol = aerosol 37 self.spectral_sampling = spectral_sampling 38 39 max_altitude = 200 * si.m 40 self.w = w 41 self.t_max = max_altitude / self.w 42 self.dt = dz / self.w 43 self.output_interval = 1 * self.dt 44 45 self.p0 = 980 * si.mbar 46 self.T0 = 280 * si.K 47 pv0 = 0.999 * self.formulae.saturation_vapour_pressure.pvs_water(self.T0) 48 self.initial_water_vapour_mixing_ratio = const.eps * pv0 / (self.p0 - pv0) 49 50 self.cloud_radius_range = (0.5 * si.micrometre, np.inf) 51 52 self.mass_of_dry_air = 44 53 54 self.wet_radius_bins_edges = np.logspace( 55 np.log10(4 * si.um), np.log10(12 * si.um), 128 + 1, endpoint=True 56 ) 57 58 @property 59 def rho0(self): 60 const = self.formulae.constants 61 rhod0 = ( 62 self.formulae.trivia.p_d(self.p0, self.initial_water_vapour_mixing_ratio) 63 / self.T0 64 / const.Rd 65 ) 66 return rhod0 * (1 + self.initial_water_vapour_mixing_ratio) 67 68 @property 69 def nt(self) -> int: 70 nt = self.t_max / self.dt 71 nt_int = round(nt) 72 np.testing.assert_almost_equal(nt, nt_int) 73 return nt_int 74 75 @property 76 def steps_per_output_interval(self) -> int: 77 return int(self.output_interval / self.dt) 78 79 @property 80 def output_steps(self) -> np.ndarray: 81 return np.arange(0, self.nt + 1, self.steps_per_output_interval)
@strict
class
Settings:
12@strict 13class Settings: 14 def __init__( 15 self, 16 dz: float, 17 n_sd_per_mode: int, 18 aerosol: DryAerosolMixture, 19 model: str, 20 spectral_sampling: type(spec_sampling.SpectralSampling), 21 w: float = 0.32 * si.m / si.s, 22 ): 23 assert model in ("Constant", "CompressedFilmOvadnevaite") 24 self.model = model 25 self.n_sd_per_mode = n_sd_per_mode 26 self.formulae = Formulae( 27 surface_tension=model, 28 constants=LOWE_CONSTS, 29 diffusion_kinetics="LoweEtAl2019", 30 diffusion_thermics="LoweEtAl2019", 31 latent_heat="Lowe2019", 32 saturation_vapour_pressure="Lowe1977", 33 optical_albedo="Bohren1987", 34 optical_depth="Stephens1978", 35 ) 36 const = self.formulae.constants 37 self.aerosol = aerosol 38 self.spectral_sampling = spectral_sampling 39 40 max_altitude = 200 * si.m 41 self.w = w 42 self.t_max = max_altitude / self.w 43 self.dt = dz / self.w 44 self.output_interval = 1 * self.dt 45 46 self.p0 = 980 * si.mbar 47 self.T0 = 280 * si.K 48 pv0 = 0.999 * self.formulae.saturation_vapour_pressure.pvs_water(self.T0) 49 self.initial_water_vapour_mixing_ratio = const.eps * pv0 / (self.p0 - pv0) 50 51 self.cloud_radius_range = (0.5 * si.micrometre, np.inf) 52 53 self.mass_of_dry_air = 44 54 55 self.wet_radius_bins_edges = np.logspace( 56 np.log10(4 * si.um), np.log10(12 * si.um), 128 + 1, endpoint=True 57 ) 58 59 @property 60 def rho0(self): 61 const = self.formulae.constants 62 rhod0 = ( 63 self.formulae.trivia.p_d(self.p0, self.initial_water_vapour_mixing_ratio) 64 / self.T0 65 / const.Rd 66 ) 67 return rhod0 * (1 + self.initial_water_vapour_mixing_ratio) 68 69 @property 70 def nt(self) -> int: 71 nt = self.t_max / self.dt 72 nt_int = round(nt) 73 np.testing.assert_almost_equal(nt, nt_int) 74 return nt_int 75 76 @property 77 def steps_per_output_interval(self) -> int: 78 return int(self.output_interval / self.dt) 79 80 @property 81 def output_steps(self) -> np.ndarray: 82 return np.arange(0, self.nt + 1, self.steps_per_output_interval)
Settings( dz: float, n_sd_per_mode: int, aerosol: PySDM.initialisation.aerosol_composition.dry_aerosol.DryAerosolMixture, model: str, spectral_sampling: type, w: float = 0.32)
14 def __init__( 15 self, 16 dz: float, 17 n_sd_per_mode: int, 18 aerosol: DryAerosolMixture, 19 model: str, 20 spectral_sampling: type(spec_sampling.SpectralSampling), 21 w: float = 0.32 * si.m / si.s, 22 ): 23 assert model in ("Constant", "CompressedFilmOvadnevaite") 24 self.model = model 25 self.n_sd_per_mode = n_sd_per_mode 26 self.formulae = Formulae( 27 surface_tension=model, 28 constants=LOWE_CONSTS, 29 diffusion_kinetics="LoweEtAl2019", 30 diffusion_thermics="LoweEtAl2019", 31 latent_heat="Lowe2019", 32 saturation_vapour_pressure="Lowe1977", 33 optical_albedo="Bohren1987", 34 optical_depth="Stephens1978", 35 ) 36 const = self.formulae.constants 37 self.aerosol = aerosol 38 self.spectral_sampling = spectral_sampling 39 40 max_altitude = 200 * si.m 41 self.w = w 42 self.t_max = max_altitude / self.w 43 self.dt = dz / self.w 44 self.output_interval = 1 * self.dt 45 46 self.p0 = 980 * si.mbar 47 self.T0 = 280 * si.K 48 pv0 = 0.999 * self.formulae.saturation_vapour_pressure.pvs_water(self.T0) 49 self.initial_water_vapour_mixing_ratio = const.eps * pv0 / (self.p0 - pv0) 50 51 self.cloud_radius_range = (0.5 * si.micrometre, np.inf) 52 53 self.mass_of_dry_air = 44 54 55 self.wet_radius_bins_edges = np.logspace( 56 np.log10(4 * si.um), np.log10(12 * si.um), 128 + 1, endpoint=True 57 )