Skip to content

Commit 8b0d6d4

Browse files
Introduce Rogers & Yau notation for terms associated with mass (Fd) and heat (Fk) diffusion in drop growth formula; avoid recomputing them within condensation implicit-Euler root-finding problem; var naming refactors in condensation solver (#1620)
1 parent 0687fac commit 8b0d6d4

File tree

11 files changed

+210
-168
lines changed

11 files changed

+210
-168
lines changed

PySDM/backends/impl_numba/methods/condensation_methods.py

Lines changed: 34 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def make_adapt_substeps(
188188
n_substeps_min = math.ceil(timestep / dt_range[1])
189189

190190
@numba.njit(**jit_flags)
191-
def adapt_substeps(args, n_substeps, thd, rtol_thd):
191+
def adapt_substeps(step_impl_args, n_substeps, thd, rtol_thd):
192192
n_substeps = np.maximum(n_substeps_min, n_substeps // multiplier)
193193
success = False
194194
for burnout in range(fuse + 1):
@@ -202,15 +202,15 @@ def adapt_substeps(args, n_substeps, thd, rtol_thd):
202202
),
203203
return_value=(0, False),
204204
)
205-
thd_new_long, success = step_fake(args, timestep, n_substeps)
205+
thd_new_long, success = step_fake(step_impl_args, timestep, n_substeps)
206206
if success:
207207
break
208208
n_substeps *= multiplier
209209
for burnout in range(fuse + 1):
210210
if burnout == fuse:
211211
return warn("burnout (short)", __file__, return_value=(0, False))
212212
thd_new_short, success = step_fake(
213-
args, timestep, n_substeps * multiplier
213+
step_impl_args, timestep, n_substeps * multiplier
214214
)
215215
if not success:
216216
return warn("short failed", __file__, return_value=(0, False))
@@ -230,18 +230,18 @@ def adapt_substeps(args, n_substeps, thd, rtol_thd):
230230
@staticmethod
231231
def make_step_fake(jit_flags, step_impl):
232232
@numba.njit(**jit_flags)
233-
def step_fake(args, dt, n_substeps):
233+
def step_fake(step_impl_args, dt, n_substeps):
234234
dt /= n_substeps
235-
_, thd_new, _, _, _, _, success = step_impl(*args, dt, 1, True)
235+
_, thd_new, _, _, _, _, success = step_impl(*step_impl_args, dt, 1, True)
236236
return thd_new, success
237237

238238
return step_fake
239239

240240
@staticmethod
241241
def make_step(jit_flags, step_impl):
242242
@numba.njit(**jit_flags)
243-
def step(args, dt, n_substeps):
244-
return step_impl(*args, dt, n_substeps, False)
243+
def step(step_impl_args, dt, n_substeps):
244+
return step_impl(*step_impl_args, dt, n_substeps, False)
245245

246246
return step
247247

@@ -293,6 +293,7 @@ def step_impl( # pylint: disable=too-many-arguments,too-many-locals
293293
lv = formulae.latent_heat_vapourisation__lv(T)
294294
pvs = formulae.saturation_vapour_pressure__pvs_water(T)
295295
DTp = formulae.diffusion_thermics__D(T, p)
296+
KTp = formulae.diffusion_thermics__K(T, p)
296297
RH = pv / pvs
297298
Sc = formulae.trivia__air_schmidt_number(
298299
dynamic_viscosity=air_dynamic_viscosity,
@@ -317,7 +318,7 @@ def step_impl( # pylint: disable=too-many-arguments,too-many-locals
317318
lv,
318319
pvs,
319320
DTp,
320-
formulae.diffusion_thermics__K(T, p),
321+
KTp,
321322
rtol_x,
322323
)
323324
dml_dt = (ml_new - ml_old) / timestep
@@ -376,21 +377,12 @@ def make_calculate_ml_new( # pylint: disable=too-many-statements
376377
):
377378
@numba.njit(**jit_flags)
378379
def minfun( # pylint: disable=too-many-arguments,too-many-locals
379-
x_new,
380-
x_old,
381-
timestep,
382-
kappa,
383-
f_org,
384-
rd3,
385-
temperature,
386-
RH,
387-
lv,
388-
pvs,
389-
D,
390-
K,
391-
mass_ventilation_factor,
392-
heat_ventilation_factor,
380+
x_new, x_old, timestep, kappa, f_org, rd3, temperature, RH, Fk, Fd
393381
):
382+
"""
383+
root finding problem for the implicit-in-x Euler step
384+
neglecting dependence of `Fk` and `Fd` on particle size
385+
"""
394386
if x_new > formulae.diffusion_coordinate__x_max():
395387
return x_old - x_new
396388
mass_new = formulae.diffusion_coordinate__mass(x_new)
@@ -405,15 +397,7 @@ def minfun( # pylint: disable=too-many-arguments,too-many-locals
405397
temperature, volume_new, formulae.constants.PI_4_3 * rd3, f_org
406398
),
407399
)
408-
r_dr_dt = formulae.drop_growth__r_dr_dt(
409-
RH_eq,
410-
temperature,
411-
RH,
412-
lv,
413-
pvs,
414-
D * mass_ventilation_factor,
415-
K * heat_ventilation_factor,
416-
)
400+
r_dr_dt = formulae.drop_growth__r_dr_dt(RH_eq=RH_eq, RH=RH, Fk=Fk, Fd=Fd)
417401
dm_dt = formulae.particle_shape_and_density__dm_dt(r=r_new, r_dr_dt=r_dr_dt)
418402
return (
419403
x_old
@@ -476,29 +460,25 @@ def calculate_ml_new( # pylint: disable=too-many-branches,too-many-arguments,to
476460
)
477461
)
478462
heat_ventilation_factor = mass_ventilation_factor # TODO #1588
479-
args = (
463+
Fk = formulae.drop_growth__Fk(
464+
T=T, K=Kr * heat_ventilation_factor, lv=lv
465+
)
466+
Fd = formulae.drop_growth__Fd(
467+
T=T, D=Dr * mass_ventilation_factor, pvs=pvs
468+
)
469+
minfun_args = (
480470
x_old,
481471
timestep,
482472
attributes.kappa[drop],
483473
attributes.f_org[drop],
484474
rd3,
485475
T,
486476
RH,
487-
lv,
488-
pvs,
489-
Dr,
490-
Kr,
491-
mass_ventilation_factor,
492-
heat_ventilation_factor,
477+
Fk,
478+
Fd,
493479
)
494480
r_dr_dt_old = formulae.drop_growth__r_dr_dt(
495-
RH_eq,
496-
T,
497-
RH,
498-
lv,
499-
pvs,
500-
mass_ventilation_factor * Dr,
501-
heat_ventilation_factor * Kr,
481+
RH_eq=RH_eq, RH=RH, Fk=Fk, Fd=Fd
502482
)
503483
mass_old = formulae.diffusion_coordinate__mass(x_old)
504484
dm_dt_old = formulae.particle_shape_and_density__dm_dt(
@@ -514,8 +494,8 @@ def calculate_ml_new( # pylint: disable=too-many-branches,too-many-arguments,to
514494
else:
515495
a = x_old
516496
b = max(x_insane, a + dx_old)
517-
fa = minfun(a, *args)
518-
fb = minfun(b, *args)
497+
fa = minfun(a, *minfun_args)
498+
fb = minfun(b, *minfun_args)
519499

520500
counter = 0
521501
while not fa * fb < 0:
@@ -545,7 +525,7 @@ def calculate_ml_new( # pylint: disable=too-many-branches,too-many-arguments,to
545525
success = False
546526
break
547527
b = max(x_insane, a + math.ldexp(dx_old, counter))
548-
fb = minfun(b, *args)
528+
fb = minfun(b, *minfun_args)
549529

550530
if not success:
551531
break
@@ -556,7 +536,7 @@ def calculate_ml_new( # pylint: disable=too-many-branches,too-many-arguments,to
556536

557537
x_new, iters_taken = toms748_solve(
558538
minfun,
559-
args,
539+
minfun_args,
560540
a,
561541
b,
562542
fa,
@@ -673,7 +653,7 @@ def solve( # pylint: disable=too-many-arguments,too-many-locals
673653
timestep,
674654
n_substeps,
675655
):
676-
args = (
656+
step_impl_args = (
677657
attributes,
678658
cell_idx,
679659
thd,
@@ -689,7 +669,9 @@ def solve( # pylint: disable=too-many-arguments,too-many-locals
689669
)
690670
success = True
691671
if adaptive:
692-
n_substeps, success = adapt_substeps(args, n_substeps, thd, rtols.thd)
672+
n_substeps, success = adapt_substeps(
673+
step_impl_args, n_substeps, thd, rtols.thd
674+
)
693675
if success:
694676
(
695677
water_vapour_mixing_ratio,
@@ -699,7 +681,7 @@ def solve( # pylint: disable=too-many-arguments,too-many-locals
699681
n_ripening,
700682
RH_max,
701683
success,
702-
) = step(args, timestep, n_substeps)
684+
) = step(step_impl_args, timestep, n_substeps)
703685
else:
704686
n_activating, n_deactivating, n_ripening, RH_max = -1, -1, -1, -1
705687
return (

PySDM/backends/impl_numba/methods/deposition_methods.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,24 @@ def body( # pylint: disable=too-many-arguments
8383
saturation_ratio_ice = (
8484
current_relative_humidity[cid] / current_water_activity[cid]
8585
)
86-
8786
if saturation_ratio_ice == 1:
8887
continue
89-
88+
Fk = formulae.drop_growth__Fk(
89+
T=temperature,
90+
K=thermal_conductivity * heat_ventilation_factor,
91+
lv=latent_heat_sub,
92+
)
93+
Fd = formulae.drop_growth__Fd(
94+
T=temperature,
95+
D=diffusion_coefficient * mass_ventilation_factor,
96+
pvs=pvs_ice,
97+
)
9098
howell_factor_x_diffcoef_x_rhovsice_x_icess = (
9199
formulae.drop_growth__r_dr_dt(
92100
RH_eq=1,
93-
T=temperature,
94101
RH=saturation_ratio_ice,
95-
lv=latent_heat_sub,
96-
pvs=pvs_ice,
97-
D=mass_ventilation_factor * diffusion_coefficient,
98-
K=heat_ventilation_factor * thermal_conductivity,
102+
Fk=Fk,
103+
Fd=Fd,
99104
)
100105
* formulae.constants.rho_w
101106
)

PySDM/backends/impl_numba/test_helpers/scipy_ode_condensation_solver.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,23 @@ def _impl( # pylint: disable=too-many-arguments,too-many-locals
140140
)
141141
heat_ventilation_factor = mass_ventilation_factor # TODO #1588
142142
sgm = jit_formulae.surface_tension__sigma(T, v, dry_volume[i], f_org[i])
143+
Fk = jit_formulae.drop_growth__Fk(
144+
T=T,
145+
lv=lv,
146+
K=heat_ventilation_factor * Kr,
147+
)
148+
Fd = jit_formulae.drop_growth__Fd(
149+
T=T,
150+
pvs=pvs,
151+
D=mass_ventilation_factor * Dr,
152+
)
143153
r_dr_dt = jit_formulae.drop_growth__r_dr_dt(
144-
jit_formulae.hygroscopicity__RH_eq(
154+
RH_eq=jit_formulae.hygroscopicity__RH_eq(
145155
r, T, kappa[i], dry_volume[i] / PI_4_3, sgm
146156
),
147-
T,
148-
RH,
149-
lv,
150-
pvs,
151-
mass_ventilation_factor * Dr,
152-
heat_ventilation_factor * Kr,
157+
RH=RH,
158+
Fk=Fk,
159+
Fd=Fd,
153160
)
154161
dm_dt = jit_formulae.particle_shape_and_density__dm_dt(r, r_dr_dt)
155162
dy_dt[idx_x + i] = jit_formulae.diffusion_coordinate__dx_dt(m, dm_dt)

0 commit comments

Comments
 (0)