PySDM_examples.Arabas_et_al_2025.make_particulator
1import numpy as np 2 3from PySDM import Builder, Formulae 4from PySDM import products as PySDM_products 5from PySDM.backends import CPU 6from PySDM.dynamics import Freezing 7from PySDM.environments import Box 8from PySDM.initialisation.sampling.spectro_glacial_sampling import ( 9 SpectroGlacialSampling, 10) 11 12A_VALUE_LARGER_THAN_ONE = 44 13 14 15def make_particulator( 16 *, 17 constants, 18 n_sd, 19 dt, 20 initial_temperature, 21 singular, 22 seed, 23 shima_T_fz, 24 ABIFM_spec, 25 droplet_volume, 26 total_particle_number, 27 volume, 28 thaw=False, 29): 30 formulae_ctor_args = { 31 "seed": seed, 32 "constants": constants, 33 "freezing_temperature_spectrum": shima_T_fz, 34 "heterogeneous_ice_nucleation_rate": "ABIFM", 35 "particle_shape_and_density": "MixedPhaseSpheres", 36 } 37 formulae = Formulae(**formulae_ctor_args) 38 backend = CPU(formulae, override_jit_flags={"parallel": False}) 39 40 attributes = { 41 "signed water mass": np.ones(n_sd) * droplet_volume * formulae.constants.rho_w 42 } 43 44 sampling = SpectroGlacialSampling( 45 freezing_temperature_spectrum=formulae.freezing_temperature_spectrum, 46 insoluble_surface_spectrum=ABIFM_spec, 47 ) 48 if singular: 49 ( 50 attributes["freezing temperature"], 51 _, 52 attributes["multiplicity"], 53 ) = sampling.sample(backend=backend, n_sd=n_sd) 54 immersion_freezing_flag = "singular" 55 else: 56 ( 57 _, 58 attributes["immersed surface area"], 59 attributes["multiplicity"], 60 ) = sampling.sample(backend=backend, n_sd=n_sd) 61 immersion_freezing_flag = "time-dependent" 62 if thaw: 63 thaw_flag = "instantaneous" 64 else: 65 thaw_flag = None 66 attributes["multiplicity"] *= total_particle_number 67 68 builder = Builder( 69 n_sd=n_sd, 70 backend=backend, 71 environment=Box(dt, volume), 72 dynamics=[Freezing(immersion_freezing=immersion_freezing_flag, thaw=thaw_flag)], 73 ) 74 75 env = builder.particulator.environment 76 env["T"] = initial_temperature 77 env["RH"] = A_VALUE_LARGER_THAN_ONE 78 env["rhod"] = 1.0 79 80 builder.request_attribute("volume") 81 82 return builder.build( 83 attributes=attributes, 84 products=( 85 PySDM_products.Time(name="t"), 86 PySDM_products.AmbientTemperature(name="T"), 87 PySDM_products.SpecificIceWaterContent(name="qi"), 88 ), 89 )
A_VALUE_LARGER_THAN_ONE =
44
def
make_particulator( *, constants, n_sd, dt, initial_temperature, singular, seed, shima_T_fz, ABIFM_spec, droplet_volume, total_particle_number, volume, thaw=False):
16def make_particulator( 17 *, 18 constants, 19 n_sd, 20 dt, 21 initial_temperature, 22 singular, 23 seed, 24 shima_T_fz, 25 ABIFM_spec, 26 droplet_volume, 27 total_particle_number, 28 volume, 29 thaw=False, 30): 31 formulae_ctor_args = { 32 "seed": seed, 33 "constants": constants, 34 "freezing_temperature_spectrum": shima_T_fz, 35 "heterogeneous_ice_nucleation_rate": "ABIFM", 36 "particle_shape_and_density": "MixedPhaseSpheres", 37 } 38 formulae = Formulae(**formulae_ctor_args) 39 backend = CPU(formulae, override_jit_flags={"parallel": False}) 40 41 attributes = { 42 "signed water mass": np.ones(n_sd) * droplet_volume * formulae.constants.rho_w 43 } 44 45 sampling = SpectroGlacialSampling( 46 freezing_temperature_spectrum=formulae.freezing_temperature_spectrum, 47 insoluble_surface_spectrum=ABIFM_spec, 48 ) 49 if singular: 50 ( 51 attributes["freezing temperature"], 52 _, 53 attributes["multiplicity"], 54 ) = sampling.sample(backend=backend, n_sd=n_sd) 55 immersion_freezing_flag = "singular" 56 else: 57 ( 58 _, 59 attributes["immersed surface area"], 60 attributes["multiplicity"], 61 ) = sampling.sample(backend=backend, n_sd=n_sd) 62 immersion_freezing_flag = "time-dependent" 63 if thaw: 64 thaw_flag = "instantaneous" 65 else: 66 thaw_flag = None 67 attributes["multiplicity"] *= total_particle_number 68 69 builder = Builder( 70 n_sd=n_sd, 71 backend=backend, 72 environment=Box(dt, volume), 73 dynamics=[Freezing(immersion_freezing=immersion_freezing_flag, thaw=thaw_flag)], 74 ) 75 76 env = builder.particulator.environment 77 env["T"] = initial_temperature 78 env["RH"] = A_VALUE_LARGER_THAN_ONE 79 env["rhod"] = 1.0 80 81 builder.request_attribute("volume") 82 83 return builder.build( 84 attributes=attributes, 85 products=( 86 PySDM_products.Time(name="t"), 87 PySDM_products.AmbientTemperature(name="T"), 88 PySDM_products.SpecificIceWaterContent(name="qi"), 89 ), 90 )