PySDM_examples.Arabas_and_Shima_2017.simulation

  1import numpy as np
  2
  3import PySDM.products as PySDM_products
  4from PySDM.backends import CPU
  5from PySDM.builder import Builder
  6from PySDM.dynamics import AmbientThermodynamics, Condensation
  7from PySDM.environments import Parcel
  8from PySDM.initialisation import equilibrate_wet_radii
  9from PySDM.physics import constants as const
 10
 11
 12class Simulation:
 13    def __init__(self, settings, backend=CPU):
 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        builder = Builder(
 22            backend=backend(
 23                formulae=settings.formulae,
 24                **(
 25                    {"override_jit_flags": {"parallel": False}}
 26                    if backend == CPU
 27                    else {}
 28                )
 29            ),
 30            n_sd=1,
 31            environment=Parcel(
 32                dt=dt_output / self.n_substeps,
 33                mass_of_dry_air=settings.mass_of_dry_air,
 34                p0=settings.p0,
 35                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 36                T0=settings.T0,
 37                w=settings.w,
 38            ),
 39        )
 40
 41        builder.add_dynamic(AmbientThermodynamics())
 42        builder.add_dynamic(
 43            Condensation(
 44                rtol_x=settings.rtol_x,
 45                rtol_thd=settings.rtol_thd,
 46                dt_cond_range=settings.dt_cond_range,
 47            )
 48        )
 49        attributes = {}
 50        r_dry = np.array([settings.r_dry])
 51        attributes["dry volume"] = settings.formulae.trivia.volume(radius=r_dry)
 52        attributes["kappa times dry volume"] = attributes["dry volume"] * settings.kappa
 53        attributes["multiplicity"] = np.array([settings.n_in_dv], dtype=np.int64)
 54        environment = builder.particulator.environment
 55        r_wet = equilibrate_wet_radii(
 56            r_dry=r_dry,
 57            environment=environment,
 58            kappa_times_dry_volume=attributes["kappa times dry volume"],
 59        )
 60        attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet)
 61        products = [
 62            PySDM_products.MeanRadius(name="radius_m1", unit="um"),
 63            PySDM_products.CondensationTimestepMin(name="dt_cond_min"),
 64            PySDM_products.ParcelDisplacement(name="z"),
 65            PySDM_products.AmbientRelativeHumidity(name="RH", unit="%"),
 66            PySDM_products.Time(name="t"),
 67            PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"),
 68            PySDM_products.DeactivatingRate(
 69                unit="s^-1 mg^-1", name="deactivating_rate"
 70            ),
 71            PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"),
 72            PySDM_products.PeakSupersaturation(unit="%", name="S_max"),
 73        ]
 74
 75        self.particulator = builder.build(attributes, products)
 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["S"].append(self.particulator.products["RH"].get()[cell_id] / 100 - 1)
 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            "S": [],
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=CPU):
 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        builder = Builder(
 23            backend=backend(
 24                formulae=settings.formulae,
 25                **(
 26                    {"override_jit_flags": {"parallel": False}}
 27                    if backend == CPU
 28                    else {}
 29                )
 30            ),
 31            n_sd=1,
 32            environment=Parcel(
 33                dt=dt_output / self.n_substeps,
 34                mass_of_dry_air=settings.mass_of_dry_air,
 35                p0=settings.p0,
 36                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 37                T0=settings.T0,
 38                w=settings.w,
 39            ),
 40        )
 41
 42        builder.add_dynamic(AmbientThermodynamics())
 43        builder.add_dynamic(
 44            Condensation(
 45                rtol_x=settings.rtol_x,
 46                rtol_thd=settings.rtol_thd,
 47                dt_cond_range=settings.dt_cond_range,
 48            )
 49        )
 50        attributes = {}
 51        r_dry = np.array([settings.r_dry])
 52        attributes["dry volume"] = settings.formulae.trivia.volume(radius=r_dry)
 53        attributes["kappa times dry volume"] = attributes["dry volume"] * settings.kappa
 54        attributes["multiplicity"] = np.array([settings.n_in_dv], dtype=np.int64)
 55        environment = builder.particulator.environment
 56        r_wet = equilibrate_wet_radii(
 57            r_dry=r_dry,
 58            environment=environment,
 59            kappa_times_dry_volume=attributes["kappa times dry volume"],
 60        )
 61        attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet)
 62        products = [
 63            PySDM_products.MeanRadius(name="radius_m1", unit="um"),
 64            PySDM_products.CondensationTimestepMin(name="dt_cond_min"),
 65            PySDM_products.ParcelDisplacement(name="z"),
 66            PySDM_products.AmbientRelativeHumidity(name="RH", unit="%"),
 67            PySDM_products.Time(name="t"),
 68            PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"),
 69            PySDM_products.DeactivatingRate(
 70                unit="s^-1 mg^-1", name="deactivating_rate"
 71            ),
 72            PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"),
 73            PySDM_products.PeakSupersaturation(unit="%", name="S_max"),
 74        ]
 75
 76        self.particulator = builder.build(attributes, products)
 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["S"].append(self.particulator.products["RH"].get()[cell_id] / 100 - 1)
 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            "S": [],
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.Numba'>)
14    def __init__(self, settings, backend=CPU):
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        builder = Builder(
23            backend=backend(
24                formulae=settings.formulae,
25                **(
26                    {"override_jit_flags": {"parallel": False}}
27                    if backend == CPU
28                    else {}
29                )
30            ),
31            n_sd=1,
32            environment=Parcel(
33                dt=dt_output / self.n_substeps,
34                mass_of_dry_air=settings.mass_of_dry_air,
35                p0=settings.p0,
36                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
37                T0=settings.T0,
38                w=settings.w,
39            ),
40        )
41
42        builder.add_dynamic(AmbientThermodynamics())
43        builder.add_dynamic(
44            Condensation(
45                rtol_x=settings.rtol_x,
46                rtol_thd=settings.rtol_thd,
47                dt_cond_range=settings.dt_cond_range,
48            )
49        )
50        attributes = {}
51        r_dry = np.array([settings.r_dry])
52        attributes["dry volume"] = settings.formulae.trivia.volume(radius=r_dry)
53        attributes["kappa times dry volume"] = attributes["dry volume"] * settings.kappa
54        attributes["multiplicity"] = np.array([settings.n_in_dv], dtype=np.int64)
55        environment = builder.particulator.environment
56        r_wet = equilibrate_wet_radii(
57            r_dry=r_dry,
58            environment=environment,
59            kappa_times_dry_volume=attributes["kappa times dry volume"],
60        )
61        attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet)
62        products = [
63            PySDM_products.MeanRadius(name="radius_m1", unit="um"),
64            PySDM_products.CondensationTimestepMin(name="dt_cond_min"),
65            PySDM_products.ParcelDisplacement(name="z"),
66            PySDM_products.AmbientRelativeHumidity(name="RH", unit="%"),
67            PySDM_products.Time(name="t"),
68            PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"),
69            PySDM_products.DeactivatingRate(
70                unit="s^-1 mg^-1", name="deactivating_rate"
71            ),
72            PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"),
73            PySDM_products.PeakSupersaturation(unit="%", name="S_max"),
74        ]
75
76        self.particulator = builder.build(attributes, products)
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["S"].append(self.particulator.products["RH"].get()[cell_id] / 100 - 1)
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            "S": [],
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