PySDM_examples.seeding.simulation
1import numpy as np 2 3from PySDM_examples.seeding.settings import Settings 4 5from PySDM import Builder 6from PySDM.backends import CPU 7from PySDM.environments import Parcel 8from PySDM.dynamics import Condensation, AmbientThermodynamics, Coalescence, Seeding 9from PySDM.dynamics.collisions.collision_kernels import Geometric 10from PySDM.initialisation.sampling.spectral_sampling import ConstantMultiplicity 11from PySDM import products 12from PySDM.physics import si 13 14 15class Simulation: 16 def __init__(self, settings: Settings): 17 builder = Builder( 18 n_sd=settings.n_sd_seeding + settings.n_sd_initial, 19 backend=CPU( 20 formulae=settings.formulae, override_jit_flags={"parallel": False} 21 ), 22 environment=Parcel( 23 dt=settings.timestep, 24 mass_of_dry_air=settings.mass_of_dry_air, 25 w=settings.updraft, 26 initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio, 27 p0=settings.initial_total_pressure, 28 T0=settings.initial_temperature, 29 ), 30 ) 31 builder.add_dynamic(AmbientThermodynamics()) 32 builder.add_dynamic(Condensation()) 33 if settings.enable_collisions: 34 builder.add_dynamic(Coalescence(collision_kernel=Geometric())) 35 builder.add_dynamic( 36 Seeding( 37 super_droplet_injection_rate=settings.super_droplet_injection_rate, 38 seeded_particle_multiplicity=settings.seeded_particle_multiplicity, 39 seeded_particle_extensive_attributes=settings.seeded_particle_extensive_attributes, 40 ) 41 ) 42 43 r_dry, n_in_dv = ConstantMultiplicity( 44 settings.initial_aerosol_dry_radii 45 ).sample_deterministic( 46 n_sd=settings.n_sd_initial, backend=builder.particulator.backend 47 ) 48 attributes = builder.particulator.environment.init_attributes( 49 n_in_dv=n_in_dv, kappa=settings.initial_aerosol_kappa, r_dry=r_dry 50 ) 51 self.particulator = builder.build( 52 attributes={ 53 k: np.pad( 54 array=v, 55 pad_width=(0, settings.n_sd_seeding), 56 mode="constant", 57 constant_values=np.nan if k == "multiplicity" else 0, 58 ) 59 for k, v in attributes.items() 60 }, 61 products=( 62 products.SuperDropletCountPerGridbox(name="sd_count"), 63 products.Time(), 64 products.WaterMixingRatio( 65 radius_range=(settings.rain_water_radius_threshold, np.inf), 66 name="rain water mixing ratio", 67 ), 68 products.EffectiveRadius( 69 name="r_eff", 70 unit="um", 71 radius_range=(0.5 * si.um, 25 * si.um), 72 ), 73 products.ParticleConcentration( 74 name="n_drop", 75 unit="cm^-3", 76 radius_range=(0.5 * si.um, 25 * si.um), 77 ), 78 ), 79 ) 80 self.n_steps = int(settings.t_max // settings.timestep) 81 82 def run(self): 83 output = { 84 "attributes": {"water mass": []}, 85 "products": {key: [] for key in self.particulator.products}, 86 } 87 for step in range(self.n_steps + 1): 88 if step != 0: 89 self.particulator.run(steps=1) 90 for key, attr in output["attributes"].items(): 91 data = self.particulator.attributes[key].to_ndarray(raw=True) 92 data[data == 0] = np.nan 93 attr.append(data) 94 for key, prod in output["products"].items(): 95 value = self.particulator.products[key].get() 96 if not isinstance(value, float): 97 (value,) = value 98 prod.append(float(value)) 99 for out in ("attributes", "products"): 100 for key, val in output[out].items(): 101 output[out][key] = np.array(val) 102 return output
class
Simulation:
16class Simulation: 17 def __init__(self, settings: Settings): 18 builder = Builder( 19 n_sd=settings.n_sd_seeding + settings.n_sd_initial, 20 backend=CPU( 21 formulae=settings.formulae, override_jit_flags={"parallel": False} 22 ), 23 environment=Parcel( 24 dt=settings.timestep, 25 mass_of_dry_air=settings.mass_of_dry_air, 26 w=settings.updraft, 27 initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio, 28 p0=settings.initial_total_pressure, 29 T0=settings.initial_temperature, 30 ), 31 ) 32 builder.add_dynamic(AmbientThermodynamics()) 33 builder.add_dynamic(Condensation()) 34 if settings.enable_collisions: 35 builder.add_dynamic(Coalescence(collision_kernel=Geometric())) 36 builder.add_dynamic( 37 Seeding( 38 super_droplet_injection_rate=settings.super_droplet_injection_rate, 39 seeded_particle_multiplicity=settings.seeded_particle_multiplicity, 40 seeded_particle_extensive_attributes=settings.seeded_particle_extensive_attributes, 41 ) 42 ) 43 44 r_dry, n_in_dv = ConstantMultiplicity( 45 settings.initial_aerosol_dry_radii 46 ).sample_deterministic( 47 n_sd=settings.n_sd_initial, backend=builder.particulator.backend 48 ) 49 attributes = builder.particulator.environment.init_attributes( 50 n_in_dv=n_in_dv, kappa=settings.initial_aerosol_kappa, r_dry=r_dry 51 ) 52 self.particulator = builder.build( 53 attributes={ 54 k: np.pad( 55 array=v, 56 pad_width=(0, settings.n_sd_seeding), 57 mode="constant", 58 constant_values=np.nan if k == "multiplicity" else 0, 59 ) 60 for k, v in attributes.items() 61 }, 62 products=( 63 products.SuperDropletCountPerGridbox(name="sd_count"), 64 products.Time(), 65 products.WaterMixingRatio( 66 radius_range=(settings.rain_water_radius_threshold, np.inf), 67 name="rain water mixing ratio", 68 ), 69 products.EffectiveRadius( 70 name="r_eff", 71 unit="um", 72 radius_range=(0.5 * si.um, 25 * si.um), 73 ), 74 products.ParticleConcentration( 75 name="n_drop", 76 unit="cm^-3", 77 radius_range=(0.5 * si.um, 25 * si.um), 78 ), 79 ), 80 ) 81 self.n_steps = int(settings.t_max // settings.timestep) 82 83 def run(self): 84 output = { 85 "attributes": {"water mass": []}, 86 "products": {key: [] for key in self.particulator.products}, 87 } 88 for step in range(self.n_steps + 1): 89 if step != 0: 90 self.particulator.run(steps=1) 91 for key, attr in output["attributes"].items(): 92 data = self.particulator.attributes[key].to_ndarray(raw=True) 93 data[data == 0] = np.nan 94 attr.append(data) 95 for key, prod in output["products"].items(): 96 value = self.particulator.products[key].get() 97 if not isinstance(value, float): 98 (value,) = value 99 prod.append(float(value)) 100 for out in ("attributes", "products"): 101 for key, val in output[out].items(): 102 output[out][key] = np.array(val) 103 return output
Simulation(settings: PySDM_examples.seeding.settings.Settings)
17 def __init__(self, settings: Settings): 18 builder = Builder( 19 n_sd=settings.n_sd_seeding + settings.n_sd_initial, 20 backend=CPU( 21 formulae=settings.formulae, override_jit_flags={"parallel": False} 22 ), 23 environment=Parcel( 24 dt=settings.timestep, 25 mass_of_dry_air=settings.mass_of_dry_air, 26 w=settings.updraft, 27 initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio, 28 p0=settings.initial_total_pressure, 29 T0=settings.initial_temperature, 30 ), 31 ) 32 builder.add_dynamic(AmbientThermodynamics()) 33 builder.add_dynamic(Condensation()) 34 if settings.enable_collisions: 35 builder.add_dynamic(Coalescence(collision_kernel=Geometric())) 36 builder.add_dynamic( 37 Seeding( 38 super_droplet_injection_rate=settings.super_droplet_injection_rate, 39 seeded_particle_multiplicity=settings.seeded_particle_multiplicity, 40 seeded_particle_extensive_attributes=settings.seeded_particle_extensive_attributes, 41 ) 42 ) 43 44 r_dry, n_in_dv = ConstantMultiplicity( 45 settings.initial_aerosol_dry_radii 46 ).sample_deterministic( 47 n_sd=settings.n_sd_initial, backend=builder.particulator.backend 48 ) 49 attributes = builder.particulator.environment.init_attributes( 50 n_in_dv=n_in_dv, kappa=settings.initial_aerosol_kappa, r_dry=r_dry 51 ) 52 self.particulator = builder.build( 53 attributes={ 54 k: np.pad( 55 array=v, 56 pad_width=(0, settings.n_sd_seeding), 57 mode="constant", 58 constant_values=np.nan if k == "multiplicity" else 0, 59 ) 60 for k, v in attributes.items() 61 }, 62 products=( 63 products.SuperDropletCountPerGridbox(name="sd_count"), 64 products.Time(), 65 products.WaterMixingRatio( 66 radius_range=(settings.rain_water_radius_threshold, np.inf), 67 name="rain water mixing ratio", 68 ), 69 products.EffectiveRadius( 70 name="r_eff", 71 unit="um", 72 radius_range=(0.5 * si.um, 25 * si.um), 73 ), 74 products.ParticleConcentration( 75 name="n_drop", 76 unit="cm^-3", 77 radius_range=(0.5 * si.um, 25 * si.um), 78 ), 79 ), 80 ) 81 self.n_steps = int(settings.t_max // settings.timestep)
def
run(self):
83 def run(self): 84 output = { 85 "attributes": {"water mass": []}, 86 "products": {key: [] for key in self.particulator.products}, 87 } 88 for step in range(self.n_steps + 1): 89 if step != 0: 90 self.particulator.run(steps=1) 91 for key, attr in output["attributes"].items(): 92 data = self.particulator.attributes[key].to_ndarray(raw=True) 93 data[data == 0] = np.nan 94 attr.append(data) 95 for key, prod in output["products"].items(): 96 value = self.particulator.products[key].get() 97 if not isinstance(value, float): 98 (value,) = value 99 prod.append(float(value)) 100 for out in ("attributes", "products"): 101 for key, val in output[out].items(): 102 output[out][key] = np.array(val) 103 return output