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