PySDM_examples.Lowe_et_al_2019.settings

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