PySDM_examples.Arabas_and_Shima_2017.simulation

  1import numpy as np
  2
  3import PySDM.products as PySDM_products
  4from PySDM import Particulator
  5from PySDM.backends import Numba
  6from PySDM.dynamics import AmbientThermodynamics, Condensation
  7from PySDM.environments import Parcel
  8from PySDM.initialisation.hygroscopic_equilibrium import equilibrate_wet_radii
  9from PySDM.physics import constants as const
 10
 11
 12class Simulation:
 13    def __init__(self, settings, backend=Numba):
 14        t_half = settings.z_half / settings.w_avg
 15
 16        dt_output = (2 * t_half) / settings.n_output
 17        self.n_substeps = 1
 18        while dt_output / self.n_substeps >= settings.dt_max:  # TODO #334 dt_max
 19            self.n_substeps += 1
 20
 21        attributes = {}
 22        r_dry = np.array([settings.r_dry])
 23        attributes["dry volume"] = settings.formulae.trivia.volume(radius=r_dry)
 24        attributes["kappa times dry volume"] = attributes["dry volume"] * settings.kappa
 25        attributes["multiplicity"] = np.array([settings.n_in_dv], dtype=np.int64)
 26        environment = Parcel(
 27            dt=dt_output / self.n_substeps,
 28            mass_of_dry_air=settings.mass_of_dry_air,
 29            p0=settings.p0,
 30            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 31            T0=settings.T0,
 32            w=settings.w,
 33            backend=backend(
 34                formulae=settings.formulae,
 35                **(
 36                    {"override_jit_flags": {"parallel": False}}
 37                    if backend is Numba
 38                    else {}
 39                ),
 40            ),
 41        )
 42        r_wet = equilibrate_wet_radii(
 43            r_dry=r_dry,
 44            environment=environment,
 45            kappa_times_dry_volume=attributes["kappa times dry volume"],
 46        )
 47        attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet)
 48        products = [
 49            PySDM_products.MeanRadius(name="radius_m1", unit="um"),
 50            PySDM_products.CondensationTimestepMin(name="dt_cond_min"),
 51            PySDM_products.ParcelDisplacement(name="z"),
 52            PySDM_products.AmbientRelativeHumidity(name="RH"),
 53            PySDM_products.PeakSaturation(name="S_max"),
 54            PySDM_products.Time(name="t"),
 55            PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"),
 56            PySDM_products.DeactivatingRate(
 57                unit="s^-1 mg^-1", name="deactivating_rate"
 58            ),
 59            PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"),
 60        ]
 61
 62        self.particulator = Particulator(
 63            n_sd=1,
 64            dynamics=[
 65                AmbientThermodynamics(),
 66                Condensation(
 67                    rtol_x=settings.rtol_x,
 68                    rtol_thd=settings.rtol_thd,
 69                    dt_cond_range=settings.dt_cond_range,
 70                ),
 71            ],
 72            attributes=attributes,
 73            products=products,
 74            environment=environment,
 75        )
 76
 77        self.n_output = settings.n_output
 78
 79    def save(self, output):
 80        cell_id = 0
 81        output["r"].append(
 82            self.particulator.products["radius_m1"].get(unit=const.si.m)[cell_id]
 83        )
 84        output["dt_cond_min"].append(
 85            self.particulator.products["dt_cond_min"].get()[cell_id]
 86        )
 87        output["z"].append(self.particulator.products["z"].get()[cell_id])
 88        output["RH"].append(self.particulator.products["RH"].get()[cell_id])
 89        output["t"].append(self.particulator.products["t"].get())
 90
 91        for event in ("activating", "deactivating", "ripening"):
 92            output[event + "_rate"].append(
 93                self.particulator.products[event + "_rate"].get()[cell_id]
 94            )
 95
 96    def run(self):
 97        output = {
 98            "r": [],
 99            "RH": [],
100            "z": [],
101            "t": [],
102            "dt_cond_min": [],
103            "activating_rate": [],
104            "deactivating_rate": [],
105            "ripening_rate": [],
106        }
107
108        self.save(output)
109        for _ in range(self.n_output):
110            self.particulator.run(self.n_substeps)
111            self.save(output)
112
113        return output
class Simulation:
 13class Simulation:
 14    def __init__(self, settings, backend=Numba):
 15        t_half = settings.z_half / settings.w_avg
 16
 17        dt_output = (2 * t_half) / settings.n_output
 18        self.n_substeps = 1
 19        while dt_output / self.n_substeps >= settings.dt_max:  # TODO #334 dt_max
 20            self.n_substeps += 1
 21
 22        attributes = {}
 23        r_dry = np.array([settings.r_dry])
 24        attributes["dry volume"] = settings.formulae.trivia.volume(radius=r_dry)
 25        attributes["kappa times dry volume"] = attributes["dry volume"] * settings.kappa
 26        attributes["multiplicity"] = np.array([settings.n_in_dv], dtype=np.int64)
 27        environment = Parcel(
 28            dt=dt_output / self.n_substeps,
 29            mass_of_dry_air=settings.mass_of_dry_air,
 30            p0=settings.p0,
 31            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 32            T0=settings.T0,
 33            w=settings.w,
 34            backend=backend(
 35                formulae=settings.formulae,
 36                **(
 37                    {"override_jit_flags": {"parallel": False}}
 38                    if backend is Numba
 39                    else {}
 40                ),
 41            ),
 42        )
 43        r_wet = equilibrate_wet_radii(
 44            r_dry=r_dry,
 45            environment=environment,
 46            kappa_times_dry_volume=attributes["kappa times dry volume"],
 47        )
 48        attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet)
 49        products = [
 50            PySDM_products.MeanRadius(name="radius_m1", unit="um"),
 51            PySDM_products.CondensationTimestepMin(name="dt_cond_min"),
 52            PySDM_products.ParcelDisplacement(name="z"),
 53            PySDM_products.AmbientRelativeHumidity(name="RH"),
 54            PySDM_products.PeakSaturation(name="S_max"),
 55            PySDM_products.Time(name="t"),
 56            PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"),
 57            PySDM_products.DeactivatingRate(
 58                unit="s^-1 mg^-1", name="deactivating_rate"
 59            ),
 60            PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"),
 61        ]
 62
 63        self.particulator = Particulator(
 64            n_sd=1,
 65            dynamics=[
 66                AmbientThermodynamics(),
 67                Condensation(
 68                    rtol_x=settings.rtol_x,
 69                    rtol_thd=settings.rtol_thd,
 70                    dt_cond_range=settings.dt_cond_range,
 71                ),
 72            ],
 73            attributes=attributes,
 74            products=products,
 75            environment=environment,
 76        )
 77
 78        self.n_output = settings.n_output
 79
 80    def save(self, output):
 81        cell_id = 0
 82        output["r"].append(
 83            self.particulator.products["radius_m1"].get(unit=const.si.m)[cell_id]
 84        )
 85        output["dt_cond_min"].append(
 86            self.particulator.products["dt_cond_min"].get()[cell_id]
 87        )
 88        output["z"].append(self.particulator.products["z"].get()[cell_id])
 89        output["RH"].append(self.particulator.products["RH"].get()[cell_id])
 90        output["t"].append(self.particulator.products["t"].get())
 91
 92        for event in ("activating", "deactivating", "ripening"):
 93            output[event + "_rate"].append(
 94                self.particulator.products[event + "_rate"].get()[cell_id]
 95            )
 96
 97    def run(self):
 98        output = {
 99            "r": [],
100            "RH": [],
101            "z": [],
102            "t": [],
103            "dt_cond_min": [],
104            "activating_rate": [],
105            "deactivating_rate": [],
106            "ripening_rate": [],
107        }
108
109        self.save(output)
110        for _ in range(self.n_output):
111            self.particulator.run(self.n_substeps)
112            self.save(output)
113
114        return output
Simulation(settings, backend=<class 'PySDM.backends.Numba'>)
14    def __init__(self, settings, backend=Numba):
15        t_half = settings.z_half / settings.w_avg
16
17        dt_output = (2 * t_half) / settings.n_output
18        self.n_substeps = 1
19        while dt_output / self.n_substeps >= settings.dt_max:  # TODO #334 dt_max
20            self.n_substeps += 1
21
22        attributes = {}
23        r_dry = np.array([settings.r_dry])
24        attributes["dry volume"] = settings.formulae.trivia.volume(radius=r_dry)
25        attributes["kappa times dry volume"] = attributes["dry volume"] * settings.kappa
26        attributes["multiplicity"] = np.array([settings.n_in_dv], dtype=np.int64)
27        environment = Parcel(
28            dt=dt_output / self.n_substeps,
29            mass_of_dry_air=settings.mass_of_dry_air,
30            p0=settings.p0,
31            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
32            T0=settings.T0,
33            w=settings.w,
34            backend=backend(
35                formulae=settings.formulae,
36                **(
37                    {"override_jit_flags": {"parallel": False}}
38                    if backend is Numba
39                    else {}
40                ),
41            ),
42        )
43        r_wet = equilibrate_wet_radii(
44            r_dry=r_dry,
45            environment=environment,
46            kappa_times_dry_volume=attributes["kappa times dry volume"],
47        )
48        attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet)
49        products = [
50            PySDM_products.MeanRadius(name="radius_m1", unit="um"),
51            PySDM_products.CondensationTimestepMin(name="dt_cond_min"),
52            PySDM_products.ParcelDisplacement(name="z"),
53            PySDM_products.AmbientRelativeHumidity(name="RH"),
54            PySDM_products.PeakSaturation(name="S_max"),
55            PySDM_products.Time(name="t"),
56            PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"),
57            PySDM_products.DeactivatingRate(
58                unit="s^-1 mg^-1", name="deactivating_rate"
59            ),
60            PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"),
61        ]
62
63        self.particulator = Particulator(
64            n_sd=1,
65            dynamics=[
66                AmbientThermodynamics(),
67                Condensation(
68                    rtol_x=settings.rtol_x,
69                    rtol_thd=settings.rtol_thd,
70                    dt_cond_range=settings.dt_cond_range,
71                ),
72            ],
73            attributes=attributes,
74            products=products,
75            environment=environment,
76        )
77
78        self.n_output = settings.n_output
n_substeps
particulator
n_output
def save(self, output):
80    def save(self, output):
81        cell_id = 0
82        output["r"].append(
83            self.particulator.products["radius_m1"].get(unit=const.si.m)[cell_id]
84        )
85        output["dt_cond_min"].append(
86            self.particulator.products["dt_cond_min"].get()[cell_id]
87        )
88        output["z"].append(self.particulator.products["z"].get()[cell_id])
89        output["RH"].append(self.particulator.products["RH"].get()[cell_id])
90        output["t"].append(self.particulator.products["t"].get())
91
92        for event in ("activating", "deactivating", "ripening"):
93            output[event + "_rate"].append(
94                self.particulator.products[event + "_rate"].get()[cell_id]
95            )
def run(self):
 97    def run(self):
 98        output = {
 99            "r": [],
100            "RH": [],
101            "z": [],
102            "t": [],
103            "dt_cond_min": [],
104            "activating_rate": [],
105            "deactivating_rate": [],
106            "ripening_rate": [],
107        }
108
109        self.save(output)
110        for _ in range(self.n_output):
111            self.particulator.run(self.n_substeps)
112            self.save(output)
113
114        return output