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)