Skip to content

Commit 2cad3b2

Browse files
Merge branch 'main' into add-fortran-linter
2 parents ec1c05d + 12bf377 commit 2cad3b2

44 files changed

Lines changed: 713 additions & 311 deletions

File tree

Some content is hidden

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

applications/lfric_atm/metadata/axis_def_main.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@
3333
<axis id="sw_bands_radiation_levels" name="sw_bands_radiation_levels" />
3434
<axis id="lw_bands_radiation_levels" name="lw_bands_radiation_levels" />
3535
<axis id="photolysis_pathways" name="photolysis_pathways" />
36-
<axis id="photol_species" name="photol_species" />
36+
<axis id="photol_species" name="photol_species" />
3737
<axis id="one_time_axis" name="one_time_axis" n_glo="1" />
3838

3939
<axis id="random_seed_size" name="random_seed_size" />
40+
<axis id="stph_spectral_dimensions" name="stph_spectral_dimensions" />
4041
<axis id="scalar_axis" name="scalar" n_glo="1" />
4142
<axis id="aod_wavel" name="aod_wavel" />
4243

applications/lfric_atm/metadata/grid_def_main.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<domain domain_ref="face"/>
4141
<axis axis_ref="vert_axis_full_levels"/>
4242
<axis axis_ref="photol_species"/>
43-
</grid>
43+
</grid>
4444
<grid id="3D_monthly_grid">
4545
<domain domain_ref="face"/>
4646
<axis axis_ref="vert_axis_full_levels"/>
@@ -118,6 +118,9 @@
118118
<grid id="random_seed_grid">
119119
<axis axis_ref="random_seed_size"/>
120120
</grid>
121+
<grid id="stochastic_physics_grid">
122+
<axis axis_ref="stph_spectral_dimensions"/>
123+
</grid>
121124
<!-- Zoom filters -->
122125
<grid id="full_level_0_face_zoom">
123126
<domain domain_ref="face"/>

applications/lfric_atm/metadata/lfric_dictionary.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,16 @@
351351
<field id="aer_lw_absorption" name="aer_lw_absorption" long_name="aer_lw_absorption" unit="1" grid_ref="full_level_face_grid_lw_bands_aero_modes" />
352352
<field id="aer_lw_scattering" name="aer_lw_scattering" long_name="aer_lw_scattering" unit="1" grid_ref="full_level_face_grid_lw_bands_aero_modes" />
353353
<field id="aer_lw_asymmetry" name="aer_lw_asymmetry" long_name="aer_lw_asymmetry" unit="1" grid_ref="full_level_face_grid_lw_bands_aero_modes" />
354-
<!-- stochastic fields -->
354+
<!-- stochastic fields -->
355355
<field id="blpert_rand_fld" name="blpert_rand_fld" long_name="blpert_random_number" unit="1" domain_ref="face" />
356356
<field id="blpert_flag" name="blpert_flag" long_name="blpert_perturbed_flag" unit="1" domain_ref="face" />
357357
<field id="random_seed" name="random_seed" long_name="random_seed_for_stochastic_physics" unit="1" grid_ref="random_seed_grid" />
358+
<field id="spt_spectral_coeffc" name="spt_spectral_coeffc" long_name="spt_real_spectral_coefficients_for_stochastic_physics" unit="1" grid_ref="stochastic_physics_grid" />
359+
<field id="spt_spectral_coeffs" name="spt_spectral_coeffs" long_name="spt_imaginary_spectral_coefficients_for_stochastic_physics" unit="1" grid_ref="stochastic_physics_grid" />
360+
<field id="spt_power_law" name="spt_power_law" long_name="spt_power_law_for_stochastic_physics" unit="1" grid_ref="stochastic_physics_grid" />
361+
<field id="skeb_spectral_coeffc" name="skeb_spectral_coeffc" long_name="skeb_real_spectral_coefficients_for_stochastic_physics" unit="1" grid_ref="stochastic_physics_grid" />
362+
<field id="skeb_spectral_coeffs" name="skeb_spectral_coeffs" long_name="skeb_imaginary_spectral_coefficients_for_stochastic_physics" unit="1" grid_ref="stochastic_physics_grid" />
363+
<field id="skeb_power_law" name="skeb_power_law" long_name="skeb_power_law_for_stochastic_physics" unit="1" grid_ref="stochastic_physics_grid" />
358364
<!-- snow fields -->
359365
<field id="tile_snow_mass" name="tile_snow_mass" long_name="tile_snow_mass" unit="kg m-2" domain_ref="face" axis_ref="surface_tiles" />
360366
<field id="tile_snow_rgrain" name="tile_snow_rgrain" long_name="tile_snow_grain_size" unit="microns" domain_ref="face" axis_ref="surface_tiles" />

interfaces/physics_schemes_interface/source/algorithm/skeb_main_alg_mod.x90

Lines changed: 86 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ module skeb_main_alg_mod
2121
! use collections
2222
use function_space_collection_mod, only: function_space_collection
2323
use mesh_collection_mod, only: mesh_collection
24+
! Physical constants
25+
use planet_constants_mod, only: planet_radius
26+
2427
! xios output and timers
2528
use io_config_mod, only: write_diag, use_xios_io
2629
use timing_mod, only: start_timing, stop_timing, tik, LPROF
@@ -38,8 +41,6 @@ module skeb_main_alg_mod
3841

3942
private
4043

41-
! Logical controlling whether spectral coeffs need calculating
42-
logical(kind=l_def), save :: initialize_skeb_spectral_coeffs = .true.
4344
logical(kind=l_def ) :: du_rot_skeb_flag
4445
logical(kind=l_def ) :: dv_rot_skeb_flag
4546
logical(kind=l_def ) :: du_div_skeb_flag
@@ -56,7 +57,7 @@ module skeb_main_alg_mod
5657
real(kind=r_def), parameter :: TWOP_P1 = 2.0_r_def*P + 1.0_r_def
5758
real(kind=r_def), parameter :: FOUR_ON_VAR = 48.0_r_def
5859

59-
public skeb_main_alg
60+
public skeb_main_alg, skeb_init_power_law
6061

6162
contains
6263
!>@brief Run the Stochastic Kinetic Energy Backscatter (SKEB)
@@ -87,13 +88,18 @@ module skeb_main_alg_mod
8788
!> 8) Add wind increments to the flow and diagnostics
8889
!>
8990
!> See UMD81 for full scheme details
90-
!>@param[in] du_stph Stochastic Physics increments for winds
91-
!>@param[in] rho Density on W3
92-
!>@param[in] u prognostic winds in W2
93-
!>@param[in] convection_fields Fields from convection scheme
94-
!>@param[in] clock Model time information
95-
96-
subroutine skeb_main_alg(du_stph, rho, u, convection_fields, derived_fields, clock)
91+
!>@param[in] du_stph Stochastic Physics increments for winds
92+
!>@param[in] rho Density on W3
93+
!>@param[in] u prognostic winds in W2
94+
!>@param[in] convection_fields Fields from convection scheme
95+
!>@param[in,out] skeb_spectral_coeffc Real Spectral coefficients
96+
!>@param[in,out] skeb_spectral_coeffs Imaginary Spectral coefficients
97+
!>@param[in,out] skeb_power_law Spectral power law
98+
!>@param[in] clock Model time information
99+
100+
subroutine skeb_main_alg(du_stph, rho, u, convection_fields, derived_fields, &
101+
skeb_spectral_coeffc, skeb_spectral_coeffs, &
102+
skeb_power_law, clock)
97103

98104
! SKEB namelist options
99105
use stochastic_physics_config_mod, only: &
@@ -174,9 +180,6 @@ module skeb_main_alg_mod
174180
! extract u and v from SKEB winds for diagnostics
175181
use physics_mappings_alg_mod, only: map_physics_winds
176182

177-
! Physical constants
178-
use planet_constants_mod, only: planet_radius
179-
180183
use sci_enforce_upper_bound_kernel_mod, only: enforce_upper_bound_kernel_type
181184
use enforce_crit_kernel_mod, only: enforce_crit_kernel_type
182185

@@ -193,6 +196,11 @@ module skeb_main_alg_mod
193196
type( field_collection_type ), intent(in) :: convection_fields
194197
type( field_collection_type ), intent(in) :: derived_fields
195198

199+
! Spectral coefficients
200+
real(r_def), intent(inout) :: skeb_spectral_coeffc(:)
201+
real(r_def), intent(inout) :: skeb_spectral_coeffs(:)
202+
real(r_def), intent(inout) :: skeb_power_law(:)
203+
196204
! classes
197205
class(clock_type), intent(in) :: clock
198206

@@ -274,27 +282,22 @@ module skeb_main_alg_mod
274282
!w2 intermediate field for scaling by cos(lat)
275283
type( field_type ) :: field_w2
276284

277-
! Spectral coefficients
278-
real(kind=r_def), allocatable, save :: skeb_spectral_coeffc(:)
279-
real(kind=r_def), allocatable, save :: skeb_spectral_coeffs(:)
280-
real(kind=r_def), allocatable, save :: skeb_power_law(:)
281-
282285
! time decorrelation parameter
283-
real(kind=r_def), save :: skeb_alpha
286+
real(kind=r_def) :: skeb_alpha
284287

285288
! Convective resolution factor to modulate conv mask
286289
real(kind=r_def) :: convective_resolution_factor
287290

288291
! scaling total dissipation by br/total_backscatter
289292
real(kind=r_def) :: factor_psif, max_backscatter, crit_backscatter
290293
! parameters for the power law and decorrelation time alpha
291-
real(kind=r_def) :: gamma, dt, spl_coeff
294+
real(kind=r_def) :: dt
292295

293296
! mesh_id
294297
integer(kind=i_def) :: mesh_id
295298

296299
! Iterators in for loops
297-
integer(i_def) :: m, n, n_row, stencil_extent
300+
integer(i_def) :: n, stencil_extent
298301

299302
! SKEB calculations are performed at cell centres (W3 points). To index the
300303
! "eta_theta_levels" array correctly at these points, set offset to 1
@@ -325,66 +328,13 @@ module skeb_main_alg_mod
325328
setval_c(fp_skeb, 0.0_r_def) )
326329

327330
dt = real(clock%get_seconds_per_step(), r_def)
331+
skeb_alpha=1-exp(-dt/skeb_decorrelation_time)
328332

329333
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
330334
!! 1) Create Forcing Pattern !!
331335
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
332336

333-
! Initialize spectral coefficients for the forcing pattern
334-
if (initialize_skeb_spectral_coeffs) then
335-
336-
!allocate spectral coefficients and power law
337-
allocate(skeb_spectral_coeffc(stph_spectral_dim))
338-
allocate(skeb_spectral_coeffs(stph_spectral_dim))
339-
allocate(skeb_power_law(stph_spectral_dim))
340-
341-
! set them to zero (invokes don't work for non-fields types)
342-
skeb_spectral_coeffc = 0.0_r_def
343-
skeb_spectral_coeffs = 0.0_r_def
344-
skeb_power_law = 0.0_r_def
345-
346-
!!!!!! 1.a compute power law
347-
348-
! compute alpha for temporal decorrelation
349-
skeb_alpha=1-exp(-dt/skeb_decorrelation_time)
350-
351-
! This power law is what Glenn Shutts observed in the CRM simulations
352-
! (see Berner et al., 2009: J. Atmos. Sci, pp 603-626)
353-
gamma = 0.0_r_def
354-
do n = stph_n_min, stph_n_max
355-
gamma = gamma + (n+1)*(2*n+1)*n**(TWOP_P1)
356-
end do
357-
gamma = gamma/skeb_alpha
358-
359-
! Below we calculate the power law which is given as
360-
! g(n) = spl_coeff * n^p
361-
! where
362-
! spl_coeff = SQRT([4 * Pi * a^2 * skeb_total_backscatter]/[dt * var * gamma])
363-
! var is the variance of random numbers [-0.5; 0.5] = 1/12
364-
! tested by 1000 cases of random arrays of size = 1e9
365-
! note: (4/var) is pre-calculated as FOUR_ON_VAR = 48
366-
367-
! Set n_row as the summatory of n
368-
n_row = 0
369-
! add up those scales below the minimum wavenumber to the
370-
! row iterator
371-
do n = 1, stph_n_min-1
372-
n_row = n_row + n
373-
end do
374-
375-
! Build power law
376-
spl_coeff = planet_radius * sqrt(FOUR_ON_VAR*pi*skeb_total_backscatter/ &
377-
(dt*gamma))
378-
do n = stph_n_min, stph_n_max
379-
n_row = n_row + n
380-
do m = 0, n
381-
skeb_power_law(n_row + m) = spl_coeff * n**P
382-
end do
383-
end do
384-
initialize_skeb_spectral_coeffs = .false.
385-
end if
386-
387-
!!!!!! 1.b call stph_fp_main to create forcing pattern for SKEB
337+
!!!!!! Create forcing pattern for SKEB
388338
call stph_fp_main_alg(skeb_level_bottom-1_i_def, skeb_level_top-1_i_def, &
389339
lev_offset, stph_n_min, stph_n_max, stph_spectral_dim, &
390340
skeb_alpha, skeb_power_law, &
@@ -701,4 +651,64 @@ module skeb_main_alg_mod
701651
end if ! end if write_diags and use_xios
702652

703653
end subroutine skeb_main_alg
654+
655+
! Initialise the power law array
656+
! @param[out] skeb_power_law Power law array
657+
! @param[in] clock Model clock
658+
subroutine skeb_init_power_law(skeb_power_law, clock)
659+
use stochastic_physics_config_mod, only: skeb_decorrelation_time, &
660+
skeb_total_backscatter, &
661+
stph_n_min, stph_n_max
662+
663+
real(r_def), intent(out) :: skeb_power_law(:)
664+
class(clock_type), intent(in) :: clock
665+
666+
! time decorrelation parameter
667+
real(kind=r_def) :: skeb_alpha
668+
real(kind=r_def) :: gamma, dt, spl_coeff
669+
670+
! Iterators in for loops
671+
integer(i_def) :: m, n, n_row
672+
673+
skeb_power_law = 0.0_r_def
674+
675+
! compute alpha for temporal decorrelation
676+
dt = real(clock%get_seconds_per_step(), r_def)
677+
skeb_alpha=1-exp(-dt/skeb_decorrelation_time)
678+
679+
! This power law is what Glenn Shutts observed in the CRM simulations
680+
! (see Berner et al., 2009: J. Atmos. Sci, pp 603-626)
681+
gamma = 0.0_r_def
682+
do n = stph_n_min, stph_n_max
683+
gamma = gamma + (n+1)*(2*n+1)*n**(TWOP_P1)
684+
end do
685+
gamma = gamma/skeb_alpha
686+
687+
! Below we calculate the power law which is given as
688+
! g(n) = spl_coeff * n^p
689+
! where
690+
! spl_coeff = SQRT([4 * Pi * a^2 * skeb_total_backscatter]/[dt * var * gamma])
691+
! var is the variance of random numbers [-0.5; 0.5] = 1/12
692+
! tested by 1000 cases of random arrays of size = 1e9
693+
! note: (4/var) is pre-calculated as FOUR_ON_VAR = 48
694+
695+
! Set n_row as the summatory of n
696+
n_row = 0
697+
! add up those scales below the minimum wavenumber to the
698+
! row iterator
699+
do n = 1, stph_n_min-1
700+
n_row = n_row + n
701+
end do
702+
703+
! Build power law
704+
spl_coeff = planet_radius * sqrt(FOUR_ON_VAR*pi*skeb_total_backscatter/ &
705+
(dt*gamma))
706+
do n = stph_n_min, stph_n_max
707+
n_row = n_row + n
708+
do m = 0, n
709+
skeb_power_law(n_row + m) = spl_coeff * n**P
710+
end do
711+
end do
712+
713+
end subroutine skeb_init_power_law
704714
end module skeb_main_alg_mod

0 commit comments

Comments
 (0)