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
8from PySDM.environments import Box
9from PySDM.initialisation.sampling.spectral_sampling import ConstantMultiplicity
10from PySDM.products.size_spectral import (
11 ParticleVolumeVersusRadiusLogarithmSpectrum,
12 VolumeFirstMoment,
13 VolumeSecondMoment,
14 ZerothMoment,
15)
16
17
18def run_box(settings, backend_class=CPU):
19 builder = Builder(
20 n_sd=settings.n_sd,
21 backend=backend_class(settings.formulae),
22 environment=Box(dv=settings.dv, dt=settings.dt),
23 )
24 builder.particulator.environment["rhod"] = settings.rhod
25 attributes = {}
26 attributes["volume"], attributes["multiplicity"] = ConstantMultiplicity(
27 settings.spectrum
28 ).sample(settings.n_sd)
29 builder.add_dynamic(
30 Coalescence(
31 collision_kernel=settings.kernel,
32 coalescence_efficiency=settings.coal_eff,
33 adaptive=settings.adaptive,
34 )
35 )
36 products = (
37 ParticleVolumeVersusRadiusLogarithmSpectrum(
38 radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr"
39 ),
40 ZerothMoment(name="M0"),
41 VolumeFirstMoment(name="M1"),
42 VolumeSecondMoment(name="M2"),
43 )
44 particulator = builder.build(attributes, products)
45
46 y = np.ndarray((len(settings.steps), len(settings.radius_bins_edges) - 1))
47 mom = np.ndarray((len(settings.steps), 3))
48 for i, step in enumerate(settings.steps):
49 particulator.run(step - particulator.n_steps)
50 y[i] = particulator.products["dv/dlnr"].get()[0]
51 (mom[i, 0],) = particulator.products["M0"].get()
52 (mom[i, 1],) = particulator.products["M1"].get()
53 (mom[i, 2],) = particulator.products["M2"].get()
54
55 return namedtuple("_", ("radius_bins_left_edges", "dv_dlnr", "moments"))(
56 radius_bins_left_edges=settings.radius_bins_edges[:-1], dv_dlnr=y, moments=mom
57 )