PySDM_examples.sandbox.Spichtinger_et_al_2023.simulation
1import numpy as np 2 3from PySDM_examples.utils import BasicSimulation 4 5import PySDM.products as PySDM_products 6from PySDM.backends import Numba 7from PySDM import Particulator 8from PySDM.dynamics import ( 9 AmbientThermodynamics, 10 Condensation, 11 Freezing, 12 VapourDepositionOnIce, 13) 14from PySDM.environments import Parcel 15from PySDM.initialisation import discretise_multiplicities 16from PySDM.initialisation.hygroscopic_equilibrium import equilibrate_wet_radii 17 18 19class Simulation(BasicSimulation): 20 def __init__(self, settings, backend=Numba): 21 22 dt = settings.dt 23 24 formulae = settings.formulae 25 26 env = Parcel( 27 mixed_phase=True, 28 dt=dt, 29 mass_of_dry_air=settings.mass_of_dry_air, 30 p0=settings.initial_pressure, 31 initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio, 32 T0=settings.initial_temperature, 33 w=settings.w_updraft, 34 backend=backend(formulae=settings.formulae), 35 ) 36 37 self.n_sd = settings.n_sd 38 self.multiplicities = discretise_multiplicities( 39 settings.specific_concentration * env.mass_of_dry_air 40 ) 41 self.r_dry = settings.r_dry 42 v_dry = settings.formulae.trivia.volume(radius=self.r_dry) 43 kappa = settings.kappa 44 45 self.r_wet = equilibrate_wet_radii( 46 r_dry=self.r_dry, 47 environment=env, 48 kappa_times_dry_volume=kappa * v_dry, 49 ) 50 51 attributes = { 52 "multiplicity": self.multiplicities, 53 "dry volume": v_dry, 54 "kappa times dry volume": kappa * v_dry, 55 "signed water mass": formulae.particle_shape_and_density.radius_to_mass( 56 self.r_wet 57 ), 58 } 59 60 products = [ 61 PySDM_products.Time(name="t"), 62 PySDM_products.AmbientRelativeHumidity(name="RH_ice", unit="%"), 63 PySDM_products.ParticleConcentration( 64 name="n_i", unit="1/m**3", radius_range=(-np.inf, 0) 65 ), 66 ] 67 68 self.n_output = settings.n_output 69 self.n_substeps = int(settings.t_duration / dt / self.n_output) 70 super().__init__( 71 Particulator( 72 attributes=attributes, 73 products=products, 74 n_sd=settings.n_sd, 75 environment=env, 76 dynamics=( 77 AmbientThermodynamics(), 78 Condensation(), 79 VapourDepositionOnIce(), 80 Freezing( 81 homogeneous_freezing="time-dependent", immersion_freezing=None 82 ), 83 ), 84 ) 85 ) 86 87 def save(self, output): 88 cell_id = 0 89 output["t"].append(self.particulator.products["t"].get()) 90 output["ni"].append(self.particulator.products["n_i"].get()[cell_id]) 91 output["RHi"].append(self.particulator.products["RH_ice"].get()[cell_id]) 92 93 def run(self): 94 output = { 95 "t": [], 96 "ni": [], 97 "RHi": [], 98 } 99 100 self.save(output) 101 102 RHi_old = self.particulator.products["RH_ice"].get()[0].copy() 103 for _ in range(self.n_output): 104 105 self.particulator.advance(self.n_substeps) 106 107 self.save(output) 108 109 RHi = self.particulator.products["RH_ice"].get()[0].copy() 110 dRHi = (RHi_old - RHi) / RHi_old 111 if dRHi > 0.0 and RHi < 130.0: 112 print("break") 113 break 114 RHi_old = RHi 115 116 return output["ni"][-1]
20class Simulation(BasicSimulation): 21 def __init__(self, settings, backend=Numba): 22 23 dt = settings.dt 24 25 formulae = settings.formulae 26 27 env = Parcel( 28 mixed_phase=True, 29 dt=dt, 30 mass_of_dry_air=settings.mass_of_dry_air, 31 p0=settings.initial_pressure, 32 initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio, 33 T0=settings.initial_temperature, 34 w=settings.w_updraft, 35 backend=backend(formulae=settings.formulae), 36 ) 37 38 self.n_sd = settings.n_sd 39 self.multiplicities = discretise_multiplicities( 40 settings.specific_concentration * env.mass_of_dry_air 41 ) 42 self.r_dry = settings.r_dry 43 v_dry = settings.formulae.trivia.volume(radius=self.r_dry) 44 kappa = settings.kappa 45 46 self.r_wet = equilibrate_wet_radii( 47 r_dry=self.r_dry, 48 environment=env, 49 kappa_times_dry_volume=kappa * v_dry, 50 ) 51 52 attributes = { 53 "multiplicity": self.multiplicities, 54 "dry volume": v_dry, 55 "kappa times dry volume": kappa * v_dry, 56 "signed water mass": formulae.particle_shape_and_density.radius_to_mass( 57 self.r_wet 58 ), 59 } 60 61 products = [ 62 PySDM_products.Time(name="t"), 63 PySDM_products.AmbientRelativeHumidity(name="RH_ice", unit="%"), 64 PySDM_products.ParticleConcentration( 65 name="n_i", unit="1/m**3", radius_range=(-np.inf, 0) 66 ), 67 ] 68 69 self.n_output = settings.n_output 70 self.n_substeps = int(settings.t_duration / dt / self.n_output) 71 super().__init__( 72 Particulator( 73 attributes=attributes, 74 products=products, 75 n_sd=settings.n_sd, 76 environment=env, 77 dynamics=( 78 AmbientThermodynamics(), 79 Condensation(), 80 VapourDepositionOnIce(), 81 Freezing( 82 homogeneous_freezing="time-dependent", immersion_freezing=None 83 ), 84 ), 85 ) 86 ) 87 88 def save(self, output): 89 cell_id = 0 90 output["t"].append(self.particulator.products["t"].get()) 91 output["ni"].append(self.particulator.products["n_i"].get()[cell_id]) 92 output["RHi"].append(self.particulator.products["RH_ice"].get()[cell_id]) 93 94 def run(self): 95 output = { 96 "t": [], 97 "ni": [], 98 "RHi": [], 99 } 100 101 self.save(output) 102 103 RHi_old = self.particulator.products["RH_ice"].get()[0].copy() 104 for _ in range(self.n_output): 105 106 self.particulator.advance(self.n_substeps) 107 108 self.save(output) 109 110 RHi = self.particulator.products["RH_ice"].get()[0].copy() 111 dRHi = (RHi_old - RHi) / RHi_old 112 if dRHi > 0.0 and RHi < 130.0: 113 print("break") 114 break 115 RHi_old = RHi 116 117 return output["ni"][-1]
Simulation(settings, backend=<class 'PySDM.backends.Numba'>)
21 def __init__(self, settings, backend=Numba): 22 23 dt = settings.dt 24 25 formulae = settings.formulae 26 27 env = Parcel( 28 mixed_phase=True, 29 dt=dt, 30 mass_of_dry_air=settings.mass_of_dry_air, 31 p0=settings.initial_pressure, 32 initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio, 33 T0=settings.initial_temperature, 34 w=settings.w_updraft, 35 backend=backend(formulae=settings.formulae), 36 ) 37 38 self.n_sd = settings.n_sd 39 self.multiplicities = discretise_multiplicities( 40 settings.specific_concentration * env.mass_of_dry_air 41 ) 42 self.r_dry = settings.r_dry 43 v_dry = settings.formulae.trivia.volume(radius=self.r_dry) 44 kappa = settings.kappa 45 46 self.r_wet = equilibrate_wet_radii( 47 r_dry=self.r_dry, 48 environment=env, 49 kappa_times_dry_volume=kappa * v_dry, 50 ) 51 52 attributes = { 53 "multiplicity": self.multiplicities, 54 "dry volume": v_dry, 55 "kappa times dry volume": kappa * v_dry, 56 "signed water mass": formulae.particle_shape_and_density.radius_to_mass( 57 self.r_wet 58 ), 59 } 60 61 products = [ 62 PySDM_products.Time(name="t"), 63 PySDM_products.AmbientRelativeHumidity(name="RH_ice", unit="%"), 64 PySDM_products.ParticleConcentration( 65 name="n_i", unit="1/m**3", radius_range=(-np.inf, 0) 66 ), 67 ] 68 69 self.n_output = settings.n_output 70 self.n_substeps = int(settings.t_duration / dt / self.n_output) 71 super().__init__( 72 Particulator( 73 attributes=attributes, 74 products=products, 75 n_sd=settings.n_sd, 76 environment=env, 77 dynamics=( 78 AmbientThermodynamics(), 79 Condensation(), 80 VapourDepositionOnIce(), 81 Freezing( 82 homogeneous_freezing="time-dependent", immersion_freezing=None 83 ), 84 ), 85 ) 86 )
def
run(self):
94 def run(self): 95 output = { 96 "t": [], 97 "ni": [], 98 "RHi": [], 99 } 100 101 self.save(output) 102 103 RHi_old = self.particulator.products["RH_ice"].get()[0].copy() 104 for _ in range(self.n_output): 105 106 self.particulator.advance(self.n_substeps) 107 108 self.save(output) 109 110 RHi = self.particulator.products["RH_ice"].get()[0].copy() 111 dRHi = (RHi_old - RHi) / RHi_old 112 if dRHi > 0.0 and RHi < 130.0: 113 print("break") 114 break 115 RHi_old = RHi 116 117 return output["ni"][-1]