PySDM_examples.sandbox.Niedermeier_et_al_2014.simulation

 1import numpy as np
 2from PySDM_examples.sandbox.Ervens_and_Feingold_2012.settings import (
 3    sampled_ccn_diameter_number_concentration_spectrum,
 4)
 5from PySDM_examples.sandbox.Niedermeier_et_al_2014.settings import Settings
 6from PySDM_examples.utils import BasicSimulation
 7
 8from PySDM import Particulator
 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            backend=CPU(settings.formulae),
28        )
29
30        air_volume = settings.mass_of_dry_air / settings.rhod0
31        (
32            ccn_diameter,
33            ccn_conc_float,
34        ) = sampled_ccn_diameter_number_concentration_spectrum(
35            size_range=settings.ccn_dry_diameter_range, n_sd=settings.ccn_sampling_n
36        )
37        dry_volume = settings.formulae.trivia.volume(radius=ccn_diameter / 2)
38
39        immersed_surface_area = np.zeros_like(dry_volume)
40        immersed_surface_area[-1] = settings.formulae.trivia.sphere_surface(
41            diameter=ccn_diameter[-1]
42        )
43
44        attributes = {
45            "multiplicity": ccn_conc_float * air_volume,
46            "dry volume": dry_volume,
47            "kappa times dry volume": settings.kappa * dry_volume,
48            "immersed surface area": immersed_surface_area,
49        }
50        attributes["signed water mass"] = settings.formulae.trivia.volume(
51            radius=equilibrate_wet_radii(
52                r_dry=ccn_diameter / 2,
53                environment=env,
54                kappa_times_dry_volume=attributes["kappa times dry volume"],
55            )
56            * settings.formulae.constants.rho_w
57        )
58
59        for attribute, data in attributes.items():
60            attributes[attribute] = np.concatenate(
61                (
62                    data[:-1],
63                    np.full(
64                        settings.in_sampling_n,
65                        (
66                            data[-1]
67                            if attribute != "multiplicity"
68                            else data[-1] / settings.in_sampling_n
69                        ),
70                    ),
71                )
72            )
73
74        products = (
75            IceWaterContent(),
76            ParcelDisplacement(name="z"),
77            AmbientTemperature(name="T"),
78        )
79        super().__init__(
80            Particulator(
81                n_sd=n_particles,
82                environment=env,
83                dynamics=(
84                    AmbientThermodynamics(),
85                    Condensation(),
86                    Freezing(immersion_freezing="time-dependent"),
87                ),
88                attributes=attributes,
89                products=products,
90            )
91        )
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)
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            backend=CPU(settings.formulae),
29        )
30
31        air_volume = settings.mass_of_dry_air / settings.rhod0
32        (
33            ccn_diameter,
34            ccn_conc_float,
35        ) = sampled_ccn_diameter_number_concentration_spectrum(
36            size_range=settings.ccn_dry_diameter_range, n_sd=settings.ccn_sampling_n
37        )
38        dry_volume = settings.formulae.trivia.volume(radius=ccn_diameter / 2)
39
40        immersed_surface_area = np.zeros_like(dry_volume)
41        immersed_surface_area[-1] = settings.formulae.trivia.sphere_surface(
42            diameter=ccn_diameter[-1]
43        )
44
45        attributes = {
46            "multiplicity": ccn_conc_float * air_volume,
47            "dry volume": dry_volume,
48            "kappa times dry volume": settings.kappa * dry_volume,
49            "immersed surface area": immersed_surface_area,
50        }
51        attributes["signed water mass"] = settings.formulae.trivia.volume(
52            radius=equilibrate_wet_radii(
53                r_dry=ccn_diameter / 2,
54                environment=env,
55                kappa_times_dry_volume=attributes["kappa times dry volume"],
56            )
57            * settings.formulae.constants.rho_w
58        )
59
60        for attribute, data in attributes.items():
61            attributes[attribute] = np.concatenate(
62                (
63                    data[:-1],
64                    np.full(
65                        settings.in_sampling_n,
66                        (
67                            data[-1]
68                            if attribute != "multiplicity"
69                            else data[-1] / settings.in_sampling_n
70                        ),
71                    ),
72                )
73            )
74
75        products = (
76            IceWaterContent(),
77            ParcelDisplacement(name="z"),
78            AmbientTemperature(name="T"),
79        )
80        super().__init__(
81            Particulator(
82                n_sd=n_particles,
83                environment=env,
84                dynamics=(
85                    AmbientThermodynamics(),
86                    Condensation(),
87                    Freezing(immersion_freezing="time-dependent"),
88                ),
89                attributes=attributes,
90                products=products,
91            )
92        )
93        self.steps = int(
94            settings.displacement / settings.vertical_velocity / settings.timestep
95        )
96
97    def run(self):
98        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            backend=CPU(settings.formulae),
29        )
30
31        air_volume = settings.mass_of_dry_air / settings.rhod0
32        (
33            ccn_diameter,
34            ccn_conc_float,
35        ) = sampled_ccn_diameter_number_concentration_spectrum(
36            size_range=settings.ccn_dry_diameter_range, n_sd=settings.ccn_sampling_n
37        )
38        dry_volume = settings.formulae.trivia.volume(radius=ccn_diameter / 2)
39
40        immersed_surface_area = np.zeros_like(dry_volume)
41        immersed_surface_area[-1] = settings.formulae.trivia.sphere_surface(
42            diameter=ccn_diameter[-1]
43        )
44
45        attributes = {
46            "multiplicity": ccn_conc_float * air_volume,
47            "dry volume": dry_volume,
48            "kappa times dry volume": settings.kappa * dry_volume,
49            "immersed surface area": immersed_surface_area,
50        }
51        attributes["signed water mass"] = settings.formulae.trivia.volume(
52            radius=equilibrate_wet_radii(
53                r_dry=ccn_diameter / 2,
54                environment=env,
55                kappa_times_dry_volume=attributes["kappa times dry volume"],
56            )
57            * settings.formulae.constants.rho_w
58        )
59
60        for attribute, data in attributes.items():
61            attributes[attribute] = np.concatenate(
62                (
63                    data[:-1],
64                    np.full(
65                        settings.in_sampling_n,
66                        (
67                            data[-1]
68                            if attribute != "multiplicity"
69                            else data[-1] / settings.in_sampling_n
70                        ),
71                    ),
72                )
73            )
74
75        products = (
76            IceWaterContent(),
77            ParcelDisplacement(name="z"),
78            AmbientTemperature(name="T"),
79        )
80        super().__init__(
81            Particulator(
82                n_sd=n_particles,
83                environment=env,
84                dynamics=(
85                    AmbientThermodynamics(),
86                    Condensation(),
87                    Freezing(immersion_freezing="time-dependent"),
88                ),
89                attributes=attributes,
90                products=products,
91            )
92        )
93        self.steps = int(
94            settings.displacement / settings.vertical_velocity / settings.timestep
95        )
steps
def run(self):
97    def run(self):
98        return super()._run(nt=self.steps, steps_per_output_interval=1)