PySDM_examples.deJong_Mackay_et_al_2023.simulation_0D
1from collections import namedtuple 2 3import numpy as np 4 5from PySDM.backends import CPU 6from PySDM.builder import Builder 7from PySDM.dynamics import Coalescence, Collision 8from PySDM.environments import Box 9from PySDM.formulae import Formulae 10from PySDM.initialisation.sampling.spectral_sampling import ( 11 ConstantMultiplicity, 12 Logarithmic, 13) 14from PySDM.physics import si 15from PySDM.products.collision.collision_rates import ( 16 BreakupRatePerGridbox, 17 CoalescenceRatePerGridbox, 18 CollisionRateDeficitPerGridbox, 19 CollisionRatePerGridbox, 20) 21from PySDM.products.size_spectral import ( 22 NumberSizeSpectrum, 23 ParticleVolumeVersusRadiusLogarithmSpectrum, 24) 25 26 27def run_box_breakup( 28 settings, steps=None, backend_class=CPU, sample_in_radius=False, return_nv=False 29): 30 builder = Builder( 31 n_sd=settings.n_sd, 32 backend=backend_class(settings.formulae), 33 environment=Box(dv=settings.dv, dt=settings.dt), 34 dynamics=( 35 Collision( 36 collision_kernel=settings.kernel, 37 coalescence_efficiency=settings.coal_eff, 38 breakup_efficiency=settings.break_eff, 39 fragmentation_function=settings.fragmentation, 40 adaptive=settings.adaptive, 41 warn_overflows=settings.warn_overflows, 42 ), 43 ), 44 ) 45 builder.particulator.environment["rhod"] = 1.0 46 attributes = {} 47 if sample_in_radius: 48 diams, attributes["multiplicity"] = Logarithmic( 49 settings.spectrum 50 ).sample_deterministic(settings.n_sd) 51 radii = diams / 2 52 attributes["volume"] = Formulae().trivia.volume(radius=radii) 53 else: 54 attributes["volume"], attributes["multiplicity"] = ConstantMultiplicity( 55 settings.spectrum 56 ).sample_deterministic(settings.n_sd) 57 products = ( 58 ParticleVolumeVersusRadiusLogarithmSpectrum( 59 radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr" 60 ), 61 NumberSizeSpectrum(radius_bins_edges=settings.radius_bins_edges, name="N(v)"), 62 CollisionRatePerGridbox(name="cr"), 63 CollisionRateDeficitPerGridbox(name="crd"), 64 CoalescenceRatePerGridbox(name="cor"), 65 BreakupRatePerGridbox(name="br"), 66 ) 67 core = builder.build(attributes, products) 68 69 if steps is None: 70 steps = settings.output_steps 71 y = np.ndarray((len(steps), len(settings.radius_bins_edges) - 1)) 72 if return_nv: 73 y2 = np.ndarray((len(steps), len(settings.radius_bins_edges) - 1)) 74 else: 75 y2 = None 76 77 rates = np.zeros((len(steps), 4)) 78 # run 79 for i, step in enumerate(steps): 80 core.run(step - core.n_steps) 81 y[i] = core.products["dv/dlnr"].get()[0] 82 if return_nv: 83 (y2[i],) = core.products["N(v)"].get() 84 (rates[i, 0],) = core.products["cr"].get() 85 (rates[i, 1],) = core.products["crd"].get() 86 (rates[i, 2],) = core.products["cor"].get() 87 (rates[i, 3],) = core.products["br"].get() 88 89 x = (settings.radius_bins_edges[:-1] / si.micrometres,)[0] 90 91 return namedtuple("_", ("x", "y", "y2", "rates"))(x=x, y=y, y2=y2, rates=rates) 92 93 94def run_box_NObreakup(settings, steps=None, backend_class=CPU): 95 builder = Builder( 96 n_sd=settings.n_sd, 97 backend=backend_class(settings.formulae), 98 environment=Box(dv=settings.dv, dt=settings.dt), 99 dynamics=( 100 Coalescence( 101 collision_kernel=settings.kernel, 102 coalescence_efficiency=settings.coal_eff, 103 adaptive=settings.adaptive, 104 ), 105 ), 106 ) 107 builder.particulator.environment["rhod"] = 1.0 108 attributes = {} 109 attributes["volume"], attributes["multiplicity"] = ConstantMultiplicity( 110 settings.spectrum 111 ).sample_deterministic(settings.n_sd) 112 products = ( 113 ParticleVolumeVersusRadiusLogarithmSpectrum( 114 radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr" 115 ), 116 CollisionRatePerGridbox(name="cr"), 117 CollisionRateDeficitPerGridbox(name="crd"), 118 CoalescenceRatePerGridbox(name="cor"), 119 ) 120 core = builder.build(attributes, products) 121 122 if steps is None: 123 steps = settings.output_steps 124 y = np.ndarray((len(steps), len(settings.radius_bins_edges) - 1)) 125 rates = np.zeros((len(steps), 4)) 126 # run 127 for i, step in enumerate(steps): 128 core.run(step - core.n_steps) 129 (y[i],) = core.products["dv/dlnr"].get() 130 (rates[i, 0],) = core.products["cr"].get() 131 (rates[i, 1],) = core.products["crd"].get() 132 (rates[i, 2],) = core.products["cor"].get() 133 134 x = (settings.radius_bins_edges[:-1] / si.micrometres,)[0] 135 136 return (x, y, rates)
def
run_box_breakup( settings, steps=None, backend_class=functools.partial(<function _cached_backend>, backend_class=<class 'PySDM.backends.Numba'>), sample_in_radius=False, return_nv=False):
28def run_box_breakup( 29 settings, steps=None, backend_class=CPU, sample_in_radius=False, return_nv=False 30): 31 builder = Builder( 32 n_sd=settings.n_sd, 33 backend=backend_class(settings.formulae), 34 environment=Box(dv=settings.dv, dt=settings.dt), 35 dynamics=( 36 Collision( 37 collision_kernel=settings.kernel, 38 coalescence_efficiency=settings.coal_eff, 39 breakup_efficiency=settings.break_eff, 40 fragmentation_function=settings.fragmentation, 41 adaptive=settings.adaptive, 42 warn_overflows=settings.warn_overflows, 43 ), 44 ), 45 ) 46 builder.particulator.environment["rhod"] = 1.0 47 attributes = {} 48 if sample_in_radius: 49 diams, attributes["multiplicity"] = Logarithmic( 50 settings.spectrum 51 ).sample_deterministic(settings.n_sd) 52 radii = diams / 2 53 attributes["volume"] = Formulae().trivia.volume(radius=radii) 54 else: 55 attributes["volume"], attributes["multiplicity"] = ConstantMultiplicity( 56 settings.spectrum 57 ).sample_deterministic(settings.n_sd) 58 products = ( 59 ParticleVolumeVersusRadiusLogarithmSpectrum( 60 radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr" 61 ), 62 NumberSizeSpectrum(radius_bins_edges=settings.radius_bins_edges, name="N(v)"), 63 CollisionRatePerGridbox(name="cr"), 64 CollisionRateDeficitPerGridbox(name="crd"), 65 CoalescenceRatePerGridbox(name="cor"), 66 BreakupRatePerGridbox(name="br"), 67 ) 68 core = builder.build(attributes, products) 69 70 if steps is None: 71 steps = settings.output_steps 72 y = np.ndarray((len(steps), len(settings.radius_bins_edges) - 1)) 73 if return_nv: 74 y2 = np.ndarray((len(steps), len(settings.radius_bins_edges) - 1)) 75 else: 76 y2 = None 77 78 rates = np.zeros((len(steps), 4)) 79 # run 80 for i, step in enumerate(steps): 81 core.run(step - core.n_steps) 82 y[i] = core.products["dv/dlnr"].get()[0] 83 if return_nv: 84 (y2[i],) = core.products["N(v)"].get() 85 (rates[i, 0],) = core.products["cr"].get() 86 (rates[i, 1],) = core.products["crd"].get() 87 (rates[i, 2],) = core.products["cor"].get() 88 (rates[i, 3],) = core.products["br"].get() 89 90 x = (settings.radius_bins_edges[:-1] / si.micrometres,)[0] 91 92 return namedtuple("_", ("x", "y", "y2", "rates"))(x=x, y=y, y2=y2, rates=rates)
def
run_box_NObreakup( settings, steps=None, backend_class=functools.partial(<function _cached_backend>, backend_class=<class 'PySDM.backends.Numba'>)):
95def run_box_NObreakup(settings, steps=None, backend_class=CPU): 96 builder = Builder( 97 n_sd=settings.n_sd, 98 backend=backend_class(settings.formulae), 99 environment=Box(dv=settings.dv, dt=settings.dt), 100 dynamics=( 101 Coalescence( 102 collision_kernel=settings.kernel, 103 coalescence_efficiency=settings.coal_eff, 104 adaptive=settings.adaptive, 105 ), 106 ), 107 ) 108 builder.particulator.environment["rhod"] = 1.0 109 attributes = {} 110 attributes["volume"], attributes["multiplicity"] = ConstantMultiplicity( 111 settings.spectrum 112 ).sample_deterministic(settings.n_sd) 113 products = ( 114 ParticleVolumeVersusRadiusLogarithmSpectrum( 115 radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr" 116 ), 117 CollisionRatePerGridbox(name="cr"), 118 CollisionRateDeficitPerGridbox(name="crd"), 119 CoalescenceRatePerGridbox(name="cor"), 120 ) 121 core = builder.build(attributes, products) 122 123 if steps is None: 124 steps = settings.output_steps 125 y = np.ndarray((len(steps), len(settings.radius_bins_edges) - 1)) 126 rates = np.zeros((len(steps), 4)) 127 # run 128 for i, step in enumerate(steps): 129 core.run(step - core.n_steps) 130 (y[i],) = core.products["dv/dlnr"].get() 131 (rates[i, 0],) = core.products["cr"].get() 132 (rates[i, 1],) = core.products["crd"].get() 133 (rates[i, 2],) = core.products["cor"].get() 134 135 x = (settings.radius_bins_edges[:-1] / si.micrometres,)[0] 136 137 return (x, y, rates)