PySDM_examples.Grabowski_and_Pawlowska_2023.settings

  1import numpy as np
  2from pystrict import strict
  3
  4from PySDM import Formulae
  5from PySDM.dynamics import condensation
  6from PySDM.initialisation.spectra import Lognormal, Sum
  7from PySDM.physics import si
  8
  9condensation_tolerance = condensation.DEFAULTS.rtol_thd / 100
 10
 11
 12@strict
 13class Settings:
 14    def __init__(
 15        self,
 16        *,
 17        aerosol: str,
 18        vertical_velocity: float,
 19        dt: float,
 20        n_sd: int,
 21        initial_temperature: float = 283 * si.K,
 22        initial_pressure: float = 900 * si.mbar,
 23        initial_relative_humidity: float = 0.97,
 24        displacement: float = 1000 * si.m,
 25        mass_accommodation_coefficient: float = 0.3,
 26        rtol_thd: float = condensation_tolerance,
 27        rtol_x: float = condensation_tolerance,
 28    ):
 29        self.formulae = Formulae(constants={"MAC": mass_accommodation_coefficient})
 30        self.n_sd = n_sd
 31        self.aerosol_modes_by_kappa = {
 32            "pristine": {
 33                1.28: Sum(
 34                    (
 35                        Lognormal(
 36                            norm_factor=125 / si.cm**3, m_mode=11 * si.nm, s_geom=1.2
 37                        ),
 38                        Lognormal(
 39                            norm_factor=65 / si.cm**3, m_mode=60 * si.nm, s_geom=1.7
 40                        ),
 41                    )
 42                )
 43            },
 44            "polluted": {
 45                1.28: Sum(
 46                    (
 47                        Lognormal(
 48                            norm_factor=160 / si.cm**3, m_mode=29 * si.nm, s_geom=1.36
 49                        ),
 50                        Lognormal(
 51                            norm_factor=380 / si.cm**3, m_mode=71 * si.nm, s_geom=1.57
 52                        ),
 53                    )
 54                )
 55            },
 56        }[aerosol]
 57
 58        self.vertical_velocity = vertical_velocity
 59        self.initial_pressure = initial_pressure
 60        self.initial_temperature = initial_temperature
 61        self.initial_relative_humidity = initial_relative_humidity
 62        self.t_max = displacement / vertical_velocity
 63        self.timestep = dt
 64        self.output_interval = self.timestep
 65        self.rtol_thd = rtol_thd
 66        self.rtol_x = rtol_x
 67
 68        self.initial_vapour_mixing_ratio = (
 69            self.formulae.trivia.water_vapour_mixing_ratio(
 70                self.initial_pressure,
 71                self.initial_relative_humidity,
 72                self.formulae.saturation_vapour_pressure.pvs_water(
 73                    self.initial_temperature
 74                ),
 75            )
 76        )
 77
 78    @property
 79    def initial_air_density(self):
 80        const = self.formulae.constants
 81        dry_air_density = (
 82            self.formulae.trivia.p_d(
 83                self.initial_pressure, self.initial_vapour_mixing_ratio
 84            )
 85            / self.initial_temperature
 86            / const.Rd
 87        )
 88        return dry_air_density * (1 + self.initial_vapour_mixing_ratio)
 89
 90    @property
 91    def nt(self) -> int:
 92        nt = self.t_max / self.timestep
 93        nt_int = round(nt)
 94        np.testing.assert_almost_equal(nt, nt_int)
 95        return nt_int
 96
 97    @property
 98    def steps_per_output_interval(self) -> int:
 99        return int(self.output_interval / self.timestep)
100
101    @property
102    def output_steps(self) -> np.ndarray:
103        return np.arange(0, self.nt + 1, self.steps_per_output_interval)
condensation_tolerance = 1e-08
@strict
class Settings:
 13@strict
 14class Settings:
 15    def __init__(
 16        self,
 17        *,
 18        aerosol: str,
 19        vertical_velocity: float,
 20        dt: float,
 21        n_sd: int,
 22        initial_temperature: float = 283 * si.K,
 23        initial_pressure: float = 900 * si.mbar,
 24        initial_relative_humidity: float = 0.97,
 25        displacement: float = 1000 * si.m,
 26        mass_accommodation_coefficient: float = 0.3,
 27        rtol_thd: float = condensation_tolerance,
 28        rtol_x: float = condensation_tolerance,
 29    ):
 30        self.formulae = Formulae(constants={"MAC": mass_accommodation_coefficient})
 31        self.n_sd = n_sd
 32        self.aerosol_modes_by_kappa = {
 33            "pristine": {
 34                1.28: Sum(
 35                    (
 36                        Lognormal(
 37                            norm_factor=125 / si.cm**3, m_mode=11 * si.nm, s_geom=1.2
 38                        ),
 39                        Lognormal(
 40                            norm_factor=65 / si.cm**3, m_mode=60 * si.nm, s_geom=1.7
 41                        ),
 42                    )
 43                )
 44            },
 45            "polluted": {
 46                1.28: Sum(
 47                    (
 48                        Lognormal(
 49                            norm_factor=160 / si.cm**3, m_mode=29 * si.nm, s_geom=1.36
 50                        ),
 51                        Lognormal(
 52                            norm_factor=380 / si.cm**3, m_mode=71 * si.nm, s_geom=1.57
 53                        ),
 54                    )
 55                )
 56            },
 57        }[aerosol]
 58
 59        self.vertical_velocity = vertical_velocity
 60        self.initial_pressure = initial_pressure
 61        self.initial_temperature = initial_temperature
 62        self.initial_relative_humidity = initial_relative_humidity
 63        self.t_max = displacement / vertical_velocity
 64        self.timestep = dt
 65        self.output_interval = self.timestep
 66        self.rtol_thd = rtol_thd
 67        self.rtol_x = rtol_x
 68
 69        self.initial_vapour_mixing_ratio = (
 70            self.formulae.trivia.water_vapour_mixing_ratio(
 71                self.initial_pressure,
 72                self.initial_relative_humidity,
 73                self.formulae.saturation_vapour_pressure.pvs_water(
 74                    self.initial_temperature
 75                ),
 76            )
 77        )
 78
 79    @property
 80    def initial_air_density(self):
 81        const = self.formulae.constants
 82        dry_air_density = (
 83            self.formulae.trivia.p_d(
 84                self.initial_pressure, self.initial_vapour_mixing_ratio
 85            )
 86            / self.initial_temperature
 87            / const.Rd
 88        )
 89        return dry_air_density * (1 + self.initial_vapour_mixing_ratio)
 90
 91    @property
 92    def nt(self) -> int:
 93        nt = self.t_max / self.timestep
 94        nt_int = round(nt)
 95        np.testing.assert_almost_equal(nt, nt_int)
 96        return nt_int
 97
 98    @property
 99    def steps_per_output_interval(self) -> int:
100        return int(self.output_interval / self.timestep)
101
102    @property
103    def output_steps(self) -> np.ndarray:
104        return np.arange(0, self.nt + 1, self.steps_per_output_interval)
Settings( *, aerosol: str, vertical_velocity: float, dt: float, n_sd: int, initial_temperature: float = 283.0, initial_pressure: float = 90000.0, initial_relative_humidity: float = 0.97, displacement: float = 1000.0, mass_accommodation_coefficient: float = 0.3, rtol_thd: float = 1e-08, rtol_x: float = 1e-08)
15    def __init__(
16        self,
17        *,
18        aerosol: str,
19        vertical_velocity: float,
20        dt: float,
21        n_sd: int,
22        initial_temperature: float = 283 * si.K,
23        initial_pressure: float = 900 * si.mbar,
24        initial_relative_humidity: float = 0.97,
25        displacement: float = 1000 * si.m,
26        mass_accommodation_coefficient: float = 0.3,
27        rtol_thd: float = condensation_tolerance,
28        rtol_x: float = condensation_tolerance,
29    ):
30        self.formulae = Formulae(constants={"MAC": mass_accommodation_coefficient})
31        self.n_sd = n_sd
32        self.aerosol_modes_by_kappa = {
33            "pristine": {
34                1.28: Sum(
35                    (
36                        Lognormal(
37                            norm_factor=125 / si.cm**3, m_mode=11 * si.nm, s_geom=1.2
38                        ),
39                        Lognormal(
40                            norm_factor=65 / si.cm**3, m_mode=60 * si.nm, s_geom=1.7
41                        ),
42                    )
43                )
44            },
45            "polluted": {
46                1.28: Sum(
47                    (
48                        Lognormal(
49                            norm_factor=160 / si.cm**3, m_mode=29 * si.nm, s_geom=1.36
50                        ),
51                        Lognormal(
52                            norm_factor=380 / si.cm**3, m_mode=71 * si.nm, s_geom=1.57
53                        ),
54                    )
55                )
56            },
57        }[aerosol]
58
59        self.vertical_velocity = vertical_velocity
60        self.initial_pressure = initial_pressure
61        self.initial_temperature = initial_temperature
62        self.initial_relative_humidity = initial_relative_humidity
63        self.t_max = displacement / vertical_velocity
64        self.timestep = dt
65        self.output_interval = self.timestep
66        self.rtol_thd = rtol_thd
67        self.rtol_x = rtol_x
68
69        self.initial_vapour_mixing_ratio = (
70            self.formulae.trivia.water_vapour_mixing_ratio(
71                self.initial_pressure,
72                self.initial_relative_humidity,
73                self.formulae.saturation_vapour_pressure.pvs_water(
74                    self.initial_temperature
75                ),
76            )
77        )
formulae
n_sd
aerosol_modes_by_kappa
vertical_velocity
initial_pressure
initial_temperature
initial_relative_humidity
t_max
timestep
output_interval
rtol_thd
rtol_x
initial_vapour_mixing_ratio
initial_air_density
79    @property
80    def initial_air_density(self):
81        const = self.formulae.constants
82        dry_air_density = (
83            self.formulae.trivia.p_d(
84                self.initial_pressure, self.initial_vapour_mixing_ratio
85            )
86            / self.initial_temperature
87            / const.Rd
88        )
89        return dry_air_density * (1 + self.initial_vapour_mixing_ratio)
nt: int
91    @property
92    def nt(self) -> int:
93        nt = self.t_max / self.timestep
94        nt_int = round(nt)
95        np.testing.assert_almost_equal(nt, nt_int)
96        return nt_int
steps_per_output_interval: int
 98    @property
 99    def steps_per_output_interval(self) -> int:
100        return int(self.output_interval / self.timestep)
output_steps: numpy.ndarray
102    @property
103    def output_steps(self) -> np.ndarray:
104        return np.arange(0, self.nt + 1, self.steps_per_output_interval)