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        builder = Builder(
 26            backend=settings.backend,
 27            n_sd=settings.n_sd,
 28            environment=Parcel(
 29                dt=settings.timestep,
 30                mass_of_dry_air=settings.mass_of_dry_air,
 31                p0=settings.initial_total_pressure,
 32                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 33                T0=settings.initial_temperature,
 34                w=settings.updraft,
 35                mixed_phase=True,
 36            ),
 37        )
 38        builder.add_dynamic(AmbientThermodynamics())
 39        builder.add_dynamic(Condensation())
 40
 41        if settings.enable_immersion_freezing:
 42            builder.add_dynamic(
 43                Freezing(
 44                    immersion_freezing=(
 45                        "singular" if settings.singular else "time-dependent"
 46                    )
 47                )
 48            )
 49        if settings.enable_vapour_deposition_on_ice:
 50            builder.add_dynamic(VapourDepositionOnIce(adaptive=True))
 51
 52        r_dry, n_in_dv = ConstantMultiplicity(settings.soluble_aerosol).sample(
 53            n_sd=settings.n_sd
 54        )
 55        attributes = builder.particulator.environment.init_attributes(
 56            n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
 57        )
 58        attributes["signed water mass"] = (
 59            builder.particulator.formulae.particle_shape_and_density.volume_to_mass(
 60                attributes["volume"]
 61            )
 62        )
 63        del attributes["volume"]
 64
 65        if settings.enable_immersion_freezing:
 66            trivia = builder.particulator.formulae.trivia
 67            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 68
 69            rng = np.random.default_rng(seed=builder.particulator.formulae.seed)
 70            insoluble_surface_area = trivia.sphere_surface(
 71                diameter=2 * settings.freezing_inp_dry_radius
 72            )
 73            attributes[
 74                "freezing temperature" if settings.singular else "immersed surface area"
 75            ] = rng.permutation(
 76                np.pad(
 77                    (
 78                        builder.particulator.formulae.freezing_temperature_spectrum.invcdf(
 79                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 80                            A_insol=insoluble_surface_area,
 81                        )
 82                        if settings.singular
 83                        else np.full(n_inp, insoluble_surface_area)
 84                    ),
 85                    (0, settings.n_sd - n_inp),
 86                    mode="constant",
 87                    constant_values=(
 88                        builder.particulator.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 89                        if settings.singular
 90                        else 0
 91                    ),
 92                )
 93            )
 94
 95        self.products = (
 96            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
 97            SpecificIceWaterContent(name="ice"),
 98            ParcelDisplacement(name="height"),
 99            AmbientTemperature(name="T"),
100            AmbientWaterVapourMixingRatio(
101                name="vapour", var="water_vapour_mixing_ratio"
102            ),
103        )
104        super().__init__(
105            particulator=builder.build(attributes=attributes, products=self.products)
106        )
107
108    def run(self, *, nt, steps_per_output_interval):
109        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)
 24class Simulation(BasicSimulation):
 25    def __init__(self, settings):
 26        builder = Builder(
 27            backend=settings.backend,
 28            n_sd=settings.n_sd,
 29            environment=Parcel(
 30                dt=settings.timestep,
 31                mass_of_dry_air=settings.mass_of_dry_air,
 32                p0=settings.initial_total_pressure,
 33                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 34                T0=settings.initial_temperature,
 35                w=settings.updraft,
 36                mixed_phase=True,
 37            ),
 38        )
 39        builder.add_dynamic(AmbientThermodynamics())
 40        builder.add_dynamic(Condensation())
 41
 42        if settings.enable_immersion_freezing:
 43            builder.add_dynamic(
 44                Freezing(
 45                    immersion_freezing=(
 46                        "singular" if settings.singular else "time-dependent"
 47                    )
 48                )
 49            )
 50        if settings.enable_vapour_deposition_on_ice:
 51            builder.add_dynamic(VapourDepositionOnIce(adaptive=True))
 52
 53        r_dry, n_in_dv = ConstantMultiplicity(settings.soluble_aerosol).sample(
 54            n_sd=settings.n_sd
 55        )
 56        attributes = builder.particulator.environment.init_attributes(
 57            n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
 58        )
 59        attributes["signed water mass"] = (
 60            builder.particulator.formulae.particle_shape_and_density.volume_to_mass(
 61                attributes["volume"]
 62            )
 63        )
 64        del attributes["volume"]
 65
 66        if settings.enable_immersion_freezing:
 67            trivia = builder.particulator.formulae.trivia
 68            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 69
 70            rng = np.random.default_rng(seed=builder.particulator.formulae.seed)
 71            insoluble_surface_area = trivia.sphere_surface(
 72                diameter=2 * settings.freezing_inp_dry_radius
 73            )
 74            attributes[
 75                "freezing temperature" if settings.singular else "immersed surface area"
 76            ] = rng.permutation(
 77                np.pad(
 78                    (
 79                        builder.particulator.formulae.freezing_temperature_spectrum.invcdf(
 80                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 81                            A_insol=insoluble_surface_area,
 82                        )
 83                        if settings.singular
 84                        else np.full(n_inp, insoluble_surface_area)
 85                    ),
 86                    (0, settings.n_sd - n_inp),
 87                    mode="constant",
 88                    constant_values=(
 89                        builder.particulator.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 90                        if settings.singular
 91                        else 0
 92                    ),
 93                )
 94            )
 95
 96        self.products = (
 97            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
 98            SpecificIceWaterContent(name="ice"),
 99            ParcelDisplacement(name="height"),
100            AmbientTemperature(name="T"),
101            AmbientWaterVapourMixingRatio(
102                name="vapour", var="water_vapour_mixing_ratio"
103            ),
104        )
105        super().__init__(
106            particulator=builder.build(attributes=attributes, products=self.products)
107        )
108
109    def run(self, *, nt, steps_per_output_interval):
110        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)
Simulation(settings)
 25    def __init__(self, settings):
 26        builder = Builder(
 27            backend=settings.backend,
 28            n_sd=settings.n_sd,
 29            environment=Parcel(
 30                dt=settings.timestep,
 31                mass_of_dry_air=settings.mass_of_dry_air,
 32                p0=settings.initial_total_pressure,
 33                initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
 34                T0=settings.initial_temperature,
 35                w=settings.updraft,
 36                mixed_phase=True,
 37            ),
 38        )
 39        builder.add_dynamic(AmbientThermodynamics())
 40        builder.add_dynamic(Condensation())
 41
 42        if settings.enable_immersion_freezing:
 43            builder.add_dynamic(
 44                Freezing(
 45                    immersion_freezing=(
 46                        "singular" if settings.singular else "time-dependent"
 47                    )
 48                )
 49            )
 50        if settings.enable_vapour_deposition_on_ice:
 51            builder.add_dynamic(VapourDepositionOnIce(adaptive=True))
 52
 53        r_dry, n_in_dv = ConstantMultiplicity(settings.soluble_aerosol).sample(
 54            n_sd=settings.n_sd
 55        )
 56        attributes = builder.particulator.environment.init_attributes(
 57            n_in_dv=n_in_dv, kappa=settings.kappa, r_dry=r_dry
 58        )
 59        attributes["signed water mass"] = (
 60            builder.particulator.formulae.particle_shape_and_density.volume_to_mass(
 61                attributes["volume"]
 62            )
 63        )
 64        del attributes["volume"]
 65
 66        if settings.enable_immersion_freezing:
 67            trivia = builder.particulator.formulae.trivia
 68            n_inp = int(settings.n_sd * settings.freezing_inp_frac)
 69
 70            rng = np.random.default_rng(seed=builder.particulator.formulae.seed)
 71            insoluble_surface_area = trivia.sphere_surface(
 72                diameter=2 * settings.freezing_inp_dry_radius
 73            )
 74            attributes[
 75                "freezing temperature" if settings.singular else "immersed surface area"
 76            ] = rng.permutation(
 77                np.pad(
 78                    (
 79                        builder.particulator.formulae.freezing_temperature_spectrum.invcdf(
 80                            cdf=rng.uniform(low=0, high=1, size=n_inp),
 81                            A_insol=insoluble_surface_area,
 82                        )
 83                        if settings.singular
 84                        else np.full(n_inp, insoluble_surface_area)
 85                    ),
 86                    (0, settings.n_sd - n_inp),
 87                    mode="constant",
 88                    constant_values=(
 89                        builder.particulator.formulae.constants.HOMOGENEOUS_FREEZING_THRESHOLD
 90                        if settings.singular
 91                        else 0
 92                    ),
 93                )
 94            )
 95
 96        self.products = (
 97            WaterMixingRatio(name="water", radius_range=(0, np.inf)),
 98            SpecificIceWaterContent(name="ice"),
 99            ParcelDisplacement(name="height"),
100            AmbientTemperature(name="T"),
101            AmbientWaterVapourMixingRatio(
102                name="vapour", var="water_vapour_mixing_ratio"
103            ),
104        )
105        super().__init__(
106            particulator=builder.build(attributes=attributes, products=self.products)
107        )
products
def run(self, *, nt, steps_per_output_interval):
109    def run(self, *, nt, steps_per_output_interval):
110        return self._run(nt=nt, steps_per_output_interval=steps_per_output_interval)