Skip to content

Commit 3dd55a6

Browse files
tluettmslayoo
andauthored
add "threshold" homogeneous freezing & refactor immersion/homogenesous freezing setting flags + new thaw logic + GPU support for homogeneous freezing + removal of paper .md files in anticipation of 3.0-preX releasing scheme + update in copula examples to match changes in pyvinecopulib API (#1665)
Co-authored-by: Sylwester Arabas <[email protected]>
1 parent 81f9e9a commit 3dd55a6

File tree

46 files changed

+35209
-79292
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+35209
-79292
lines changed

.github/workflows/joss.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.

.github/workflows/joss_paper.yml

Lines changed: 0 additions & 36 deletions
This file was deleted.

.github/workflows/pdoc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
pdoc:
1717
strategy:
1818
matrix:
19-
platform: [ ubuntu-latest, macos-13, windows-latest ]
19+
platform: [ ubuntu-latest, macos-latest, windows-latest ]
2020
runs-on: ${{ matrix.platform }}
2121
steps:
2222
- uses: actions/[email protected]

.github/workflows/pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
pkg_install_check:
5858
strategy:
5959
matrix:
60-
platform: [ ubuntu-latest, macos-13, macos-14, windows-latest ]
60+
platform: [ ubuntu-latest, macos-latest, windows-latest ]
6161
python-version: [ "3.9", "3.12" ]
6262
exclude:
6363
- platform: macos-14

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ jobs:
243243
244244
# TODO #1207
245245
- if: startsWith(matrix.platform, 'macos-13')
246-
run: python -m pytest --basetemp=/tmp/pytest ${{ env.pytest_options }} tests/examples_tests/test_run* -k "not Rozanski_and_Sonntag_1982" --suite ${{ matrix.test-suite }}
246+
run: python -m pytest --basetemp=/tmp/pytest ${{ env.pytest_options }} tests/examples_tests/test_run* -k "not (Rozanski_and_Sonntag_1982 or copula_hello)" --suite ${{ matrix.test-suite }}
247247

248248
- if: ( ! startsWith(matrix.platform, 'macos-13') )
249249
run: python -m pytest ${{ env.pytest_options }} --basetemp=/tmp/pytest --timeout_method=thread --timeout=${{ startsWith(matrix.platform, 'windows-') && 1000 || 900 }} tests/examples_tests/test_run* --suite ${{ matrix.test-suite }}

PySDM/attributes/ice/freezing_temperature.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ class TemperatureOfLastFreezing(DerivedAttribute):
2020

2121
def __init__(self, builder):
2222
assert "Freezing" in builder.particulator.dynamics
23-
assert not builder.particulator.dynamics["Freezing"].singular
23+
assert (
24+
builder.particulator.dynamics["Freezing"].immersion_freezing != "singular"
25+
)
2426
self.signed_water_mass = builder.get_attribute("signed water mass")
2527
self.cell_id = builder.get_attribute("cell id")
2628
super().__init__(

PySDM/backends/impl_common/freezing_attributes.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""
2-
groups of attributes used in either singular or time-dependent immersion freezing regimes
2+
groups of attributes used in either singular or time-dependent immersion freezing regimes,
3+
in threshold or time-dependent homogeneous freezing and for thaw routines
34
"""
45

56
from collections import namedtuple
@@ -36,3 +37,14 @@ class TimeDependentHomogeneousAttributes(
3637
"""groups attributes required in time-dependent regime for homogeneous freezing"""
3738

3839
__slots__ = ()
40+
41+
42+
class ThresholdHomogeneousAndThawAttributes(
43+
namedtuple(
44+
typename="ThresholdHomogeneousAttributes",
45+
field_names=("signed_water_mass"),
46+
)
47+
):
48+
"""groups attributes required in time-dependent regime for homogeneous freezing"""
49+
50+
__slots__ = ()

PySDM/backends/impl_numba/methods/freezing_methods.py

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
SingularAttributes,
1515
TimeDependentAttributes,
1616
TimeDependentHomogeneousAttributes,
17+
ThresholdHomogeneousAndThawAttributes,
1718
)
1819

1920

@@ -37,25 +38,40 @@ def body(signed_water_mass, i):
3738
return body
3839

3940
@cached_property
40-
def _freeze_singular_body(self):
41+
def _thaw_instantaneous_body(self):
4142
_thaw = self._thaw
42-
_freeze = self._freeze
4343
frozen_and_above_freezing_point = (
4444
self.formulae.trivia.frozen_and_above_freezing_point
4545
)
46+
47+
@numba.njit(**self.default_jit_flags)
48+
def body(attributes, cell, temperature):
49+
n_sd = len(attributes.signed_water_mass)
50+
for i in numba.prange(n_sd): # pylint: disable=not-an-iterable
51+
if frozen_and_above_freezing_point(
52+
attributes.signed_water_mass[i], temperature[cell[i]]
53+
):
54+
_thaw(attributes.signed_water_mass, i)
55+
56+
return body
57+
58+
@cached_property
59+
def _immersion_freezing_singular_body(self):
60+
_freeze = self._freeze
4661
unfrozen_and_saturated = self.formulae.trivia.unfrozen_and_saturated
4762

4863
@numba.njit(**self.default_jit_flags)
49-
def body(attributes, temperature, relative_humidity, cell, thaw):
64+
def body(
65+
attributes,
66+
temperature,
67+
relative_humidity,
68+
cell,
69+
):
5070
n_sd = len(attributes.freezing_temperature)
5171
for i in numba.prange(n_sd): # pylint: disable=not-an-iterable
5272
if attributes.freezing_temperature[i] == 0:
5373
continue
54-
if thaw and frozen_and_above_freezing_point(
55-
attributes.signed_water_mass[i], temperature[cell[i]]
56-
):
57-
_thaw(attributes.signed_water_mass, i)
58-
elif (
74+
if (
5975
unfrozen_and_saturated(
6076
attributes.signed_water_mass[i], relative_humidity[cell[i]]
6177
)
@@ -66,12 +82,8 @@ def body(attributes, temperature, relative_humidity, cell, thaw):
6682
return body
6783

6884
@cached_property
69-
def _freeze_time_dependent_body(self):
70-
_thaw = self._thaw
85+
def _immersion_freezing_time_dependent_body(self):
7186
_freeze = self._freeze
72-
frozen_and_above_freezing_point = (
73-
self.formulae.trivia.frozen_and_above_freezing_point
74-
)
7587
unfrozen_and_saturated = self.formulae.trivia.unfrozen_and_saturated
7688
j_het = self.formulae.heterogeneous_ice_nucleation_rate.j_het
7789
prob_zero_events = self.formulae.trivia.poissonian_avoidance_function
@@ -83,20 +95,14 @@ def body( # pylint: disable=too-many-arguments
8395
timestep,
8496
cell,
8597
a_w_ice,
86-
temperature,
8798
relative_humidity,
88-
thaw,
8999
):
90100
n_sd = len(attributes.signed_water_mass)
91101
for i in numba.prange(n_sd): # pylint: disable=not-an-iterable
92102
if attributes.immersed_surface_area[i] == 0:
93103
continue
94104
cell_id = cell[i]
95-
if thaw and frozen_and_above_freezing_point(
96-
attributes.signed_water_mass[i], temperature[cell_id]
97-
):
98-
_thaw(attributes.signed_water_mass, i)
99-
elif unfrozen_and_saturated(
105+
if unfrozen_and_saturated(
100106
attributes.signed_water_mass[i], relative_humidity[cell_id]
101107
):
102108
rate_assuming_constant_temperature_within_dt = (
@@ -111,12 +117,8 @@ def body( # pylint: disable=too-many-arguments
111117
return body
112118

113119
@cached_property
114-
def _freeze_time_dependent_homogeneous_body(self):
115-
_thaw = self._thaw
120+
def _homogeneous_freezing_time_dependent_body(self):
116121
_freeze = self._freeze
117-
frozen_and_above_freezing_point = (
118-
self.formulae.trivia.frozen_and_above_freezing_point
119-
)
120122
unfrozen_and_ice_saturated = self.formulae.trivia.unfrozen_and_ice_saturated
121123
j_hom = self.formulae.homogeneous_ice_nucleation_rate.j_hom
122124
prob_zero_events = self.formulae.trivia.poissonian_avoidance_function
@@ -136,17 +138,12 @@ def body( # pylint: disable=unused-argument,too-many-arguments
136138
a_w_ice,
137139
temperature,
138140
relative_humidity_ice,
139-
thaw,
140141
):
141142

142143
n_sd = len(attributes.signed_water_mass)
143144
for i in numba.prange(n_sd): # pylint: disable=not-an-iterable
144145
cell_id = cell[i]
145-
if thaw and frozen_and_above_freezing_point(
146-
attributes.signed_water_mass[i], temperature[cell_id]
147-
):
148-
_thaw(attributes.signed_water_mass, i)
149-
elif unfrozen_and_ice_saturated(
146+
if unfrozen_and_ice_saturated(
150147
attributes.signed_water_mass[i], relative_humidity_ice[cell_id]
151148
):
152149
d_a_w_ice = (relative_humidity_ice[cell_id] - 1.0) * a_w_ice[
@@ -167,33 +164,64 @@ def body( # pylint: disable=unused-argument,too-many-arguments
167164

168165
return body
169166

170-
def freeze_singular(
171-
self, *, attributes, temperature, relative_humidity, cell, thaw: bool
167+
@cached_property
168+
def _homogeneous_freezing_threshold_body(self):
169+
_freeze = self._freeze
170+
unfrozen_and_ice_saturated = self.formulae.trivia.unfrozen_and_ice_saturated
171+
const = self.formulae.constants
172+
173+
@numba.njit(**self.default_jit_flags)
174+
def body(attributes, cell, temperature, relative_humidity_ice):
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 unfrozen_and_ice_saturated(
179+
attributes.signed_water_mass[i], relative_humidity_ice[cell_id]
180+
):
181+
if temperature[cell_id] <= const.HOMOGENEOUS_FREEZING_THRESHOLD:
182+
_freeze(attributes.signed_water_mass, i)
183+
184+
return body
185+
186+
def thaw_instantaneous(
187+
self,
188+
*,
189+
attributes,
190+
cell,
191+
temperature,
192+
):
193+
self._thaw_instantaneous_body(
194+
ThresholdHomogeneousAndThawAttributes(
195+
signed_water_mass=attributes.signed_water_mass.data,
196+
),
197+
cell.data,
198+
temperature.data,
199+
)
200+
201+
def immersion_freezing_singular(
202+
self, *, attributes, temperature, relative_humidity, cell
172203
):
173-
self._freeze_singular_body(
204+
self._immersion_freezing_singular_body(
174205
SingularAttributes(
175206
freezing_temperature=attributes.freezing_temperature.data,
176207
signed_water_mass=attributes.signed_water_mass.data,
177208
),
178209
temperature.data,
179210
relative_humidity.data,
180211
cell.data,
181-
thaw=thaw,
182212
)
183213

184-
def freeze_time_dependent(
214+
def immersion_freezing_time_dependent(
185215
self,
186216
*,
187217
rand,
188218
attributes,
189219
timestep,
190220
cell,
191221
a_w_ice,
192-
temperature,
193222
relative_humidity,
194-
thaw: bool,
195223
):
196-
self._freeze_time_dependent_body(
224+
self._immersion_freezing_time_dependent_body(
197225
rand.data,
198226
TimeDependentAttributes(
199227
immersed_surface_area=attributes.immersed_surface_area.data,
@@ -202,12 +230,27 @@ def freeze_time_dependent(
202230
timestep,
203231
cell.data,
204232
a_w_ice.data,
205-
temperature.data,
206233
relative_humidity.data,
207-
thaw=thaw,
208234
)
209235

210-
def freeze_time_dependent_homogeneous(
236+
def homogeneous_freezing_threshold(
237+
self,
238+
*,
239+
attributes,
240+
cell,
241+
temperature,
242+
relative_humidity_ice,
243+
):
244+
self._homogeneous_freezing_threshold_body(
245+
ThresholdHomogeneousAndThawAttributes(
246+
signed_water_mass=attributes.signed_water_mass.data,
247+
),
248+
cell.data,
249+
temperature.data,
250+
relative_humidity_ice.data,
251+
)
252+
253+
def homogeneous_freezing_time_dependent(
211254
self,
212255
*,
213256
rand,
@@ -217,9 +260,8 @@ def freeze_time_dependent_homogeneous(
217260
a_w_ice,
218261
temperature,
219262
relative_humidity_ice,
220-
thaw: bool,
221263
):
222-
self._freeze_time_dependent_homogeneous_body(
264+
self._homogeneous_freezing_time_dependent_body(
223265
rand.data,
224266
TimeDependentHomogeneousAttributes(
225267
volume=attributes.volume.data,
@@ -230,7 +272,6 @@ def freeze_time_dependent_homogeneous(
230272
a_w_ice.data,
231273
temperature.data,
232274
relative_humidity_ice.data,
233-
thaw=thaw,
234275
)
235276

236277
@cached_property

0 commit comments

Comments
 (0)