Skip to content

Commit 1733049

Browse files
committed
Added smagorinsky factors and heights
1 parent 18b6135 commit 1733049

7 files changed

Lines changed: 174 additions & 61 deletions

File tree

model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion.py

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ def __init__(
149149
hdiff_efdt_ratio: float = 36.0,
150150
hdiff_w_efdt_ratio: float = 15.0,
151151
smagorinski_scaling_factor: float = 0.015,
152+
smagorinski_scaling_factor2: float = 2e-6
153+
* (1600.0 + 25000.0 + math.sqrt(1600.0 * (1600 + 50000.0))),
154+
smagorinski_scaling_factor3: float = 0,
155+
smagorinski_scaling_factor4: float = 1,
156+
smagorinski_scaling_height: float = 32500.0,
157+
smagorinski_scaling_height2: float = 1600.0
158+
+ 50000.0
159+
+ math.sqrt(1600.0 * (1600 + 50000.0)),
160+
smagorinski_scaling_height3: float = 50000.0,
161+
smagorinski_scaling_height4: float = 90000.0,
152162
n_substeps: int = 5,
153163
zdiffu_t: bool = True,
154164
velocity_boundary_diffusion_denom: float = 200.0,
@@ -199,10 +209,41 @@ def __init__(
199209
#: Called 'hdiff_w_efdt_ratio' in mo_diffusion_nml.f90.
200210
self.hdiff_w_efdt_ratio: float = hdiff_w_efdt_ratio
201211

202-
#: Scaling factor for Smagorinsky diffusion at height hdiff_smag_z and below
212+
#: Scaling factor for Smagorinsky diffusion at height smagorinski_scaling_height and below
203213
#: Called 'hdiff_smag_fac' in mo_diffusion_nml.f90
204214
self.smagorinski_scaling_factor: float = smagorinski_scaling_factor
205215

216+
#: Scaling factor for Smagorinsky diffusion at height smagorinski_scaling_height to smagorinski_scaling_height2
217+
#: This is the linearly interpolated part
218+
#: Called 'hdiff_smag_fac2' in mo_diffusion_nml.f90
219+
self.smagorinski_scaling_factor2: float = smagorinski_scaling_factor2
220+
221+
#: Scaling factor for Smagorinsky diffusion at height smagorinski_scaling_height2 to smagorinski_scaling_height3
222+
#: This is the quadratically interpolated part
223+
#: Called 'hdiff_smag_fac3' in mo_diffusion_nml.f90
224+
self.smagorinski_scaling_factor3: float = smagorinski_scaling_factor3
225+
226+
#: Scaling factor for Smagorinsky diffusion at height smagorinski_scaling_height3 to smagorinski_scaling_height4
227+
#: This is the quadratically interpolated part
228+
#: Called 'hdiff_smag_fac4' in mo_diffusion_nml.f90
229+
self.smagorinski_scaling_factor4: float = smagorinski_scaling_factor4
230+
231+
#: Height for Smagorinsky diffusion expressing the border between constant and linear interpolation
232+
#: Called 'hdiff_smag_z' in mo_diffusion_nml.f90
233+
self.smagorinski_scaling_height: float = smagorinski_scaling_height
234+
235+
#: Height for Smagorinsky diffusion expressing the border between linear and quadratic interpolation
236+
#: Called 'hdiff_smag_z2' in mo_diffusion_nml.f90
237+
self.smagorinski_scaling_height2: float = smagorinski_scaling_height2
238+
239+
#: Height for Smagorinsky diffusion expressing the middle of the quadratic interpolation region
240+
#: Called 'hdiff_smag_z3' in mo_diffusion_nml.f90
241+
self.smagorinski_scaling_height3: float = smagorinski_scaling_height3
242+
243+
#: Height for Smagorinsky diffusion expressing the top of the quadratic interpolation region
244+
#: Called 'hdiff_smag_z4' in mo_diffusion_nml.f90
245+
self.smagorinski_scaling_height4: float = smagorinski_scaling_height4
246+
206247
#: If True, apply truly horizontal temperature diffusion over steep slopes
207248
#: Called 'l_zdiffu_t' in mo_nonhydrostatic_nml.f90
208249
self.apply_zdiffusion_t: bool = zdiffu_t
@@ -329,53 +370,26 @@ def __post_init__(self, config):
329370
(1.0 / (config.hdiff_w_efdt_ratio * 36.0) if config.hdiff_w_efdt_ratio > 0 else 0.0),
330371
)
331372

332-
(
333-
smagorinski_factor,
334-
smagorinski_height,
335-
) = self._determine_smagorinski_factor(config)
336-
object.__setattr__(self, "smagorinski_factor", smagorinski_factor)
337-
object.__setattr__(self, "smagorinski_height", smagorinski_height)
338-
339-
def _determine_smagorinski_factor(self, config: DiffusionConfig):
340-
"""Enhanced Smagorinsky diffusion factor.
341-
342-
Smagorinsky diffusion factor is defined as a profile in height
343-
above sea level with 4 height sections.
344-
345-
It is calculated/used only in the case of diffusion_type 3 or 5
346-
"""
347-
match config.diffusion_type:
348-
case 5:
349-
(
350-
smagorinski_factor,
351-
smagorinski_height,
352-
) = diffusion_type_5_smagorinski_factor(config)
353-
case 4:
354-
# according to mo_nh_diffusion.f90 this isn't used anywhere the factor is only
355-
# used for diffusion_type (3,5) but the defaults are only defined for iequations=3
356-
smagorinski_factor = (
357-
config.smagorinski_scaling_factor
358-
if config.smagorinski_scaling_factor
359-
else 0.15,
360-
)
361-
smagorinski_height = None
362-
case _:
363-
raise NotImplementedError("Only implemented for diffusion type 4 and 5")
364-
return smagorinski_factor, smagorinski_height
365-
366-
367-
def diffusion_type_5_smagorinski_factor(config: DiffusionConfig):
368-
"""
369-
Initialize Smagorinski factors used in diffusion type 5.
370-
371-
The calculation and magic numbers are taken from mo_diffusion_nml.f90
372-
"""
373-
magic_sqrt = math.sqrt(1600.0 * (1600 + 50000.0))
374-
magic_fac2_value = 2e-6 * (1600.0 + 25000.0 + magic_sqrt)
375-
magic_z2 = 1600.0 + 50000.0 + magic_sqrt
376-
factor = (config.smagorinski_scaling_factor, magic_fac2_value, 0.0, 1.0)
377-
heights = (32500.0, magic_z2, 50000.0, 90000.0)
378-
return factor, heights
373+
object.__setattr__(
374+
self,
375+
"smagorinski_factor",
376+
(
377+
config.smagorinski_scaling_factor,
378+
config.smagorinski_scaling_factor2,
379+
config.smagorinski_scaling_factor3,
380+
config.smagorinski_scaling_factor4,
381+
),
382+
)
383+
object.__setattr__(
384+
self,
385+
"smagorinski_height",
386+
(
387+
config.smagorinski_scaling_height,
388+
config.smagorinski_scaling_height2,
389+
config.smagorinski_scaling_height3,
390+
config.smagorinski_scaling_height4,
391+
),
392+
)
379393

380394

381395
class Diffusion:

model/atmosphere/diffusion/tests/diffusion/integration_tests/test_diffusion.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,6 @@ def test_diffusion_coefficients_without_hdiff_efdt_ratio(experiment):
120120
assert params.K4W == 0.0
121121

122122

123-
def test_smagorinski_factor_for_diffusion_type_4(experiment):
124-
config = definitions.construct_diffusion_config(experiment, ndyn_substeps=5)
125-
config.smagorinski_scaling_factor = 0.15
126-
config.diffusion_type = 4
127-
128-
params = diffusion.DiffusionParams(config)
129-
assert len(params.smagorinski_factor) == 1
130-
assert params.smagorinski_factor[0] == pytest.approx(0.15, abs=1e-16)
131-
assert params.smagorinski_height is None
132-
133123

134124
def test_smagorinski_heights_diffusion_type_5_are_consistent(
135125
experiment,

tools/src/icon4py/tools/py2fgen/wrappers/diffusion_wrapper.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ def diffusion_init(
8484
hdiff_efdt_ratio: gtx.float64,
8585
hdiff_w_efdt_ratio: gtx.float64,
8686
smagorinski_scaling_factor: gtx.float64,
87+
smagorinski_scaling_factor2: gtx.float64,
88+
smagorinski_scaling_factor3: gtx.float64,
89+
smagorinski_scaling_factor4: gtx.float64,
90+
smagorinski_scaling_height: gtx.float64,
91+
smagorinski_scaling_height2: gtx.float64,
92+
smagorinski_scaling_height3: gtx.float64,
93+
smagorinski_scaling_height4: gtx.float64,
8794
hdiff_temp: bool,
8895
denom_diffu_v: float,
8996
nudge_max_coeff: float, # note: this is the scaled ICON value, i.e. not the namelist value
@@ -117,6 +124,13 @@ def diffusion_init(
117124
hdiff_efdt_ratio=hdiff_efdt_ratio,
118125
hdiff_w_efdt_ratio=hdiff_w_efdt_ratio,
119126
smagorinski_scaling_factor=smagorinski_scaling_factor,
127+
smagorinski_scaling_factor2=smagorinski_scaling_factor2,
128+
smagorinski_scaling_factor3=smagorinski_scaling_factor3,
129+
smagorinski_scaling_factor4=smagorinski_scaling_factor4,
130+
smagorinski_scaling_height=smagorinski_scaling_height,
131+
smagorinski_scaling_height2=smagorinski_scaling_height2,
132+
smagorinski_scaling_height3=smagorinski_scaling_height3,
133+
smagorinski_scaling_height4=smagorinski_scaling_height4,
120134
hdiff_temp=hdiff_temp,
121135
n_substeps=ndyn_substeps,
122136
velocity_boundary_diffusion_denom=denom_diffu_v,

tools/tests/tools/py2fgen/wrappers/references/diffusion/diffusion.f90

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ function diffusion_init_wrapper(theta_ref_mc, &
152152
hdiff_efdt_ratio, &
153153
hdiff_w_efdt_ratio, &
154154
smagorinski_scaling_factor, &
155+
smagorinski_scaling_factor2, &
156+
smagorinski_scaling_factor3, &
157+
smagorinski_scaling_factor4, &
158+
smagorinski_scaling_height, &
159+
smagorinski_scaling_height2, &
160+
smagorinski_scaling_height3, &
161+
smagorinski_scaling_height4, &
155162
hdiff_temp, &
156163
denom_diffu_v, &
157164
nudge_max_coeff, &
@@ -260,6 +267,20 @@ function diffusion_init_wrapper(theta_ref_mc, &
260267

261268
real(c_double), value, target :: smagorinski_scaling_factor
262269

270+
real(c_double), value, target :: smagorinski_scaling_factor2
271+
272+
real(c_double), value, target :: smagorinski_scaling_factor3
273+
274+
real(c_double), value, target :: smagorinski_scaling_factor4
275+
276+
real(c_double), value, target :: smagorinski_scaling_height
277+
278+
real(c_double), value, target :: smagorinski_scaling_height2
279+
280+
real(c_double), value, target :: smagorinski_scaling_height3
281+
282+
real(c_double), value, target :: smagorinski_scaling_height4
283+
263284
logical(c_int), value, target :: hdiff_temp
264285

265286
real(c_double), value, target :: denom_diffu_v
@@ -493,6 +514,13 @@ subroutine diffusion_init(theta_ref_mc, &
493514
hdiff_efdt_ratio, &
494515
hdiff_w_efdt_ratio, &
495516
smagorinski_scaling_factor, &
517+
smagorinski_scaling_factor2, &
518+
smagorinski_scaling_factor3, &
519+
smagorinski_scaling_factor4, &
520+
smagorinski_scaling_height, &
521+
smagorinski_scaling_height2, &
522+
smagorinski_scaling_height3, &
523+
smagorinski_scaling_height4, &
496524
hdiff_temp, &
497525
denom_diffu_v, &
498526
nudge_max_coeff, &
@@ -550,6 +578,20 @@ subroutine diffusion_init(theta_ref_mc, &
550578

551579
real(c_double), value, target :: smagorinski_scaling_factor
552580

581+
real(c_double), value, target :: smagorinski_scaling_factor2
582+
583+
real(c_double), value, target :: smagorinski_scaling_factor3
584+
585+
real(c_double), value, target :: smagorinski_scaling_factor4
586+
587+
real(c_double), value, target :: smagorinski_scaling_height
588+
589+
real(c_double), value, target :: smagorinski_scaling_height2
590+
591+
real(c_double), value, target :: smagorinski_scaling_height3
592+
593+
real(c_double), value, target :: smagorinski_scaling_height4
594+
553595
logical(c_int), value, target :: hdiff_temp
554596

555597
real(c_double), value, target :: denom_diffu_v
@@ -752,6 +794,13 @@ subroutine diffusion_init(theta_ref_mc, &
752794
hdiff_efdt_ratio=hdiff_efdt_ratio, &
753795
hdiff_w_efdt_ratio=hdiff_w_efdt_ratio, &
754796
smagorinski_scaling_factor=smagorinski_scaling_factor, &
797+
smagorinski_scaling_factor2=smagorinski_scaling_factor2, &
798+
smagorinski_scaling_factor3=smagorinski_scaling_factor3, &
799+
smagorinski_scaling_factor4=smagorinski_scaling_factor4, &
800+
smagorinski_scaling_height=smagorinski_scaling_height, &
801+
smagorinski_scaling_height2=smagorinski_scaling_height2, &
802+
smagorinski_scaling_height3=smagorinski_scaling_height3, &
803+
smagorinski_scaling_height4=smagorinski_scaling_height4, &
755804
hdiff_temp=hdiff_temp, &
756805
denom_diffu_v=denom_diffu_v, &
757806
nudge_max_coeff=nudge_max_coeff, &

tools/tests/tools/py2fgen/wrappers/references/diffusion/diffusion.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ extern int diffusion_init_wrapper(
2323
int ndyn_substeps, int diffusion_type, int hdiff_w, int hdiff_vn,
2424
int hdiff_smag_w, int zdiffu_t, int type_t_diffu, int type_vn_diffu,
2525
double hdiff_efdt_ratio, double hdiff_w_efdt_ratio,
26-
double smagorinski_scaling_factor, int hdiff_temp, double denom_diffu_v,
27-
double nudge_max_coeff, int itype_sher, int ltkeshs, int backend,
28-
int on_gpu);
26+
double smagorinski_scaling_factor, double smagorinski_scaling_factor2,
27+
double smagorinski_scaling_factor3, double smagorinski_scaling_factor4,
28+
double smagorinski_scaling_height, double smagorinski_scaling_height2,
29+
double smagorinski_scaling_height3, double smagorinski_scaling_height4,
30+
int hdiff_temp, double denom_diffu_v, double nudge_max_coeff,
31+
int itype_sher, int ltkeshs, int backend, int on_gpu);

tools/tests/tools/py2fgen/wrappers/references/diffusion/diffusion.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,13 @@ def diffusion_init_wrapper(
391391
hdiff_efdt_ratio,
392392
hdiff_w_efdt_ratio,
393393
smagorinski_scaling_factor,
394+
smagorinski_scaling_factor2,
395+
smagorinski_scaling_factor3,
396+
smagorinski_scaling_factor4,
397+
smagorinski_scaling_height,
398+
smagorinski_scaling_height2,
399+
smagorinski_scaling_height3,
400+
smagorinski_scaling_height4,
394401
hdiff_temp,
395402
denom_diffu_v,
396403
nudge_max_coeff,
@@ -566,6 +573,13 @@ def diffusion_init_wrapper(
566573
hdiff_efdt_ratio=hdiff_efdt_ratio,
567574
hdiff_w_efdt_ratio=hdiff_w_efdt_ratio,
568575
smagorinski_scaling_factor=smagorinski_scaling_factor,
576+
smagorinski_scaling_factor2=smagorinski_scaling_factor2,
577+
smagorinski_scaling_factor3=smagorinski_scaling_factor3,
578+
smagorinski_scaling_factor4=smagorinski_scaling_factor4,
579+
smagorinski_scaling_height=smagorinski_scaling_height,
580+
smagorinski_scaling_height2=smagorinski_scaling_height2,
581+
smagorinski_scaling_height3=smagorinski_scaling_height3,
582+
smagorinski_scaling_height4=smagorinski_scaling_height4,
569583
hdiff_temp=hdiff_temp,
570584
denom_diffu_v=denom_diffu_v,
571585
nudge_max_coeff=nudge_max_coeff,

tools/tests/tools/py2fgen/wrappers/test_diffusion_wrapper.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# Please, refer to the LICENSE file in the root directory.
77
# SPDX-License-Identifier: BSD-3-Clause
88

9+
import math
910
from unittest import mock
1011

1112
import cffi
@@ -60,6 +61,13 @@ def test_diffusion_wrapper_granule_inputs(
6061
hdiff_efdt_ratio = 24.0
6162
hdiff_w_efdt_ratio = 15.0
6263
smagorinski_scaling_factor = 0.025
64+
smagorinski_scaling_factor2 = 2e-6 * (1600.0 + 25000.0 + math.sqrt(1600.0 * (1600 + 50000.0)))
65+
smagorinski_scaling_factor3 = 0.0
66+
smagorinski_scaling_factor4 = 1.0
67+
smagorinski_scaling_height = 32500.0
68+
smagorinski_scaling_height2 = 1600.0 + 50000.0 + math.sqrt(1600.0 * (1600 + 50000.0))
69+
smagorinski_scaling_height3 = 50000.0
70+
smagorinski_scaling_height4 = 90000.0
6371
zdiffu_t = True
6472
denom_diffu_v = 150.0
6573
max_nudging_coefficient = 0.375
@@ -183,6 +191,13 @@ def test_diffusion_wrapper_granule_inputs(
183191
hdiff_efdt_ratio=hdiff_efdt_ratio,
184192
hdiff_w_efdt_ratio=hdiff_w_efdt_ratio,
185193
smagorinski_scaling_factor=smagorinski_scaling_factor,
194+
smagorinski_scaling_factor2=smagorinski_scaling_factor2,
195+
smagorinski_scaling_factor3=smagorinski_scaling_factor3,
196+
smagorinski_scaling_factor4=smagorinski_scaling_factor4,
197+
smagorinski_scaling_height=smagorinski_scaling_height,
198+
smagorinski_scaling_height2=smagorinski_scaling_height2,
199+
smagorinski_scaling_height3=smagorinski_scaling_height3,
200+
smagorinski_scaling_height4=smagorinski_scaling_height4,
186201
hdiff_temp=hdiff_temp,
187202
denom_diffu_v=denom_diffu_v,
188203
nudge_max_coeff=max_nudging_coefficient,
@@ -297,6 +312,13 @@ def test_diffusion_wrapper_single_step(
297312
hdiff_efdt_ratio = 24.0
298313
hdiff_w_efdt_ratio = 15.0
299314
smagorinski_scaling_factor = 0.025
315+
smagorinski_scaling_factor2 = 2e-6 * (1600.0 + 25000.0 + math.sqrt(1600.0 * (1600 + 50000.0)))
316+
smagorinski_scaling_factor3 = 0.0
317+
smagorinski_scaling_factor4 = 1.0
318+
smagorinski_scaling_height = 32500.0
319+
smagorinski_scaling_height2 = 1600.0 + 50000.0 + math.sqrt(1600.0 * (1600 + 50000.0))
320+
smagorinski_scaling_height3 = 50000.0
321+
smagorinski_scaling_height4 = 90000.0
300322
zdiffu_t = True
301323
denom_diffu_v = 150.0
302324
max_nudging_coefficient = 0.375
@@ -387,6 +409,13 @@ def test_diffusion_wrapper_single_step(
387409
hdiff_efdt_ratio=hdiff_efdt_ratio,
388410
hdiff_w_efdt_ratio=hdiff_w_efdt_ratio,
389411
smagorinski_scaling_factor=smagorinski_scaling_factor,
412+
smagorinski_scaling_factor2=smagorinski_scaling_factor2,
413+
smagorinski_scaling_factor3=smagorinski_scaling_factor3,
414+
smagorinski_scaling_factor4=smagorinski_scaling_factor4,
415+
smagorinski_scaling_height=smagorinski_scaling_height,
416+
smagorinski_scaling_height2=smagorinski_scaling_height2,
417+
smagorinski_scaling_height3=smagorinski_scaling_height3,
418+
smagorinski_scaling_height4=smagorinski_scaling_height4,
390419
hdiff_temp=hdiff_temp,
391420
denom_diffu_v=denom_diffu_v,
392421
nudge_max_coeff=max_nudging_coefficient,

0 commit comments

Comments
 (0)