PySDM_examples.Abade_and_Albuquerque_2024.simulation

  1import numpy as np
  2
  3from PySDM_examples.utils import BasicSimulation
  4
  5from PySDM import Builder
  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        builder = Builder(
 44            backend=settings.backend,
 45            n_sd=settings.n_sd,
 46            environment=Parcel(
 47                dt=settings.timestep,
 48                mass_of_dry_air=settings.mass_of_dry_air,
 49                p0=settings.initial_total_pressure,
 50                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 51                T0=settings.initial_temperature,
 52                w=settings.updraft,
 53                mixed_phase=True,
 54            ),
 55            dynamics=dynamics,
 56        )
 57
 58        r_dry, n_in_dv = ConstantMultiplicity(
 59            settings.soluble_aerosol
 60        ).sample_deterministic(n_sd=settings.n_sd)
 61        attributes = builder.particulator.environment.init_attributes(
 62            n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
 63        )
 64        attributes["signed water mass"] = (
 65            builder.particulator.formulae.particle_shape_and_density.volume_to_mass(
 66                attributes["volume"]
 67            )
 68        )
 69        del attributes["volume"]
 70
 71        if settings.enable_immersion_freezing:
 72            trivia = builder.particulator.formulae.trivia
 73            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 74
 75            rng = np.random.default_rng(seed=builder.particulator.formulae.seed)
 76            insoluble_surface_area = trivia.sphere_surface(
 77                diameter=2 * settings.freezing_inp_dry_radius
 78            )
 79            attributes[
 80                "freezing temperature" if settings.singular else "immersed surface area"
 81            ] = rng.permutation(
 82                np.pad(
 83                    (
 84                        builder.particulator.formulae.freezing_temperature_spectrum.invcdf(
 85                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 86                            A_insol=insoluble_surface_area,
 87                        )
 88                        if settings.singular
 89                        else np.full(n_inp, insoluble_surface_area)
 90                    ),
 91                    (0, settings.n_sd - n_inp),
 92                    mode="constant",
 93                    constant_values=(
 94                        builder.particulator.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 95                        if settings.singular
 96                        else 0
 97                    ),
 98                )
 99            )
100
101        self.products = (
102            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
103            SpecificIceWaterContent(name="ice"),
104            ParcelDisplacement(name="height"),
105            AmbientTemperature(name="T"),
106            AmbientWaterVapourMixingRatio(
107                name="vapour", var="water_vapour_mixing_ratio"
108            ),
109        )
110        super().__init__(
111            particulator=builder.build(attributes=attributes, products=self.products)
112        )
113
114    def run(self, *, nt, steps_per_output_interval):
115        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        builder = Builder(
 45            backend=settings.backend,
 46            n_sd=settings.n_sd,
 47            environment=Parcel(
 48                dt=settings.timestep,
 49                mass_of_dry_air=settings.mass_of_dry_air,
 50                p0=settings.initial_total_pressure,
 51                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 52                T0=settings.initial_temperature,
 53                w=settings.updraft,
 54                mixed_phase=True,
 55            ),
 56            dynamics=dynamics,
 57        )
 58
 59        r_dry, n_in_dv = ConstantMultiplicity(
 60            settings.soluble_aerosol
 61        ).sample_deterministic(n_sd=settings.n_sd)
 62        attributes = builder.particulator.environment.init_attributes(
 63            n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
 64        )
 65        attributes["signed water mass"] = (
 66            builder.particulator.formulae.particle_shape_and_density.volume_to_mass(
 67                attributes["volume"]
 68            )
 69        )
 70        del attributes["volume"]
 71
 72        if settings.enable_immersion_freezing:
 73            trivia = builder.particulator.formulae.trivia
 74            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 75
 76            rng = np.random.default_rng(seed=builder.particulator.formulae.seed)
 77            insoluble_surface_area = trivia.sphere_surface(
 78                diameter=2 * settings.freezing_inp_dry_radius
 79            )
 80            attributes[
 81                "freezing temperature" if settings.singular else "immersed surface area"
 82            ] = rng.permutation(
 83                np.pad(
 84                    (
 85                        builder.particulator.formulae.freezing_temperature_spectrum.invcdf(
 86                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 87                            A_insol=insoluble_surface_area,
 88                        )
 89                        if settings.singular
 90                        else np.full(n_inp, insoluble_surface_area)
 91                    ),
 92                    (0, settings.n_sd - n_inp),
 93                    mode="constant",
 94                    constant_values=(
 95                        builder.particulator.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 96                        if settings.singular
 97                        else 0
 98                    ),
 99                )
100            )
101
102        self.products = (
103            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
104            SpecificIceWaterContent(name="ice"),
105            ParcelDisplacement(name="height"),
106            AmbientTemperature(name="T"),
107            AmbientWaterVapourMixingRatio(
108                name="vapour", var="water_vapour_mixing_ratio"
109            ),
110        )
111        super().__init__(
112            particulator=builder.build(attributes=attributes, products=self.products)
113        )
114
115    def run(self, *, nt, steps_per_output_interval):
116        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        builder = Builder(
 45            backend=settings.backend,
 46            n_sd=settings.n_sd,
 47            environment=Parcel(
 48                dt=settings.timestep,
 49                mass_of_dry_air=settings.mass_of_dry_air,
 50                p0=settings.initial_total_pressure,
 51                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 52                T0=settings.initial_temperature,
 53                w=settings.updraft,
 54                mixed_phase=True,
 55            ),
 56            dynamics=dynamics,
 57        )
 58
 59        r_dry, n_in_dv = ConstantMultiplicity(
 60            settings.soluble_aerosol
 61        ).sample_deterministic(n_sd=settings.n_sd)
 62        attributes = builder.particulator.environment.init_attributes(
 63            n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
 64        )
 65        attributes["signed water mass"] = (
 66            builder.particulator.formulae.particle_shape_and_density.volume_to_mass(
 67                attributes["volume"]
 68            )
 69        )
 70        del attributes["volume"]
 71
 72        if settings.enable_immersion_freezing:
 73            trivia = builder.particulator.formulae.trivia
 74            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 75
 76            rng = np.random.default_rng(seed=builder.particulator.formulae.seed)
 77            insoluble_surface_area = trivia.sphere_surface(
 78                diameter=2 * settings.freezing_inp_dry_radius
 79            )
 80            attributes[
 81                "freezing temperature" if settings.singular else "immersed surface area"
 82            ] = rng.permutation(
 83                np.pad(
 84                    (
 85                        builder.particulator.formulae.freezing_temperature_spectrum.invcdf(
 86                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 87                            A_insol=insoluble_surface_area,
 88                        )
 89                        if settings.singular
 90                        else np.full(n_inp, insoluble_surface_area)
 91                    ),
 92                    (0, settings.n_sd - n_inp),
 93                    mode="constant",
 94                    constant_values=(
 95                        builder.particulator.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 96                        if settings.singular
 97                        else 0
 98                    ),
 99                )
100            )
101
102        self.products = (
103            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
104            SpecificIceWaterContent(name="ice"),
105            ParcelDisplacement(name="height"),
106            AmbientTemperature(name="T"),
107            AmbientWaterVapourMixingRatio(
108                name="vapour", var="water_vapour_mixing_ratio"
109            ),
110        )
111        super().__init__(
112            particulator=builder.build(attributes=attributes, products=self.products)
113        )
products
def run(self, *, nt, steps_per_output_interval):
115    def run(self, *, nt, steps_per_output_interval):
116        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)