PySDM_examples.Abade_and_Albuquerque_2024.simulation

  1import numpy as np
  2
  3from PySDM_examples.utils import BasicSimulation
  4
  5from PySDM.particulator import Particulator
  6from PySDM.dynamics import (
  7    Condensation,
  8    AmbientThermodynamics,
  9    VapourDepositionOnIce,
 10    Freezing,
 11)
 12from PySDM.initialisation.sampling.spectral_sampling import ConstantMultiplicity
 13from PySDM.products import (
 14    AmbientTemperature,
 15    AmbientWaterVapourMixingRatio,
 16    ParcelDisplacement,
 17    WaterMixingRatio,
 18    SpecificIceWaterContent,
 19)
 20from PySDM.environments import Parcel
 21
 22
 23class Simulation(BasicSimulation):
 24    def __init__(self, settings):
 25
 26        dynamics = [
 27            AmbientThermodynamics(),
 28            Condensation(),
 29        ]
 30
 31        if settings.enable_immersion_freezing:
 32            dynamics.append(
 33                Freezing(
 34                    immersion_freezing=(
 35                        "singular" if settings.singular else "time-dependent"
 36                    )
 37                )
 38            )
 39
 40        if settings.enable_vapour_deposition_on_ice:
 41            dynamics.append(VapourDepositionOnIce(adaptive=True))
 42
 43        environment = Parcel(
 44            dt=settings.timestep,
 45            mass_of_dry_air=settings.mass_of_dry_air,
 46            p0=settings.initial_total_pressure,
 47            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 48            T0=settings.initial_temperature,
 49            w=settings.updraft,
 50            mixed_phase=True,
 51            backend=settings.backend,
 52        )
 53        r_dry, n_in_dv = ConstantMultiplicity(
 54            settings.soluble_aerosol
 55        ).sample_deterministic(n_sd=settings.n_sd)
 56        attributes = environment.init_attributes(
 57            n_in_dv=n_in_dv,
 58            kappa=settings.kappa,
 59            r_dry=r_dry,
 60        )
 61        attributes["signed water mass"] = (
 62            settings.backend.formulae.particle_shape_and_density.volume_to_mass(
 63                attributes["volume"]
 64            )
 65        )
 66        del attributes["volume"]
 67
 68        if settings.enable_immersion_freezing:
 69            trivia = settings.backend.formulae.trivia
 70            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 71
 72            rng = np.random.default_rng(seed=settings.backend.formulae.seed)
 73            insoluble_surface_area = trivia.sphere_surface(
 74                diameter=2 * settings.freezing_inp_dry_radius
 75            )
 76            attributes[
 77                "freezing temperature" if settings.singular else "immersed surface area"
 78            ] = rng.permutation(
 79                np.pad(
 80                    (
 81                        settings.backend.formulae.freezing_temperature_spectrum.invcdf(
 82                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 83                            A_insol=insoluble_surface_area,
 84                        )
 85                        if settings.singular
 86                        else np.full(n_inp, insoluble_surface_area)
 87                    ),
 88                    (0, settings.n_sd - n_inp),
 89                    mode="constant",
 90                    constant_values=(
 91                        settings.backend.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 92                        if settings.singular
 93                        else 0
 94                    ),
 95                )
 96            )
 97
 98        self.products = (
 99            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
100            SpecificIceWaterContent(name="ice"),
101            ParcelDisplacement(name="height"),
102            AmbientTemperature(name="T"),
103            AmbientWaterVapourMixingRatio(
104                name="vapour", var="water_vapour_mixing_ratio"
105            ),
106        )
107        particulator = Particulator(
108            n_sd=settings.n_sd,
109            environment=environment,
110            dynamics=dynamics,
111            attributes=attributes,
112            products=self.products,
113        )
114        super().__init__(particulator=particulator)
115
116    def run(self, *, nt, steps_per_output_interval):
117        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)
 24class Simulation(BasicSimulation):
 25    def __init__(self, settings):
 26
 27        dynamics = [
 28            AmbientThermodynamics(),
 29            Condensation(),
 30        ]
 31
 32        if settings.enable_immersion_freezing:
 33            dynamics.append(
 34                Freezing(
 35                    immersion_freezing=(
 36                        "singular" if settings.singular else "time-dependent"
 37                    )
 38                )
 39            )
 40
 41        if settings.enable_vapour_deposition_on_ice:
 42            dynamics.append(VapourDepositionOnIce(adaptive=True))
 43
 44        environment = Parcel(
 45            dt=settings.timestep,
 46            mass_of_dry_air=settings.mass_of_dry_air,
 47            p0=settings.initial_total_pressure,
 48            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 49            T0=settings.initial_temperature,
 50            w=settings.updraft,
 51            mixed_phase=True,
 52            backend=settings.backend,
 53        )
 54        r_dry, n_in_dv = ConstantMultiplicity(
 55            settings.soluble_aerosol
 56        ).sample_deterministic(n_sd=settings.n_sd)
 57        attributes = environment.init_attributes(
 58            n_in_dv=n_in_dv,
 59            kappa=settings.kappa,
 60            r_dry=r_dry,
 61        )
 62        attributes["signed water mass"] = (
 63            settings.backend.formulae.particle_shape_and_density.volume_to_mass(
 64                attributes["volume"]
 65            )
 66        )
 67        del attributes["volume"]
 68
 69        if settings.enable_immersion_freezing:
 70            trivia = settings.backend.formulae.trivia
 71            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 72
 73            rng = np.random.default_rng(seed=settings.backend.formulae.seed)
 74            insoluble_surface_area = trivia.sphere_surface(
 75                diameter=2 * settings.freezing_inp_dry_radius
 76            )
 77            attributes[
 78                "freezing temperature" if settings.singular else "immersed surface area"
 79            ] = rng.permutation(
 80                np.pad(
 81                    (
 82                        settings.backend.formulae.freezing_temperature_spectrum.invcdf(
 83                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 84                            A_insol=insoluble_surface_area,
 85                        )
 86                        if settings.singular
 87                        else np.full(n_inp, insoluble_surface_area)
 88                    ),
 89                    (0, settings.n_sd - n_inp),
 90                    mode="constant",
 91                    constant_values=(
 92                        settings.backend.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 93                        if settings.singular
 94                        else 0
 95                    ),
 96                )
 97            )
 98
 99        self.products = (
100            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
101            SpecificIceWaterContent(name="ice"),
102            ParcelDisplacement(name="height"),
103            AmbientTemperature(name="T"),
104            AmbientWaterVapourMixingRatio(
105                name="vapour", var="water_vapour_mixing_ratio"
106            ),
107        )
108        particulator = Particulator(
109            n_sd=settings.n_sd,
110            environment=environment,
111            dynamics=dynamics,
112            attributes=attributes,
113            products=self.products,
114        )
115        super().__init__(particulator=particulator)
116
117    def run(self, *, nt, steps_per_output_interval):
118        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)
Simulation(settings)
 25    def __init__(self, settings):
 26
 27        dynamics = [
 28            AmbientThermodynamics(),
 29            Condensation(),
 30        ]
 31
 32        if settings.enable_immersion_freezing:
 33            dynamics.append(
 34                Freezing(
 35                    immersion_freezing=(
 36                        "singular" if settings.singular else "time-dependent"
 37                    )
 38                )
 39            )
 40
 41        if settings.enable_vapour_deposition_on_ice:
 42            dynamics.append(VapourDepositionOnIce(adaptive=True))
 43
 44        environment = Parcel(
 45            dt=settings.timestep,
 46            mass_of_dry_air=settings.mass_of_dry_air,
 47            p0=settings.initial_total_pressure,
 48            initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 49            T0=settings.initial_temperature,
 50            w=settings.updraft,
 51            mixed_phase=True,
 52            backend=settings.backend,
 53        )
 54        r_dry, n_in_dv = ConstantMultiplicity(
 55            settings.soluble_aerosol
 56        ).sample_deterministic(n_sd=settings.n_sd)
 57        attributes = environment.init_attributes(
 58            n_in_dv=n_in_dv,
 59            kappa=settings.kappa,
 60            r_dry=r_dry,
 61        )
 62        attributes["signed water mass"] = (
 63            settings.backend.formulae.particle_shape_and_density.volume_to_mass(
 64                attributes["volume"]
 65            )
 66        )
 67        del attributes["volume"]
 68
 69        if settings.enable_immersion_freezing:
 70            trivia = settings.backend.formulae.trivia
 71            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 72
 73            rng = np.random.default_rng(seed=settings.backend.formulae.seed)
 74            insoluble_surface_area = trivia.sphere_surface(
 75                diameter=2 * settings.freezing_inp_dry_radius
 76            )
 77            attributes[
 78                "freezing temperature" if settings.singular else "immersed surface area"
 79            ] = rng.permutation(
 80                np.pad(
 81                    (
 82                        settings.backend.formulae.freezing_temperature_spectrum.invcdf(
 83                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 84                            A_insol=insoluble_surface_area,
 85                        )
 86                        if settings.singular
 87                        else np.full(n_inp, insoluble_surface_area)
 88                    ),
 89                    (0, settings.n_sd - n_inp),
 90                    mode="constant",
 91                    constant_values=(
 92                        settings.backend.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 93                        if settings.singular
 94                        else 0
 95                    ),
 96                )
 97            )
 98
 99        self.products = (
100            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
101            SpecificIceWaterContent(name="ice"),
102            ParcelDisplacement(name="height"),
103            AmbientTemperature(name="T"),
104            AmbientWaterVapourMixingRatio(
105                name="vapour", var="water_vapour_mixing_ratio"
106            ),
107        )
108        particulator = Particulator(
109            n_sd=settings.n_sd,
110            environment=environment,
111            dynamics=dynamics,
112            attributes=attributes,
113            products=self.products,
114        )
115        super().__init__(particulator=particulator)
products
def run(self, *, nt, steps_per_output_interval):
117    def run(self, *, nt, steps_per_output_interval):
118        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)