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 )