Skip to content

Commit 3c6b3cf

Browse files
tluettmslayoo
authored andcommitted
Homogeneous freezing (as a new option in Freezing dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: Spichtinger_et_al_2023 (#1488)
Co-authored-by: Sylwester Arabas <sylwester.arabas@agh.edu.pl>
1 parent 1ad4d69 commit 3c6b3cf

File tree

34 files changed

+127993
-1
lines changed

34 files changed

+127993
-1
lines changed

PySDM/backends/impl_common/freezing_attributes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class TimeDependentHomogeneousAttributes(
3737
"""groups attributes required in time-dependent regime for homogeneous freezing"""
3838

3939
__slots__ = ()
40+
<<<<<<< HEAD
4041

4142

4243
class ThresholdHomogeneousAndThawAttributes(
@@ -48,3 +49,5 @@ class ThresholdHomogeneousAndThawAttributes(
4849
"""groups attributes required in time-dependent regime for homogeneous freezing"""
4950

5051
__slots__ = ()
52+
=======
53+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))

PySDM/backends/impl_numba/methods/freezing_methods.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
SingularAttributes,
1515
TimeDependentAttributes,
1616
TimeDependentHomogeneousAttributes,
17+
<<<<<<< HEAD
1718
ThresholdHomogeneousAndThawAttributes,
19+
=======
20+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
1821
)
1922

2023

@@ -38,6 +41,7 @@ def body(signed_water_mass, i):
3841
return body
3942

4043
@cached_property
44+
<<<<<<< HEAD
4145
def _thaw_instantaneous_body(self):
4246
_thaw = self._thaw
4347
frozen_and_above_freezing_point = (
@@ -67,6 +71,18 @@ def body(
6771
relative_humidity,
6872
cell,
6973
):
74+
=======
75+
def _freeze_singular_body(self):
76+
_thaw = self._thaw
77+
_freeze = self._freeze
78+
frozen_and_above_freezing_point = (
79+
self.formulae.trivia.frozen_and_above_freezing_point
80+
)
81+
unfrozen_and_saturated = self.formulae.trivia.unfrozen_and_saturated
82+
83+
@numba.njit(**self.default_jit_flags)
84+
def body(attributes, temperature, relative_humidity, cell, thaw):
85+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
7086
n_sd = len(attributes.freezing_temperature)
7187
for i in numba.prange(n_sd): # pylint: disable=not-an-iterable
7288
if attributes.freezing_temperature[i] == 0:
@@ -82,8 +98,17 @@ def body(
8298
return body
8399

84100
@cached_property
101+
<<<<<<< HEAD
85102
def _immersion_freezing_time_dependent_body(self):
86103
_freeze = self._freeze
104+
=======
105+
def _freeze_time_dependent_body(self):
106+
_thaw = self._thaw
107+
_freeze = self._freeze
108+
frozen_and_above_freezing_point = (
109+
self.formulae.trivia.frozen_and_above_freezing_point
110+
)
111+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
87112
unfrozen_and_saturated = self.formulae.trivia.unfrozen_and_saturated
88113
j_het = self.formulae.heterogeneous_ice_nucleation_rate.j_het
89114
prob_zero_events = self.formulae.trivia.poissonian_avoidance_function
@@ -115,6 +140,66 @@ def body( # pylint: disable=too-many-arguments
115140
_freeze(attributes.signed_water_mass, i)
116141

117142
return body
143+
<<<<<<< HEAD
144+
=======
145+
146+
@cached_property
147+
def _freeze_time_dependent_homogeneous_body(self):
148+
_thaw = self._thaw
149+
_freeze = self._freeze
150+
frozen_and_above_freezing_point = (
151+
self.formulae.trivia.frozen_and_above_freezing_point
152+
)
153+
unfrozen_and_ice_saturated = self.formulae.trivia.unfrozen_and_ice_saturated
154+
j_hom = self.formulae.homogeneous_ice_nucleation_rate.j_hom
155+
prob_zero_events = self.formulae.trivia.poissonian_avoidance_function
156+
d_a_w_ice_within_range = (
157+
self.formulae.homogeneous_ice_nucleation_rate.d_a_w_ice_within_range
158+
)
159+
d_a_w_ice_maximum = (
160+
self.formulae.homogeneous_ice_nucleation_rate.d_a_w_ice_maximum
161+
)
162+
163+
@numba.njit(**self.default_jit_flags)
164+
def body( # pylint: disable=unused-argument,too-many-arguments
165+
rand,
166+
attributes,
167+
timestep,
168+
cell,
169+
a_w_ice,
170+
temperature,
171+
relative_humidity_ice,
172+
thaw,
173+
):
174+
175+
n_sd = len(attributes.signed_water_mass)
176+
for i in numba.prange(n_sd): # pylint: disable=not-an-iterable
177+
cell_id = cell[i]
178+
if thaw and frozen_and_above_freezing_point(
179+
attributes.signed_water_mass[i], temperature[cell_id]
180+
):
181+
_thaw(attributes.signed_water_mass, i)
182+
elif unfrozen_and_ice_saturated(
183+
attributes.signed_water_mass[i], relative_humidity_ice[cell_id]
184+
):
185+
d_a_w_ice = (relative_humidity_ice[cell_id] - 1.0) * a_w_ice[
186+
cell_id
187+
]
188+
189+
if d_a_w_ice_within_range(d_a_w_ice):
190+
d_a_w_ice = d_a_w_ice_maximum(d_a_w_ice)
191+
rate_assuming_constant_temperature_within_dt = (
192+
j_hom(temperature[cell_id], d_a_w_ice)
193+
* attributes.volume[i]
194+
)
195+
prob = 1 - prob_zero_events(
196+
r=rate_assuming_constant_temperature_within_dt, dt=timestep
197+
)
198+
if rand[i] < prob:
199+
_freeze(attributes.signed_water_mass, i)
200+
201+
return body
202+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
118203

119204
@cached_property
120205
def _homogeneous_freezing_time_dependent_body(self):
@@ -190,6 +275,7 @@ def thaw_instantaneous(
190275
cell,
191276
temperature,
192277
):
278+
<<<<<<< HEAD
193279
self._thaw_instantaneous_body(
194280
ThresholdHomogeneousAndThawAttributes(
195281
signed_water_mass=attributes.signed_water_mass.data,
@@ -202,6 +288,9 @@ def immersion_freezing_singular(
202288
self, *, attributes, temperature, relative_humidity, cell
203289
):
204290
self._immersion_freezing_singular_body(
291+
=======
292+
self._freeze_singular_body(
293+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
205294
SingularAttributes(
206295
freezing_temperature=attributes.freezing_temperature.data,
207296
signed_water_mass=attributes.signed_water_mass.data,
@@ -221,7 +310,11 @@ def immersion_freezing_time_dependent(
221310
a_w_ice,
222311
relative_humidity,
223312
):
313+
<<<<<<< HEAD
224314
self._immersion_freezing_time_dependent_body(
315+
=======
316+
self._freeze_time_dependent_body(
317+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
225318
rand.data,
226319
TimeDependentAttributes(
227320
immersed_surface_area=attributes.immersed_surface_area.data,
@@ -274,6 +367,32 @@ def homogeneous_freezing_time_dependent(
274367
relative_humidity_ice.data,
275368
)
276369

370+
def freeze_time_dependent_homogeneous(
371+
self,
372+
*,
373+
rand,
374+
attributes,
375+
timestep,
376+
cell,
377+
a_w_ice,
378+
temperature,
379+
relative_humidity_ice,
380+
thaw: bool,
381+
):
382+
self._freeze_time_dependent_homogeneous_body(
383+
rand.data,
384+
TimeDependentHomogeneousAttributes(
385+
volume=attributes.volume.data,
386+
signed_water_mass=attributes.signed_water_mass.data,
387+
),
388+
timestep,
389+
cell.data,
390+
a_w_ice.data,
391+
temperature.data,
392+
relative_humidity_ice.data,
393+
thaw=thaw,
394+
)
395+
277396
@cached_property
278397
def _record_freezing_temperatures_body(self):
279398
ff = self.formulae_flattened

PySDM/dynamics/freezing.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Freezing: # pylint: disable=too-many-instance-attributes
1313
def __init__(
1414
self,
1515
*,
16+
<<<<<<< HEAD
1617
homogeneous_freezing: Optional[str] = None,
1718
immersion_freezing: Optional[str] = None,
1819
thaw: Optional[str] = None,
@@ -30,6 +31,14 @@ def __init__(
3031
)
3132
assert thaw is None or thaw == "instantaneous"
3233

34+
=======
35+
singular=True,
36+
homogeneous_freezing=False,
37+
immersion_freezing=True,
38+
thaw=False,
39+
):
40+
self.singular = singular
41+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
3342
self.homogeneous_freezing = homogeneous_freezing
3443
self.immersion_freezing = immersion_freezing
3544
self.thaw = thaw
@@ -49,24 +58,36 @@ def register(self, builder):
4958
if self.immersion_freezing == "singular":
5059
builder.request_attribute("freezing temperature")
5160

61+
<<<<<<< HEAD
5262
if self.immersion_freezing == "time-dependent":
63+
=======
64+
if not self.singular and self.immersion_freezing:
65+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
5366
assert (
5467
self.particulator.formulae.heterogeneous_ice_nucleation_rate.__name__
5568
!= "Null"
5669
)
5770
builder.request_attribute("immersed surface area")
5871

72+
<<<<<<< HEAD
5973
if self.homogeneous_freezing == "time-dependent":
74+
=======
75+
if self.homogeneous_freezing:
76+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
6077
assert (
6178
self.particulator.formulae.homogeneous_ice_nucleation_rate.__name__
6279
!= "Null"
6380
)
6481
builder.request_attribute("volume")
6582

83+
<<<<<<< HEAD
6684
if (
6785
self.homogeneous_freezing == "time-dependent"
6886
or self.immersion_freezing == "time-dependent"
6987
):
88+
=======
89+
if self.homogeneous_freezing or not self.singular:
90+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
7091
self.rand = self.particulator.Storage.empty(
7192
self.particulator.n_sd, dtype=float
7293
)
@@ -84,11 +105,25 @@ def __call__(self):
84105
if not self.enable:
85106
return
86107

108+
<<<<<<< HEAD
87109
if self.immersion_freezing == "singular":
88110
self.particulator.immersion_freezing_singular()
89111
elif self.immersion_freezing == "time-dependent":
112+
=======
113+
if self.immersion_freezing:
114+
if self.singular:
115+
self.particulator.immersion_freezing_singular(thaw=self.thaw)
116+
else:
117+
self.rand.urand(self.rng)
118+
self.particulator.immersion_freezing_time_dependent(
119+
rand=self.rand,
120+
thaw=self.thaw,
121+
)
122+
123+
if self.homogeneous_freezing:
124+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
90125
self.rand.urand(self.rng)
91-
self.particulator.immersion_freezing_time_dependent(
126+
self.particulator.homogeneous_freezing_time_dependent(
92127
rand=self.rand,
93128
)
94129

PySDM/particulator.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
SingularAttributes,
1010
TimeDependentAttributes,
1111
TimeDependentHomogeneousAttributes,
12+
<<<<<<< HEAD
1213
ThresholdHomogeneousAndThawAttributes,
14+
=======
15+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
1316
)
1417
from PySDM.backends.impl_common.index import make_Index
1518
from PySDM.backends.impl_common.indexed_storage import make_IndexedStorage
@@ -533,8 +536,13 @@ def immersion_freezing_singular(self):
533536
)
534537
self.attributes.mark_updated("signed water mass")
535538

539+
<<<<<<< HEAD
536540
def homogeneous_freezing_time_dependent(self, *, rand: Storage):
537541
self.backend.homogeneous_freezing_time_dependent(
542+
=======
543+
def homogeneous_freezing_time_dependent(self, *, thaw: bool, rand: Storage):
544+
self.backend.freeze_time_dependent_homogeneous(
545+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
538546
rand=rand,
539547
attributes=TimeDependentHomogeneousAttributes(
540548
volume=self.attributes["volume"],
@@ -545,6 +553,7 @@ def homogeneous_freezing_time_dependent(self, *, rand: Storage):
545553
a_w_ice=self.environment["a_w_ice"],
546554
temperature=self.environment["T"],
547555
relative_humidity_ice=self.environment["RH_ice"],
556+
<<<<<<< HEAD
548557
)
549558

550559
def homogeneous_freezing_threshold(self):
@@ -564,4 +573,7 @@ def thaw_instantaneous(self):
564573
),
565574
cell=self.attributes["cell id"],
566575
temperature=self.environment["T"],
576+
=======
577+
thaw=thaw,
578+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
567579
)

PySDM/physics/constants_defaults.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@
104104
""" thermal accommodation coefficient for vapour deposition as recommended in
105105
[Pruppacher & Klett](https://doi.org/10.1007/978-0-306-48100-0) """
106106

107+
<<<<<<< HEAD
107108
C_cunn = 0.7
108109
""" Cunningham correction factor as used in
109110
[Spichtinger & Gierens 2009](https://doi.org/10.5194/acp-9-685-2009) """
110111

112+
=======
113+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
111114
ARM_C1 = 6.1094 * si.hectopascal
112115
""" [August](https://doi.org/10.1002/andp.18280890511) Roche Magnus formula coefficients
113116
(values from [Alduchov & Eskridge 1996](https://doi.org/10.1175%2F1520-0450%281996%29035%3C0601%3AIMFAOS%3E2.0.CO%3B2))

PySDM/physics/homogeneous_ice_nucleation_rate/constant.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
import numpy as np
66

77

8+
<<<<<<< HEAD
89
class Constant:
10+
=======
11+
class Constant: # pylint: disable=too-few-public-methods
12+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
913
def __init__(self, const):
1014
assert np.isfinite(const.J_HOM)
1115

@@ -18,5 +22,9 @@ def d_a_w_ice_maximum(const, da_w_ice): # pylint: disable=unused-argument
1822
return da_w_ice
1923

2024
@staticmethod
25+
<<<<<<< HEAD
2126
def j_hom(const, T, da_w_ice): # pylint: disable=unused-argument
27+
=======
28+
def j_hom(const, T, a_w_ice): # pylint: disable=unused-argument
29+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
2230
return const.J_HOM

PySDM/physics/homogeneous_ice_nucleation_rate/koop.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
import numpy as np
88

99

10+
<<<<<<< HEAD
1011
class Koop2000:
12+
=======
13+
class Koop2000: # pylint: disable=too-few-public-methods
14+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
1115
def __init__(self, const):
1216
pass
1317

PySDM/physics/homogeneous_ice_nucleation_rate/koop_corr.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
import numpy as np
99

1010

11+
<<<<<<< HEAD
1112
class Koop_Correction:
13+
=======
14+
class Koop_Correction: # pylint: disable=too-few-public-methods
15+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
1216
def __init__(self, const):
1317
pass
1418

PySDM/physics/homogeneous_ice_nucleation_rate/koop_murray.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
import numpy as np
88

99

10+
<<<<<<< HEAD
1011
class KoopMurray2016:
12+
=======
13+
class KoopMurray2016: # pylint: disable=too-few-public-methods
14+
>>>>>>> 561d4927 (Homogeneous freezing (as a new option in `Freezing` dynamic, disabled by default + new physics formulae for hom. nucl. rate); new example: `Spichtinger_et_al_2023` (#1488))
1115
def __init__(self, const):
1216
pass
1317

0 commit comments

Comments
 (0)