88from PySDM .environments import Box
99from PySDM .physics import si
1010from PySDM .products import IceWaterContent
11+ from PySDM .backends import GPU
12+
13+ VERY_BIG_J_HET = 1e20
14+ EPSILON_RH = 1e-3
1115
1216
1317class TestImmersionFreezing :
14- # TODO #599
15- def test_record_freezing_temperature_on_time_dependent_freeze (self ):
16- pass
18+ @staticmethod
19+ @pytest .mark .parametrize (
20+ "record_freezing_temperature" ,
21+ (pytest .param (True , id = "recording" ), pytest .param (False , id = "not recording" )),
22+ )
23+ def test_record_freezing_temperature_on_time_dependent_freeze (
24+ backend_class , record_freezing_temperature
25+ ):
26+ if backend_class is GPU and record_freezing_temperature :
27+ pytest .skip ("TODO #1495" )
28+
29+ # arrange
30+ formulae = Formulae (
31+ particle_shape_and_density = "MixedPhaseSpheres" ,
32+ heterogeneous_ice_nucleation_rate = "Constant" ,
33+ constants = {"J_HET" : VERY_BIG_J_HET },
34+ )
35+ builder = Builder (
36+ n_sd = 1 ,
37+ backend = backend_class (formulae = formulae ),
38+ environment = Box (dt = 1 * si .s , dv = 1 * si .m ** 3 ),
39+ )
40+ builder .add_dynamic (Freezing (singular = False , thaw = True ))
41+ if record_freezing_temperature :
42+ builder .request_attribute ("temperature of last freezing" )
43+ particulator = builder .build (
44+ attributes = {
45+ "multiplicity" : np .asarray ([1 ]),
46+ "signed water mass" : np .asarray ([1 * si .ug ]),
47+ "immersed surface area" : np .asarray ([1 * si .um ** 2 ]),
48+ }
49+ )
50+
51+ temp_1 = 200 * si .K
52+ temp_2 = 250 * si .K
53+ particulator .environment ["a_w_ice" ] = np .nan
54+ particulator .environment ["T" ] = temp_1
55+
56+ # act & assert
57+ attr_name = "temperature of last freezing"
58+ if not record_freezing_temperature :
59+ assert attr_name not in particulator .attributes
60+ else :
61+ # never frozen yet
62+ np .isnan (particulator .attributes [attr_name ].to_ndarray ()).all ()
63+
64+ # still not frozen since RH not greater than 100%
65+ particulator .environment ["RH" ] = 1.0
66+ particulator .run (steps = 1 )
67+ np .isnan (particulator .attributes [attr_name ].to_ndarray ()).all ()
68+
69+ # should freeze and record T1
70+ particulator .environment ["RH" ] += EPSILON_RH
71+ particulator .run (steps = 1 )
72+ assert all (particulator .attributes [attr_name ].to_ndarray () == temp_1 )
73+
74+ # should thaw
75+ particulator .environment ["T" ] = 300 * si .K
76+ particulator .run (steps = 1 )
77+ np .isnan (particulator .attributes [attr_name ].to_ndarray ()).all ()
78+
79+ # should re-freeze and record T2
80+ particulator .environment ["T" ] = temp_2
81+ particulator .run (steps = 1 )
82+ assert all (particulator .attributes [attr_name ].to_ndarray () == temp_2 )
1783
1884 # TODO #599
1985 def test_no_subsaturated_freezing (self ):
@@ -25,7 +91,17 @@ def test_no_subsaturated_freezing(self):
2591 @pytest .mark .parametrize ("epsilon" , (0 , 1e-5 ))
2692 def test_thaw (backend_class , singular , thaw , epsilon ):
2793 # arrange
28- formulae = Formulae (particle_shape_and_density = "MixedPhaseSpheres" )
94+ formulae = Formulae (
95+ particle_shape_and_density = "MixedPhaseSpheres" ,
96+ ** (
97+ {}
98+ if singular
99+ else {
100+ "heterogeneous_ice_nucleation_rate" : "Constant" ,
101+ "constants" : {"J_HET" : 0 },
102+ }
103+ ),
104+ )
29105 env = Box (dt = 1 * si .s , dv = 1 * si .m ** 3 )
30106 builder = Builder (
31107 n_sd = 1 , backend = backend_class (formulae = formulae ), environment = env
0 commit comments