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 )