PySDM_examples.Niedermeier_et_al_2014.simulation

 1import numpy as np
 2from PySDM_examples.Ervens_and_Feingold_2012.settings import (
 3    sampled_ccn_diameter_number_concentration_spectrum,
 4)
 5from PySDM_examples.Niedermeier_et_al_2014.settings import Settings
 6from PySDM_examples.utils import BasicSimulation
 7
 8from PySDM import Builder
 9from PySDM.backends import CPU
10from PySDM.dynamics import AmbientThermodynamics, Condensation, Freezing
11from PySDM.environments import Parcel
12from PySDM.initialisation.hygroscopic_equilibrium import equilibrate_wet_radii
13from PySDM.products import AmbientTemperature, IceWaterContent, ParcelDisplacement
14
15
16class Simulation(BasicSimulation):
17    def __init__(self, settings: Settings):
18        n_particles = settings.ccn_sampling_n - 1 + settings.in_sampling_n
19        env = Parcel(
20            dt=settings.timestep,
21            p0=settings.p0,
22            T0=settings.T0,
23            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
24            mass_of_dry_air=settings.mass_of_dry_air,
25            w=settings.vertical_velocity,
26            mixed_phase=True,
27        )
28        builder = Builder(
29            n_sd=n_particles,
30            backend=CPU(
31                settings.formulae,
32                override_jit_flags={"parallel": False},
33            ),
34            environment=env,
35        )
36
37        builder.add_dynamic(AmbientThermodynamics())
38        builder.add_dynamic(Condensation())
39        builder.add_dynamic(Freezing(immersion_freezing="time-dependent"))
40
41        air_volume = settings.mass_of_dry_air / settings.rhod0
42        (
43            ccn_diameter,
44            ccn_conc_float,
45        ) = sampled_ccn_diameter_number_concentration_spectrum(
46            size_range=settings.ccn_dry_diameter_range, n_sd=settings.ccn_sampling_n
47        )
48        dry_volume = settings.formulae.trivia.volume(radius=ccn_diameter / 2)
49
50        immersed_surface_area = np.zeros_like(dry_volume)
51        immersed_surface_area[-1] = settings.formulae.trivia.sphere_surface(
52            diameter=ccn_diameter[-1]
53        )
54
55        attributes = {
56            "multiplicity": ccn_conc_float * air_volume,
57            "dry volume": dry_volume,
58            "kappa times dry volume": settings.kappa * dry_volume,
59            "immersed surface area": immersed_surface_area,
60        }
61        attributes["signed water mass"] = settings.formulae.trivia.volume(
62            radius=equilibrate_wet_radii(
63                r_dry=ccn_diameter / 2,
64                environment=builder.particulator.environment,
65                kappa_times_dry_volume=attributes["kappa times dry volume"],
66            )
67            * settings.formulae.constants.rho_w
68        )
69
70        for attribute, data in attributes.items():
71            attributes[attribute] = np.concatenate(
72                (
73                    data[:-1],
74                    np.full(
75                        settings.in_sampling_n,
76                        (
77                            data[-1]
78                            if attribute != "multiplicity"
79                            else data[-1] / settings.in_sampling_n
80                        ),
81                    ),
82                )
83            )
84
85        products = (
86            IceWaterContent(),
87            ParcelDisplacement(name="z"),
88            AmbientTemperature(name="T"),
89        )
90        super().__init__(builder.build(attributes=attributes, products=products))
91        self.steps = int(
92            settings.displacement / settings.vertical_velocity / settings.timestep
93        )
94
95    def run(self):
96        return super()._run(nt=self.steps, steps_per_output_interval=1)
17class Simulation(BasicSimulation):
18    def __init__(self, settings: Settings):
19        n_particles = settings.ccn_sampling_n - 1 + settings.in_sampling_n
20        env = Parcel(
21            dt=settings.timestep,
22            p0=settings.p0,
23            T0=settings.T0,
24            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
25            mass_of_dry_air=settings.mass_of_dry_air,
26            w=settings.vertical_velocity,
27            mixed_phase=True,
28        )
29        builder = Builder(
30            n_sd=n_particles,
31            backend=CPU(
32                settings.formulae,
33                override_jit_flags={"parallel": False},
34            ),
35            environment=env,
36        )
37
38        builder.add_dynamic(AmbientThermodynamics())
39        builder.add_dynamic(Condensation())
40        builder.add_dynamic(Freezing(immersion_freezing="time-dependent"))
41
42        air_volume = settings.mass_of_dry_air / settings.rhod0
43        (
44            ccn_diameter,
45            ccn_conc_float,
46        ) = sampled_ccn_diameter_number_concentration_spectrum(
47            size_range=settings.ccn_dry_diameter_range, n_sd=settings.ccn_sampling_n
48        )
49        dry_volume = settings.formulae.trivia.volume(radius=ccn_diameter / 2)
50
51        immersed_surface_area = np.zeros_like(dry_volume)
52        immersed_surface_area[-1] = settings.formulae.trivia.sphere_surface(
53            diameter=ccn_diameter[-1]
54        )
55
56        attributes = {
57            "multiplicity": ccn_conc_float * air_volume,
58            "dry volume": dry_volume,
59            "kappa times dry volume": settings.kappa * dry_volume,
60            "immersed surface area": immersed_surface_area,
61        }
62        attributes["signed water mass"] = settings.formulae.trivia.volume(
63            radius=equilibrate_wet_radii(
64                r_dry=ccn_diameter / 2,
65                environment=builder.particulator.environment,
66                kappa_times_dry_volume=attributes["kappa times dry volume"],
67            )
68            * settings.formulae.constants.rho_w
69        )
70
71        for attribute, data in attributes.items():
72            attributes[attribute] = np.concatenate(
73                (
74                    data[:-1],
75                    np.full(
76                        settings.in_sampling_n,
77                        (
78                            data[-1]
79                            if attribute != "multiplicity"
80                            else data[-1] / settings.in_sampling_n
81                        ),
82                    ),
83                )
84            )
85
86        products = (
87            IceWaterContent(),
88            ParcelDisplacement(name="z"),
89            AmbientTemperature(name="T"),
90        )
91        super().__init__(builder.build(attributes=attributes, products=products))
92        self.steps = int(
93            settings.displacement / settings.vertical_velocity / settings.timestep
94        )
95
96    def run(self):
97        return super()._run(nt=self.steps, steps_per_output_interval=1)
18    def __init__(self, settings: Settings):
19        n_particles = settings.ccn_sampling_n - 1 + settings.in_sampling_n
20        env = Parcel(
21            dt=settings.timestep,
22            p0=settings.p0,
23            T0=settings.T0,
24            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
25            mass_of_dry_air=settings.mass_of_dry_air,
26            w=settings.vertical_velocity,
27            mixed_phase=True,
28        )
29        builder = Builder(
30            n_sd=n_particles,
31            backend=CPU(
32                settings.formulae,
33                override_jit_flags={"parallel": False},
34            ),
35            environment=env,
36        )
37
38        builder.add_dynamic(AmbientThermodynamics())
39        builder.add_dynamic(Condensation())
40        builder.add_dynamic(Freezing(immersion_freezing="time-dependent"))
41
42        air_volume = settings.mass_of_dry_air / settings.rhod0
43        (
44            ccn_diameter,
45            ccn_conc_float,
46        ) = sampled_ccn_diameter_number_concentration_spectrum(
47            size_range=settings.ccn_dry_diameter_range, n_sd=settings.ccn_sampling_n
48        )
49        dry_volume = settings.formulae.trivia.volume(radius=ccn_diameter / 2)
50
51        immersed_surface_area = np.zeros_like(dry_volume)
52        immersed_surface_area[-1] = settings.formulae.trivia.sphere_surface(
53            diameter=ccn_diameter[-1]
54        )
55
56        attributes = {
57            "multiplicity": ccn_conc_float * air_volume,
58            "dry volume": dry_volume,
59            "kappa times dry volume": settings.kappa * dry_volume,
60            "immersed surface area": immersed_surface_area,
61        }
62        attributes["signed water mass"] = settings.formulae.trivia.volume(
63            radius=equilibrate_wet_radii(
64                r_dry=ccn_diameter / 2,
65                environment=builder.particulator.environment,
66                kappa_times_dry_volume=attributes["kappa times dry volume"],
67            )
68            * settings.formulae.constants.rho_w
69        )
70
71        for attribute, data in attributes.items():
72            attributes[attribute] = np.concatenate(
73                (
74                    data[:-1],
75                    np.full(
76                        settings.in_sampling_n,
77                        (
78                            data[-1]
79                            if attribute != "multiplicity"
80                            else data[-1] / settings.in_sampling_n
81                        ),
82                    ),
83                )
84            )
85
86        products = (
87            IceWaterContent(),
88            ParcelDisplacement(name="z"),
89            AmbientTemperature(name="T"),
90        )
91        super().__init__(builder.build(attributes=attributes, products=products))
92        self.steps = int(
93            settings.displacement / settings.vertical_velocity / settings.timestep
94        )
steps
def run(self):
96    def run(self):
97        return super()._run(nt=self.steps, steps_per_output_interval=1)