PySDM-examples 2.129__py3-none-any.whl → 2.130__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PySDM_examples/Spichtinger_et_al_2023/__init__.py +7 -0
- PySDM_examples/Spichtinger_et_al_2023/data/__init__.py +0 -0
- PySDM_examples/Spichtinger_et_al_2023/data/reference_bulk.py +47 -0
- PySDM_examples/Spichtinger_et_al_2023/data/simulation_data.py +22 -0
- PySDM_examples/Spichtinger_et_al_2023/settings.py +66 -0
- PySDM_examples/Spichtinger_et_al_2023/simulation.py +121 -0
- {pysdm_examples-2.129.dist-info → pysdm_examples-2.130.dist-info}/METADATA +3 -1
- {pysdm_examples-2.129.dist-info → pysdm_examples-2.130.dist-info}/RECORD +10 -4
- {pysdm_examples-2.129.dist-info → pysdm_examples-2.130.dist-info}/WHEEL +0 -0
- {pysdm_examples-2.129.dist-info → pysdm_examples-2.130.dist-info}/top_level.txt +0 -0
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
reference results for bulk scheme in Fig B1. in
|
|
3
|
+
[Spichtinger et al. 2023](https://doi.org/10.5194/acp-23-2035-2023)
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def bulk_model_reference_array():
|
|
10
|
+
|
|
11
|
+
initial_temperatures = np.array([196.0, 216.0, 236.0])
|
|
12
|
+
updrafts = np.array([0.05, 0.1, 0.3, 0.5, 1.0, 3.0, 5.0, 10.0])
|
|
13
|
+
|
|
14
|
+
dim_size = (np.shape(initial_temperatures)[0], np.shape(updrafts)[0])
|
|
15
|
+
ni_bulk_ref = np.zeros(dim_size)
|
|
16
|
+
|
|
17
|
+
# T = 196
|
|
18
|
+
ni_bulk_ref[0, 0] = 643686.1316903427
|
|
19
|
+
ni_bulk_ref[0, 1] = 2368481.0609527444
|
|
20
|
+
ni_bulk_ref[0, 2] = 20160966.984670535
|
|
21
|
+
ni_bulk_ref[0, 3] = 49475281.81718969
|
|
22
|
+
ni_bulk_ref[0, 4] = 131080662.23620115
|
|
23
|
+
ni_bulk_ref[0, 5] = 401046528.70428866
|
|
24
|
+
ni_bulk_ref[0, 6] = 627442148.3402529
|
|
25
|
+
ni_bulk_ref[0, 7] = 1151707310.2210448
|
|
26
|
+
|
|
27
|
+
# T = 216
|
|
28
|
+
ni_bulk_ref[1, 0] = 60955.84292640147
|
|
29
|
+
ni_bulk_ref[1, 1] = 189002.0792186534
|
|
30
|
+
ni_bulk_ref[1, 2] = 1200751.6897658105
|
|
31
|
+
ni_bulk_ref[1, 3] = 2942110.815055958
|
|
32
|
+
ni_bulk_ref[1, 4] = 10475282.894692907
|
|
33
|
+
ni_bulk_ref[1, 5] = 90871045.40856971
|
|
34
|
+
ni_bulk_ref[1, 6] = 252175505.460412
|
|
35
|
+
ni_bulk_ref[1, 7] = 860335156.4717773
|
|
36
|
+
|
|
37
|
+
# T = 236
|
|
38
|
+
ni_bulk_ref[2, 0] = 13049.108886452004
|
|
39
|
+
ni_bulk_ref[2, 1] = 40422.244759544985
|
|
40
|
+
ni_bulk_ref[2, 2] = 237862.49854786208
|
|
41
|
+
ni_bulk_ref[2, 3] = 545315.7805748513
|
|
42
|
+
ni_bulk_ref[2, 4] = 1707801.469906006
|
|
43
|
+
ni_bulk_ref[2, 5] = 11128055.66932415
|
|
44
|
+
ni_bulk_ref[2, 6] = 27739585.111447476
|
|
45
|
+
ni_bulk_ref[2, 7] = 101799566.47225031
|
|
46
|
+
|
|
47
|
+
return initial_temperatures, updrafts, ni_bulk_ref
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def saved_simulation_ensemble_mean():
|
|
5
|
+
|
|
6
|
+
ni_ens_mean = np.array(
|
|
7
|
+
[
|
|
8
|
+
[0.00000000e00, 0.00000000e00, 0.00000000e00],
|
|
9
|
+
[0.00000000e00, 0.00000000e00, 0.00000000e00],
|
|
10
|
+
[1.62069821e03, 0.00000000e00, 0.00000000e00],
|
|
11
|
+
[5.25377025e06, 9.75512904e05, 4.51431097e05],
|
|
12
|
+
[3.67137290e07, 5.45240337e06, 1.53884530e06],
|
|
13
|
+
[7.96514420e07, 1.13878118e07, 3.26386880e06],
|
|
14
|
+
[2.19385480e08, 3.62240242e07, 9.00657591e06],
|
|
15
|
+
[1.00631095e09, 2.34443408e08, 4.90577208e07],
|
|
16
|
+
[1.73457062e09, 5.20774276e08, 1.16040316e08],
|
|
17
|
+
]
|
|
18
|
+
)
|
|
19
|
+
T = np.array([196.0, 216.0, 236.0])
|
|
20
|
+
w = np.array([0.01, 0.03, 0.05, 0.1, 0.3, 0.5, 1.0, 3.0, 5.0])
|
|
21
|
+
|
|
22
|
+
return T, w, ni_ens_mean
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from pystrict import strict
|
|
2
|
+
|
|
3
|
+
from PySDM import Formulae
|
|
4
|
+
from PySDM.physics.constants import si
|
|
5
|
+
from PySDM.initialisation.spectra import Lognormal
|
|
6
|
+
from PySDM.initialisation.sampling import spectral_sampling
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@strict
|
|
10
|
+
class Settings:
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
*,
|
|
14
|
+
n_sd: int,
|
|
15
|
+
w_updraft: float,
|
|
16
|
+
T0: float,
|
|
17
|
+
seed: int,
|
|
18
|
+
dt: float,
|
|
19
|
+
):
|
|
20
|
+
|
|
21
|
+
self.n_sd = n_sd
|
|
22
|
+
self.w_updraft = w_updraft
|
|
23
|
+
|
|
24
|
+
self.N_dv_solution_droplet = 2500 / si.centimetre**3
|
|
25
|
+
self.r_mean_solution_droplet = 0.055 * si.micrometre
|
|
26
|
+
self.sigma_solution_droplet = 1.6
|
|
27
|
+
|
|
28
|
+
self.mass_of_dry_air = 1000 * si.kilogram
|
|
29
|
+
self.initial_pressure = 200 * si.hectopascals
|
|
30
|
+
self.initial_ice_supersaturation = 1.0
|
|
31
|
+
self.kappa = 0.64
|
|
32
|
+
self.initial_temperature = T0
|
|
33
|
+
|
|
34
|
+
self.formulae = Formulae(
|
|
35
|
+
particle_shape_and_density="MixedPhaseSpheres",
|
|
36
|
+
homogeneous_ice_nucleation_rate="Koop_Correction",
|
|
37
|
+
seed=seed,
|
|
38
|
+
)
|
|
39
|
+
const = self.formulae.constants
|
|
40
|
+
pvs_i = self.formulae.saturation_vapour_pressure.pvs_ice(
|
|
41
|
+
self.initial_temperature
|
|
42
|
+
)
|
|
43
|
+
self.initial_water_vapour_mixing_ratio = const.eps / (
|
|
44
|
+
self.initial_pressure / self.initial_ice_supersaturation / pvs_i - 1
|
|
45
|
+
)
|
|
46
|
+
dry_air_density = (
|
|
47
|
+
self.formulae.trivia.p_d(
|
|
48
|
+
self.initial_pressure, self.initial_water_vapour_mixing_ratio
|
|
49
|
+
)
|
|
50
|
+
/ self.initial_temperature
|
|
51
|
+
/ const.Rd
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
spectrum = Lognormal(
|
|
55
|
+
norm_factor=self.N_dv_solution_droplet / dry_air_density,
|
|
56
|
+
m_mode=self.r_mean_solution_droplet,
|
|
57
|
+
s_geom=self.sigma_solution_droplet,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
self.r_dry, self.specific_concentration = spectral_sampling.Linear(
|
|
61
|
+
spectrum
|
|
62
|
+
).sample(n_sd)
|
|
63
|
+
|
|
64
|
+
self.t_duration = 7200
|
|
65
|
+
self.dt = dt
|
|
66
|
+
self.n_output = int(self.t_duration / 100)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from PySDM_examples.utils import BasicSimulation
|
|
4
|
+
|
|
5
|
+
import PySDM.products as PySDM_products
|
|
6
|
+
from PySDM.backends import CPU
|
|
7
|
+
from PySDM.builder import Builder
|
|
8
|
+
from PySDM.dynamics import (
|
|
9
|
+
AmbientThermodynamics,
|
|
10
|
+
Condensation,
|
|
11
|
+
Freezing,
|
|
12
|
+
VapourDepositionOnIce,
|
|
13
|
+
)
|
|
14
|
+
from PySDM.environments import Parcel
|
|
15
|
+
from PySDM.initialisation import discretise_multiplicities, equilibrate_wet_radii
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Simulation(BasicSimulation):
|
|
19
|
+
def __init__(self, settings, backend=CPU):
|
|
20
|
+
|
|
21
|
+
dt = settings.dt
|
|
22
|
+
|
|
23
|
+
formulae = settings.formulae
|
|
24
|
+
|
|
25
|
+
env = Parcel(
|
|
26
|
+
mixed_phase=True,
|
|
27
|
+
dt=dt,
|
|
28
|
+
mass_of_dry_air=settings.mass_of_dry_air,
|
|
29
|
+
p0=settings.initial_pressure,
|
|
30
|
+
initial_water_vapour_mixing_ratio=settings.initial_water_vapour_mixing_ratio,
|
|
31
|
+
T0=settings.initial_temperature,
|
|
32
|
+
w=settings.w_updraft,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
builder = Builder(
|
|
36
|
+
backend=backend(
|
|
37
|
+
formulae=settings.formulae,
|
|
38
|
+
**(
|
|
39
|
+
{"override_jit_flags": {"parallel": False}}
|
|
40
|
+
if backend == CPU
|
|
41
|
+
else {}
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
n_sd=settings.n_sd,
|
|
45
|
+
environment=env,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
builder.add_dynamic(AmbientThermodynamics())
|
|
49
|
+
builder.add_dynamic(Condensation())
|
|
50
|
+
builder.add_dynamic(VapourDepositionOnIce())
|
|
51
|
+
builder.add_dynamic(
|
|
52
|
+
Freezing(
|
|
53
|
+
singular=False, homogeneous_freezing=True, immersion_freezing=False
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
self.n_sd = settings.n_sd
|
|
58
|
+
self.multiplicities = discretise_multiplicities(
|
|
59
|
+
settings.specific_concentration * env.mass_of_dry_air
|
|
60
|
+
)
|
|
61
|
+
self.r_dry = settings.r_dry
|
|
62
|
+
v_dry = settings.formulae.trivia.volume(radius=self.r_dry)
|
|
63
|
+
kappa = settings.kappa
|
|
64
|
+
|
|
65
|
+
self.r_wet = equilibrate_wet_radii(
|
|
66
|
+
r_dry=self.r_dry,
|
|
67
|
+
environment=builder.particulator.environment,
|
|
68
|
+
kappa_times_dry_volume=kappa * v_dry,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
attributes = {
|
|
72
|
+
"multiplicity": self.multiplicities,
|
|
73
|
+
"dry volume": v_dry,
|
|
74
|
+
"kappa times dry volume": kappa * v_dry,
|
|
75
|
+
"signed water mass": formulae.particle_shape_and_density.radius_to_mass(
|
|
76
|
+
self.r_wet
|
|
77
|
+
),
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
products = [
|
|
81
|
+
PySDM_products.Time(name="t"),
|
|
82
|
+
PySDM_products.AmbientRelativeHumidity(name="RH_ice", unit="%"),
|
|
83
|
+
PySDM_products.ParticleConcentration(
|
|
84
|
+
name="n_i", unit="1/m**3", radius_range=(-np.inf, 0)
|
|
85
|
+
),
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
self.n_output = settings.n_output
|
|
89
|
+
self.n_substeps = int(settings.t_duration / dt / self.n_output)
|
|
90
|
+
super().__init__(builder.build(attributes, products))
|
|
91
|
+
|
|
92
|
+
def save(self, output):
|
|
93
|
+
cell_id = 0
|
|
94
|
+
output["t"].append(self.particulator.products["t"].get())
|
|
95
|
+
output["ni"].append(self.particulator.products["n_i"].get()[cell_id])
|
|
96
|
+
output["RHi"].append(self.particulator.products["RH_ice"].get()[cell_id])
|
|
97
|
+
|
|
98
|
+
def run(self):
|
|
99
|
+
output = {
|
|
100
|
+
"t": [],
|
|
101
|
+
"ni": [],
|
|
102
|
+
"RHi": [],
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
self.save(output)
|
|
106
|
+
|
|
107
|
+
RHi_old = self.particulator.products["RH_ice"].get()[0].copy()
|
|
108
|
+
for _ in range(self.n_output):
|
|
109
|
+
|
|
110
|
+
self.particulator.run(self.n_substeps)
|
|
111
|
+
|
|
112
|
+
self.save(output)
|
|
113
|
+
|
|
114
|
+
RHi = self.particulator.products["RH_ice"].get()[0].copy()
|
|
115
|
+
dRHi = (RHi_old - RHi) / RHi_old
|
|
116
|
+
if dRHi > 0.0 and RHi < 130.0:
|
|
117
|
+
print("break")
|
|
118
|
+
break
|
|
119
|
+
RHi_old = RHi
|
|
120
|
+
|
|
121
|
+
return output["ni"][-1]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysdm-examples
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.130
|
|
4
4
|
Summary: PySDM usage examples reproducing results from literature and depicting how to use PySDM from Python Jupyter notebooks
|
|
5
5
|
Home-page: https://github.com/open-atmos/PySDM
|
|
6
6
|
Author: https://github.com/open-atmos/PySDM/graphs/contributors
|
|
@@ -128,6 +128,8 @@ Example notebooks include:
|
|
|
128
128
|
- condensation and aqueous-chemistry
|
|
129
129
|
- <a href="https://open-atmos.github.io/PySDM/PySDM_examples/Kreidenweis_et_al_2003.html">Kreidenweis_et_al_2003</a>: <mark>Hoppel gap</mark> simulation setup (i.e. depiction of evolution of aerosol mass spectrum from a monomodal to bimodal due to aqueous‐phase SO2 oxidation)
|
|
130
130
|
- <a href="https://open-atmos.github.io/PySDM/PySDM_examples/Jaruga_and_Pawlowska_2018.html">Jaruga_and_Pawlowska_2018</a>: exploration of numerical convergence using the above Hoppel-gap simulation setup
|
|
131
|
+
- freezing
|
|
132
|
+
- <a href="https://open-atmos.github.io/PySDM/PySDM_examples/Spichtinger_et_al_2023.html">Spichtinger_et_al_2023</a>: <mark>homogeneous freezing</mark> and ice growth (<mark>Wegener-Bergeron-Findeisen process</mark>)
|
|
131
133
|
|
|
132
134
|
The parcel environment is also featured in the <a href="https://open-atmos.github.io/PySDM/PySDM.html#tutorials">PySDM tutorials</a>.
|
|
133
135
|
|
|
@@ -111,6 +111,12 @@ PySDM_examples/Shipway_and_Hill_2012/settings.py,sha256=JLBDI_HID-SFjgN6B1N4gLQe
|
|
|
111
111
|
PySDM_examples/Shipway_and_Hill_2012/simulation.py,sha256=4MAfO71-KfC75IJRFQslwTgrn9FLeJu_qN_j6i7LTrM,10338
|
|
112
112
|
PySDM_examples/Singer_Ward/__init__.py,sha256=2nKsepqAvYfHeiGAF1qca6DRzPQvUMosxhoCQKM7iiQ,161
|
|
113
113
|
PySDM_examples/Singer_Ward/aerosol.py,sha256=H7TcvI94Wc-IvhTMFshFaJRJY3eUjihAlSdNxVKZzL0,5805
|
|
114
|
+
PySDM_examples/Spichtinger_et_al_2023/__init__.py,sha256=rpXJyg4OKJA1z3jSNRnkhUqEKRVeDh5RRD8n3VtcNPA,231
|
|
115
|
+
PySDM_examples/Spichtinger_et_al_2023/settings.py,sha256=FGgp_vanSFl6FeGT4VwGBxo0myX-QNWFRV0Z2qX1tyo,1987
|
|
116
|
+
PySDM_examples/Spichtinger_et_al_2023/simulation.py,sha256=ENUZPonoC9ldoRLquqbZLPh_6sbcwezzFoSSzvHgoZA,3710
|
|
117
|
+
PySDM_examples/Spichtinger_et_al_2023/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
118
|
+
PySDM_examples/Spichtinger_et_al_2023/data/reference_bulk.py,sha256=T3F1LcCkejwwNmae3b-GyUjOBJ8nDCnyUybuQEQrOx8,1540
|
|
119
|
+
PySDM_examples/Spichtinger_et_al_2023/data/simulation_data.py,sha256=s_th_aQQDRHJdxiNOVTCsZxEGzSZoOywrUTPiR0k_lM,782
|
|
114
120
|
PySDM_examples/Srivastava_1982/__init__.py,sha256=mD9KZ6Gecr2jpynNZxFuv-fD-4B79yhQ98gM-tROaqg,564
|
|
115
121
|
PySDM_examples/Srivastava_1982/equations.py,sha256=RQHvXbznreupzhOdfSQpc859DUNhThjPEKt7sXTeEAw,3262
|
|
116
122
|
PySDM_examples/Srivastava_1982/example.py,sha256=fGaLDvqz4BBLLG8NqHB2D2aAYFPOJhEg1r5DBPUntB8,8576
|
|
@@ -159,7 +165,7 @@ PySDM_examples/utils/kinematic_2d/storage.py,sha256=NaGoujCRLubSEbhLA0QZDaSkATpJ
|
|
|
159
165
|
PySDM_examples/utils/widgets/__init__.py,sha256=U67WZ2YDcXSocMraI7pzcMxCfcxzXNqehDzoG6ogsh4,519
|
|
160
166
|
PySDM_examples/utils/widgets/freezer.py,sha256=tFlZWShXUzA2X0cxgeE44N1g9kD33q3KQWZBqkgBP0A,407
|
|
161
167
|
PySDM_examples/utils/widgets/progbar_updater.py,sha256=3uhG32QkAiSM3dTV7DoROJl7fAUNA6ZsJEIKSg3tdmk,267
|
|
162
|
-
pysdm_examples-2.
|
|
163
|
-
pysdm_examples-2.
|
|
164
|
-
pysdm_examples-2.
|
|
165
|
-
pysdm_examples-2.
|
|
168
|
+
pysdm_examples-2.130.dist-info/METADATA,sha256=K8YiJfOxJJWvn9jmjx1FnZX_pTyymwJMUjl_k5gn0Lk,13207
|
|
169
|
+
pysdm_examples-2.130.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
170
|
+
pysdm_examples-2.130.dist-info/top_level.txt,sha256=axw2inuuYKPWkQhzBYtkZJTPDlo5LrpGLOA0iSAf9v0,15
|
|
171
|
+
pysdm_examples-2.130.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|