Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b695688

Browse files
author
Robin Hogan
committedNov 23, 2023
Capability to use different gas models (ECCKD & RRTMG) in the shortwave and longwave
1 parent 8a9e3ce commit b695688

10 files changed

+448
-230
lines changed
 

‎CHANGELOG

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ version 1.6.1
1818
optimization options as preprocessor parameters
1919
- Replaced slow "sum" intrinsic function in McICA and Tripleclouds
2020
solvers with optimized versions for x86-64 and DWD's NEC
21+
- Enable different gas optics models for shortwave and longwave:
22+
namelist gas_model_name can still be used, or use
23+
sw_gas_model_name and lw_gas_model_name to specify separate models
2124

2225
version 1.6.0 (27 April 2023)
2326
- Removed compiler flag specifying to load unformated Fortran

‎radiation/radiation_config.F90

+2-1
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ subroutine read_config_from_namelist(this, file_name, unit, is_success)
704704
character(511) :: gas_optics_sw_override_file_name, gas_optics_lw_override_file_name
705705
character(511) :: ssi_override_file_name
706706
character(63) :: liquid_model_name, ice_model_name, gas_model_name
707+
character(63) :: sw_gas_model_name, lw_gas_model_name
707708
character(63) :: sw_solver_name, lw_solver_name, overlap_scheme_name
708709
character(63) :: sw_entrapment_name, sw_encroachment_name, cloud_pdf_shape_name
709710
character(len=511) :: cloud_type_name(NMaxCloudTypes) = ["","","","","","","","","","","",""]
@@ -729,7 +730,7 @@ subroutine read_config_from_namelist(this, file_name, unit, is_success)
729730
& do_save_spectral_flux, do_save_gpoint_flux, &
730731
& do_surface_sw_spectral_flux, do_lw_derivatives, do_toa_spectral_flux, &
731732
& do_lw_aerosol_scattering, do_lw_cloud_scattering, &
732-
& n_regions, directory_name, gas_model_name, &
733+
& n_regions, directory_name, gas_model_name, sw_gas_model_name, lw_gas_model_name, &
733734
& ice_optics_override_file_name, liq_optics_override_file_name, &
734735
& aerosol_optics_override_file_name, cloud_pdf_override_file_name, &
735736
& gas_optics_sw_override_file_name, gas_optics_lw_override_file_name, &

‎radiation/radiation_ecckd.F90

+27-5
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ end subroutine read_spectral_solar_cycle
448448
! at nlev layers
449449
subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nmaxgas, &
450450
& pressure_hl, temperature_fl, mole_fraction_fl, &
451-
& optical_depth_fl, rayleigh_od_fl)
451+
& optical_depth_fl, rayleigh_od_fl, concentration_scaling)
452452

453453
use yomhook, only : lhook, dr_hook, jphook
454454
use radiation_constants, only : AccelDueToGravity
@@ -464,6 +464,8 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm
464464
real(jprb), intent(in) :: temperature_fl(istartcol:iendcol,nlev)
465465
! Gas mole fractions at full levels (mol mol-1), dimensioned (ncol,nlev,nmaxgas)
466466
real(jprb), intent(in) :: mole_fraction_fl(ncol,nlev,nmaxgas)
467+
! Optional concentration scaling of each gas
468+
real(jprb), optional, intent(in) :: concentration_scaling(nmaxgas)
467469

468470
! Output variables
469471

@@ -484,6 +486,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm
484486
!real(jprb) :: od_single_gas(this%ng)
485487

486488
real(jprb) :: multiplier(nlev), simple_multiplier(nlev), global_multiplier, temperature1
489+
real(jprb) :: scaling
487490

488491
! Indices and weights in temperature, pressure and concentration interpolation
489492
real(jprb) :: pindex1, tindex1, cindex1
@@ -545,6 +548,10 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm
545548
molar_abs => this%single_gas(jgas)%molar_abs
546549
multiplier = simple_multiplier * mole_fraction_fl(jcol,:,igascode)
547550

551+
if (present(concentration_scaling)) then
552+
multiplier = multiplier * concentration_scaling(igascode)
553+
end if
554+
548555
do jlev = 1,nlev
549556
optical_depth_fl(:,jlev,jcol) = optical_depth_fl(:,jlev,jcol) &
550557
& + (multiplier(jlev)*tw1(jlev)) * (pw1(jlev) * molar_abs(:,ip1(jlev),it1(jlev)) &
@@ -555,8 +562,16 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm
555562

556563
case (IConcDependenceRelativeLinear)
557564
molar_abs => this%single_gas(jgas)%molar_abs
558-
multiplier = simple_multiplier * (mole_fraction_fl(jcol,:,igascode) &
559-
& - single_gas%reference_mole_frac)
565+
566+
if (present(concentration_scaling)) then
567+
multiplier = simple_multiplier &
568+
& * (mole_fraction_fl(jcol,:,igascode)*concentration_scaling(igascode) &
569+
& - single_gas%reference_mole_frac)
570+
else
571+
multiplier = simple_multiplier * (mole_fraction_fl(jcol,:,igascode) &
572+
& - single_gas%reference_mole_frac)
573+
end if
574+
560575
do jlev = 1,nlev
561576
optical_depth_fl(:,jlev,jcol) = optical_depth_fl(:,jlev,jcol) &
562577
& + (multiplier(jlev)*tw1(jlev)) * (pw1(jlev) * molar_abs(:,ip1(jlev),it1(jlev)) &
@@ -577,12 +592,19 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm
577592
end do
578593

579594
case (IConcDependenceLUT)
595+
596+
if (present(concentration_scaling)) then
597+
scaling = concentration_scaling(igascode)
598+
else
599+
scaling = 1.0_jprb
600+
end if
601+
580602
! Logarithmic interpolation in concentration space
581603
molar_abs_conc => this%single_gas(jgas)%molar_abs_conc
582604
mole_frac1 = exp(single_gas%log_mole_frac1)
583605
do jlev = 1,nlev
584606
! Take care of mole_fraction == 0
585-
log_conc = log(max(mole_fraction_fl(jcol,jlev,igascode), mole_frac1))
607+
log_conc = log(max(mole_fraction_fl(jcol,jlev,igascode)*scaling, mole_frac1))
586608
cindex1 = (log_conc - single_gas%log_mole_frac1) / single_gas%d_log_mole_frac
587609
cindex1 = 1.0_jprb + max(0.0_jprb, min(cindex1, single_gas%n_mole_frac-1.0001_jprb))
588610
ic1(jlev) = int(cindex1)
@@ -599,7 +621,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm
599621
! & +pw2 * molar_abs_conc(:,ip1+1,it1+1,ic1+1)))
600622
do jlev = 1,nlev
601623
optical_depth_fl(:,jlev,jcol) = optical_depth_fl(:,jlev,jcol) &
602-
& + (simple_multiplier(jlev) * mole_fraction_fl(jcol,jlev,igascode)) * ( &
624+
& + (simple_multiplier(jlev) * mole_fraction_fl(jcol,jlev,igascode) * scaling) * ( &
603625
& (cw1(jlev) * tw1(jlev) * pw1(jlev)) * molar_abs_conc(:,ip1(jlev),it1(jlev),ic1(jlev)) &
604626
& +(cw1(jlev) * tw1(jlev) * pw2(jlev)) * molar_abs_conc(:,ip1(jlev)+1,it1(jlev),ic1(jlev)) &
605627
& +(cw1(jlev) * tw2(jlev) * pw1(jlev)) * molar_abs_conc(:,ip1(jlev),it1(jlev)+1,ic1(jlev)) &

‎radiation/radiation_ecckd_interface.F90

+44-21
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ subroutine setup_gas_optics(config)
3838

3939
if (lhook) call dr_hook('radiation_ecckd_interface:setup_gas_optics',0,hook_handle)
4040

41-
if (config%do_sw) then
41+
if (config%do_sw .and. config%i_gas_model_sw == IGasModelECCKD) then
4242

4343
! Read shortwave ecCKD gas optics NetCDF file
4444
call config%gas_optics_sw%read(trim(config%gas_optics_sw_file_name), &
@@ -83,7 +83,7 @@ subroutine setup_gas_optics(config)
8383

8484
end if
8585

86-
if (config%do_lw) then
86+
if (config%do_lw .and. config%i_gas_model_lw == IGasModelECCKD) then
8787

8888
! Read longwave ecCKD gas optics NetCDF file
8989
call config%gas_optics_lw%read(trim(config%gas_optics_lw_file_name), &
@@ -179,7 +179,7 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, &
179179
use parkind1, only : jprb
180180
use yomhook, only : lhook, dr_hook, jphook
181181

182-
use radiation_config, only : config_type
182+
use radiation_config, only : config_type, IGasModelECCKD
183183
use radiation_thermodynamics, only : thermodynamics_type
184184
use radiation_single_level, only : single_level_type
185185
use radiation_gas_constants, only : NMaxGases
@@ -222,6 +222,10 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, &
222222
! Temperature at full levels (K)
223223
real(jprb) :: temperature_fl(istartcol:iendcol,nlev)
224224

225+
real(jprb) :: concentration_scaling(NMaxGases)
226+
227+
logical :: is_volume_mixing_ratio
228+
225229
integer :: jcol, jlev, jg
226230

227231
real(jphook) :: hook_handle
@@ -239,16 +243,31 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, &
239243
& *thermodynamics%pressure_hl(istartcol:iendcol,2:nlev+1)) &
240244
& / (thermodynamics%pressure_hl(istartcol:iendcol,1:nlev) &
241245
& +thermodynamics%pressure_hl(istartcol:iendcol,2:nlev+1))
242-
243-
if (config%do_sw) then
244-
245-
call config%gas_optics_sw%calc_optical_depth(ncol,nlev,istartcol,iendcol, &
246-
& NMaxGases, thermodynamics%pressure_hl, &
247-
& temperature_fl, &
248-
& gas%mixing_ratio, &
249-
! & reshape(gas%mixing_ratio(istartcol:iendcol,:,:), &
250-
! & [nlev,iendcol-istartcol+1,NMaxGases],order=[2,1,3]), &
251-
& od_sw, rayleigh_od_fl=ssa_sw)
246+
247+
! Check that the gas concentrations are stored in volume mixing
248+
! ratio with no scaling; if not, return a vector of scalings
249+
call gas%assert_units(IVolumeMixingRatio, scale_factor=1.0_jprb, &
250+
& istatus=is_volume_mixing_ratio)
251+
if (.not. is_volume_mixing_ratio) then
252+
call gas%get_scaling(IVolumeMixingRatio, concentration_scaling)
253+
else
254+
concentration_scaling = 1.0_jprb
255+
end if
256+
257+
if (config%do_sw .and. config%i_gas_model_sw == IGasModelECCKD) then
258+
259+
if (is_volume_mixing_ratio) then
260+
call config%gas_optics_sw%calc_optical_depth(ncol,nlev,istartcol,iendcol, &
261+
& NMaxGases, thermodynamics%pressure_hl, &
262+
& temperature_fl, gas%mixing_ratio, &
263+
& od_sw, rayleigh_od_fl=ssa_sw)
264+
else
265+
call config%gas_optics_sw%calc_optical_depth(ncol,nlev,istartcol,iendcol, &
266+
& NMaxGases, thermodynamics%pressure_hl, &
267+
& temperature_fl, gas%mixing_ratio, &
268+
& od_sw, rayleigh_od_fl=ssa_sw, concentration_scaling=concentration_scaling)
269+
end if
270+
252271
! At this point od_sw = absorption optical depth and ssa_sw =
253272
! rayleigh optical depth: convert to total optical depth and
254273
! single-scattering albedo
@@ -273,15 +292,19 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, &
273292

274293
end if
275294

276-
if (config%do_lw) then
295+
if (config%do_lw .and. config%i_gas_model_lw == IGasModelECCKD) then
277296

278-
call config%gas_optics_lw%calc_optical_depth(ncol,nlev,istartcol,iendcol, &
279-
& NMaxGases, thermodynamics%pressure_hl, &
280-
& temperature_fl, &
281-
& gas%mixing_ratio, &
282-
! & reshape(gas%mixing_ratio(istartcol:iendcol,:,:), &
283-
! & [nlev,iendcol-istartcol+1,NMaxGases],order=[2,1,3]), &
284-
& od_lw)
297+
if (is_volume_mixing_ratio) then
298+
call config%gas_optics_lw%calc_optical_depth(ncol,nlev,istartcol,iendcol, &
299+
& NMaxGases, thermodynamics%pressure_hl, &
300+
& temperature_fl, gas%mixing_ratio, &
301+
& od_lw)
302+
else
303+
call config%gas_optics_lw%calc_optical_depth(ncol,nlev,istartcol,iendcol, &
304+
& NMaxGases, thermodynamics%pressure_hl, &
305+
& temperature_fl, gas%mixing_ratio, &
306+
& od_lw, concentration_scaling=concentration_scaling)
307+
end if
285308

286309
! Calculate the Planck function for each g point
287310
do jcol = istartcol,iendcol

‎radiation/radiation_gas.F90

+59-21
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ module radiation_gas
7171
procedure :: set_units => set_units_gas
7272
procedure :: assert_units => assert_units_gas
7373
procedure :: get => get_gas
74+
procedure :: get_scaling
7475
procedure :: reverse => reverse_gas
7576
procedure :: out_of_physical_bounds
7677
end type gas_type
@@ -354,7 +355,7 @@ recursive subroutine set_units_gas(this, iunits, igas, scale_factor)
354355
integer, optional, intent(in) :: igas
355356
real(jprb), optional, intent(in) :: scale_factor
356357

357-
integer :: ig
358+
integer :: jg
358359

359360
! Scaling factor to convert from old to new
360361
real(jprb) :: sf
@@ -395,30 +396,55 @@ recursive subroutine set_units_gas(this, iunits, igas, scale_factor)
395396
this%scale_factor(igas) = new_sf
396397
end if
397398
else
398-
do ig = 1,this%ntype
399-
call this%set_units(iunits, igas=this%icode(ig), scale_factor=new_sf)
399+
do jg = 1,this%ntype
400+
call this%set_units(iunits, igas=this%icode(jg), scale_factor=new_sf)
400401
end do
401402
end if
402403

403404
end subroutine set_units_gas
404405

406+
407+
!---------------------------------------------------------------------
408+
! Return a vector indicating the scaling that one would need to
409+
! apply to each gas in order to obtain the dimension units in
410+
! "iunits" (which can be IVolumeMixingRatio or IMassMixingRatio)
411+
subroutine get_scaling(this, iunits, scaling)
412+
class(gas_type), intent(in) :: this
413+
integer, intent(in) :: iunits
414+
real(jprb), intent(out) :: scaling(NMaxGases)
415+
integer :: jg
416+
417+
scaling = this%scale_factor
418+
do jg = 1,NMaxGases
419+
if (iunits == IMassMixingRatio .and. this%iunits(jg) == IVolumeMixingRatio) then
420+
scaling(jg) = scaling(jg) * GasMolarMass(jg) / AirMolarMass
421+
else if (iunits == IVolumeMixingRatio .and. this%iunits(jg) == IMassMixingRatio) then
422+
scaling(jg) = scaling(jg) * AirMolarMass / GasMolarMass(jg)
423+
end if
424+
end do
425+
426+
end subroutine get_scaling
405427

428+
406429
!---------------------------------------------------------------------
407430
! Assert that gas mixing ratio units are "iunits", applying to gas
408431
! with ID "igas" if present, otherwise to all gases. Otherwise the
409-
! program will exit. Otional argument scale factor specifies any
410-
! subsequent multiplication to apply; for PPMV one would use
411-
! iunits=IVolumeMixingRatio and scale_factor=1.0e6.
412-
recursive subroutine assert_units_gas(this, iunits, igas, scale_factor)
432+
! program will exit, except if the optional argument "istatus" is
433+
! provided in which case it will return true if the units are
434+
! correct and false if they are not. Optional argument scale factor
435+
! specifies any subsequent multiplication to apply; for PPMV one
436+
! would use iunits=IVolumeMixingRatio and scale_factor=1.0e6.
437+
recursive subroutine assert_units_gas(this, iunits, igas, scale_factor, istatus)
413438

414439
use radiation_io, only : nulerr, radiation_abort
415440

416-
class(gas_type), intent(in) :: this
417-
integer, intent(in) :: iunits
418-
integer, optional, intent(in) :: igas
419-
real(jprb), optional, intent(in) :: scale_factor
441+
class(gas_type), intent(in) :: this
442+
integer, intent(in) :: iunits
443+
integer, optional, intent(in) :: igas
444+
real(jprb), optional, intent(in) :: scale_factor
445+
logical, optional, intent(out) :: istatus
420446

421-
integer :: ig
447+
integer :: jg
422448

423449
real(jprb) :: sf
424450

@@ -428,22 +454,34 @@ recursive subroutine assert_units_gas(this, iunits, igas, scale_factor)
428454
sf = 1.0_jprb
429455
end if
430456

457+
if (present(istatus)) then
458+
istatus = .true.
459+
end if
460+
431461
if (present(igas)) then
432462
if (this%is_present(igas)) then
433463
if (iunits /= this%iunits(igas)) then
434-
write(nulerr,'(a,a,a)') '*** Error: ', trim(GasName(igas)), &
435-
& ' is not in the required units'
436-
call radiation_abort()
464+
if (present(istatus)) then
465+
istatus = .false.
466+
else
467+
write(nulerr,'(a,a,a)') '*** Error: ', trim(GasName(igas)), &
468+
& ' is not in the required units'
469+
call radiation_abort()
470+
end if
437471
else if (sf /= this%scale_factor(igas)) then
438-
write(nulerr,'(a,a,a,e12.4,a,e12.4)') '*** Error: ', GasName(igas), &
439-
& ' scaling of ', this%scale_factor(igas), &
440-
& ' does not match required ', sf
441-
call radiation_abort()
472+
if (present(istatus)) then
473+
istatus = .false.
474+
else
475+
write(nulerr,'(a,a,a,e12.4,a,e12.4)') '*** Error: ', GasName(igas), &
476+
& ' scaling of ', this%scale_factor(igas), &
477+
& ' does not match required ', sf
478+
call radiation_abort()
479+
end if
442480
end if
443481
end if
444482
else
445-
do ig = 1,this%ntype
446-
call this%assert_units(iunits, igas=this%icode(ig), scale_factor=sf)
483+
do jg = 1,this%ntype
484+
call this%assert_units(iunits, igas=this%icode(jg), scale_factor=sf, istatus=istatus)
447485
end do
448486
end if
449487

‎radiation/radiation_ifs_rrtm.F90

+170-155
Large diffs are not rendered by default.

‎radiation/radiation_interface.F90

+37-25
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ subroutine setup_radiation(config)
6969
! Load the look-up tables from files in the specified directory
7070
if (config%i_gas_model_sw == IGasModelMonochromatic) then
7171
call setup_gas_optics_mono(config, trim(config%directory_name))
72-
else if (config%i_gas_model_sw == IGasModelIFSRRTMG .or. config%i_gas_model_lw == IGasModelIFSRRTMG) then
73-
call setup_gas_optics_rrtmg(config, trim(config%directory_name))
74-
else if (config%i_gas_model_sw == IGasModelECCKD .or. config%i_gas_model_lw == IGasModelECCKD) then
75-
call setup_gas_optics_ecckd(config)
72+
else
73+
! Note that we can run RRTMG and ECCKD for different parts of
74+
! the spectrum: the setup routines only configure the relevant
75+
! part.
76+
if (config%i_gas_model_sw == IGasModelIFSRRTMG .or. config%i_gas_model_lw == IGasModelIFSRRTMG) then
77+
call setup_gas_optics_rrtmg(config, trim(config%directory_name))
78+
end if
79+
if (config%i_gas_model_sw == IGasModelECCKD .or. config%i_gas_model_lw == IGasModelECCKD) then
80+
call setup_gas_optics_ecckd(config)
81+
end if
7682
end if
7783

7884
if (config%do_lw_aerosol_scattering &
@@ -121,7 +127,7 @@ subroutine setup_radiation(config)
121127
end if
122128

123129
if (config%do_clouds) then
124-
if (config%i_gas_model == IGasModelMonochromatic) then
130+
if (config%i_gas_model_sw == IGasModelMonochromatic) then
125131
! call setup_cloud_optics_mono(config)
126132
elseif (config%use_general_cloud_optics) then
127133
call setup_general_cloud_optics(config)
@@ -131,7 +137,7 @@ subroutine setup_radiation(config)
131137
end if
132138

133139
if (config%use_aerosols) then
134-
if (config%i_gas_model == IGasModelMonochromatic) then
140+
if (config%i_gas_model_sw == IGasModelMonochromatic) then
135141
! call setup_aerosol_optics_mono(config)
136142
else
137143
call setup_aerosol_optics(config)
@@ -166,12 +172,13 @@ subroutine set_gas_units(config, gas)
166172
type(config_type), intent(in) :: config
167173
type(gas_type), intent(inout) :: gas
168174

169-
if (config%i_gas_model == IGasModelMonochromatic) then
175+
if (config%i_gas_model_sw == IGasModelMonochromatic) then
170176
call set_gas_units_mono(gas)
171-
elseif (config%i_gas_model == IGasModelECCKD) then
172-
call set_gas_units_ecckd(gas)
173-
else
177+
elseif (config%i_gas_model_sw == IGasModelIFSRRTMG &
178+
& .or. config%i_gas_model_lw == IGasModelIFSRRTMG) then
174179
call set_gas_units_ifs(gas)
180+
else
181+
call set_gas_units_ecckd(gas)
175182
end if
176183

177184
end subroutine set_gas_units
@@ -195,7 +202,7 @@ subroutine radiation(ncol, nlev, istartcol, iendcol, config, &
195202

196203
use radiation_io, only : nulout
197204
use radiation_config, only : config_type, &
198-
& IGasModelMonochromatic, IGasModelIFSRRTMG, &
205+
& IGasModelMonochromatic, IGasModelIFSRRTMG, IGasModelECCKD, &
199206
& ISolverMcICA, ISolverSpartacus, ISolverHomogeneous, &
200207
& ISolverTripleclouds
201208
use radiation_single_level, only : single_level_type
@@ -320,23 +327,28 @@ subroutine radiation(ncol, nlev, istartcol, iendcol, config, &
320327
! extinction due to Rayleigh scattering), Planck functions and
321328
! incoming shortwave flux at each g-point, for the specified
322329
! range of atmospheric columns
323-
if (config%i_gas_model == IGasModelMonochromatic) then
330+
if (config%i_gas_model_sw == IGasModelMonochromatic) then
324331
call gas_optics_mono(ncol,nlev,istartcol,iendcol, config, &
325332
& single_level, thermodynamics, gas, lw_albedo, &
326333
& od_lw, od_sw, ssa_sw, &
327334
& planck_hl, lw_emission, incoming_sw)
328-
else if (config%i_gas_model == IGasModelIFSRRTMG) then
329-
call gas_optics_rrtmg(ncol,nlev,istartcol,iendcol, config, &
330-
& single_level, thermodynamics, gas, &
331-
& od_lw, od_sw, ssa_sw, lw_albedo=lw_albedo, &
332-
& planck_hl=planck_hl, lw_emission=lw_emission, &
333-
& incoming_sw=incoming_sw)
334335
else
335-
call gas_optics_ecckd(ncol,nlev,istartcol,iendcol, config, &
336-
& single_level, thermodynamics, gas, &
337-
& od_lw, od_sw, ssa_sw, lw_albedo=lw_albedo, &
338-
& planck_hl=planck_hl, lw_emission=lw_emission, &
339-
& incoming_sw=incoming_sw)
336+
if (config%i_gas_model_sw == IGasModelIFSRRTMG &
337+
& .or. config%i_gas_model_lw == IGasModelIFSRRTMG) then
338+
call gas_optics_rrtmg(ncol,nlev,istartcol,iendcol, config, &
339+
& single_level, thermodynamics, gas, &
340+
& od_lw, od_sw, ssa_sw, lw_albedo=lw_albedo, &
341+
& planck_hl=planck_hl, lw_emission=lw_emission, &
342+
& incoming_sw=incoming_sw)
343+
end if
344+
if (config%i_gas_model_sw == IGasModelECCKD &
345+
& .or. config%i_gas_model_lw == IGasModelECCKD) then
346+
call gas_optics_ecckd(ncol,nlev,istartcol,iendcol, config, &
347+
& single_level, thermodynamics, gas, &
348+
& od_lw, od_sw, ssa_sw, lw_albedo=lw_albedo, &
349+
& planck_hl=planck_hl, lw_emission=lw_emission, &
350+
& incoming_sw=incoming_sw)
351+
end if
340352
end if
341353

342354
if (config%do_clouds) then
@@ -349,7 +361,7 @@ subroutine radiation(ncol, nlev, istartcol, iendcol, config, &
349361

350362
! Compute hydrometeor absorption/scattering properties in each
351363
! shortwave and longwave band
352-
if (config%i_gas_model == IGasModelMonochromatic) then
364+
if (config%i_gas_model_sw == IGasModelMonochromatic) then
353365
call cloud_optics_mono(nlev, istartcol, iendcol, &
354366
& config, thermodynamics, cloud, &
355367
& od_lw_cloud, ssa_lw_cloud, g_lw_cloud, &
@@ -368,7 +380,7 @@ subroutine radiation(ncol, nlev, istartcol, iendcol, config, &
368380
end if ! do_clouds
369381

370382
if (config%use_aerosols) then
371-
if (config%i_gas_model == IGasModelMonochromatic) then
383+
if (config%i_gas_model_sw == IGasModelMonochromatic) then
372384
! call add_aerosol_optics_mono(nlev,istartcol,iendcol, &
373385
! & config, thermodynamics, gas, aerosol, &
374386
! & od_lw, ssa_lw, g_lw, od_sw, ssa_sw, g_sw)

‎radiation/radiation_save.F90

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ subroutine save_fluxes(file_name, config, thermodynamics, flux, &
8585
return
8686
end if
8787

88-
if (config%i_gas_model == IGasModelMonochromatic &
88+
if (config%i_gas_model_lw == IGasModelMonochromatic &
8989
.and. config%mono_lw_wavelength > 0.0_jprb) then
9090
lw_units_str = 'W m-3'
9191
else
@@ -514,7 +514,7 @@ subroutine save_net_fluxes(file_name, config, thermodynamics, flux, &
514514
return
515515
end if
516516

517-
if (config%i_gas_model == IGasModelMonochromatic &
517+
if (config%i_gas_model_lw == IGasModelMonochromatic &
518518
.and. config%mono_lw_wavelength > 0.0_jprb) then
519519
lw_units_str = 'W m-3'
520520
else

‎test/ifs/Makefile

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CHANGENAM = ../common/change_namelist.sh
1414
#CONFIG = configCY47R3.nam
1515
CONFIG = configCY49R1.nam
1616
CONFIG_ECCKD = configCY49R1_ecckd.nam
17+
CONFIG_MIXED = configCY49R1_mixed.nam
1718

1819
# Typing "make" will run radiation scheme on IFS profiles
1920
all: test
@@ -111,6 +112,15 @@ test_ecckd_mcica:
111112
test_ecckd_tc:
112113
$(DRIVER) $(CONFIG_ECCKD) $(INPUT).nc $(INPUT)_ecckd_tc_out.nc
113114

115+
test_mixed_gas:
116+
$(DRIVER) $(CONFIG_MIXED) $(INPUT).nc $(INPUT)_sw_ecckd_lw_ecckd_out.nc
117+
$(CHANGENAM) $(CONFIG_MIXED) config_mix.nam lw_gas_model_name='"RRTMG-IFS"' do_cloud_aerosol_per_lw_g_point=false
118+
$(DRIVER) config_mix.nam $(INPUT).nc $(INPUT)_sw_ecckd_lw_rrtmg_out.nc
119+
$(CHANGENAM) $(CONFIG_MIXED) config_mix.nam sw_gas_model_name='"RRTMG-IFS"' do_cloud_aerosol_per_sw_g_point=false
120+
$(DRIVER) config_mix.nam $(INPUT).nc $(INPUT)_sw_rrtmg_lw_ecckd_out.nc
121+
$(CHANGENAM) $(CONFIG_MIXED) config_mix.nam sw_gas_model_name='"RRTMG-IFS"' lw_gas_model_name='"RRTMG-IFS"' do_cloud_aerosol_per_lw_g_point=false do_cloud_aerosol_per_sw_g_point=false
122+
$(DRIVER) config_mix.nam $(INPUT).nc $(INPUT)_sw_rrtmg_lw_rrtmg_out.nc
123+
114124
# ecCKD with no aerosols
115125
test_ecckd_noaer:
116126
$(CHANGENAM) $(CONFIG_ECCKD) config_ecckd_noaer.nam \

‎test/ifs/configCY49R1_mixed.nam

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
! Configuration namelists for ECRAD radiation code
2+
!
3+
! The following namelist controls the behaviour of the driver routine,
4+
! including parallelization options and overriding numbers read from
5+
! the NetCDF input file
6+
!
7+
! This version is a test configuration of ECMWF IFS Cycle 49R1 but
8+
! with the ecCKD gas optics scheme turned on.
9+
!
10+
&radiation_driver
11+
do_parallel = true, ! Use OpenMP parallelization?
12+
nblocksize = 80, ! Number of columns to process per thread
13+
do_save_inputs = false, ! Save inputs in "inputs.nc"?
14+
! Verbosity level: 0=none, 1=warning, 2=info, 3=progress, 4=detailed, 5=debug
15+
iverbose = 2,
16+
istartcol = 0, ! Use full range of columns by default
17+
iendcol = 0,
18+
nrepeat = 1,
19+
cloud_separation_scale_toa = 14000.0,
20+
cloud_separation_scale_surface = 2500.0,
21+
cloud_separation_scale_power = 3.5,
22+
cloud_inhom_separation_factor = 0.75,
23+
!do_save_aerosol_optics = false,
24+
!sw_diag_wavelength_bound = .4e-6,.5e-6,.6e-6,.7e-6, ! Example for red-green-blue diagnostics
25+
!sw_diag_file_name = 'sw_diag.nc',
26+
do_save_net_fluxes = false,
27+
do_write_double_precision = false,
28+
/
29+
!
30+
! The following namelist controls the behaviour of the SPARTACUS
31+
! radiation code
32+
!
33+
&radiation
34+
do_sw = true, ! Compute shortwave fluxes?
35+
do_lw = true, ! Compute longwave fluxes?
36+
do_sw_direct = true, ! Compute direct downward shortwave fluxes?
37+
do_clear = true, ! Compute clear-sky fluxes?
38+
directory_name = "../../data", ! Location of configuration files
39+
use_general_cloud_optics = true,
40+
use_general_aerosol_optics = true,
41+
liquid_model_name = "SOCRATES", ! Liquid droplet scattering model
42+
ice_model_name = "Fu-IFS", ! Ice particle scattering model
43+
sw_solver_name = "Tripleclouds",
44+
lw_solver_name = "Tripleclouds",
45+
overlap_scheme_name = "Exp-Ran", ! Exp-Ran, Max-Ran or Exp-Exp
46+
cloud_fraction_threshold = 0.001e-3, !
47+
do_lw_aerosol_scattering= false, ! Aerosols scatter in the longwave?
48+
do_lw_cloud_scattering = true, ! Clouds scatter in the longwave?
49+
cloud_inhom_decorr_scaling = 0.5, ! Ratio of overlap decorr len of inhomogeneities to boundaries
50+
use_beta_overlap = false,
51+
use_vectorizable_generator = false,
52+
do_save_radiative_properties = false, ! Save raw radiation properties in radiative_properties.nc?
53+
do_3d_effects = false, ! Represent 3D effects?
54+
sw_entrapment_name = "Explicit", ! Zero, Edge-only, Explicit, Non-fractal, Maximum are possible
55+
! Verbosity level: 0=none, 1=warning, 2=info, 3=progress, 4=detailed, 5=debug
56+
! Separate verbosity specified for setup and ordinary execution
57+
iverbose = 1,
58+
iverbosesetup = 2,
59+
use_aerosols = true, ! Include aerosols in radiation calculations?
60+
do_save_spectral_flux = false, ! Save spectral fluxes in output file?
61+
do_save_gpoint_flux = false, ! Save fluxes per g-point in output file?
62+
do_lw_derivatives = true, ! Hogan-Bozzo style derivatives for approx updates
63+
sw_gas_model_name = "ECCKD", ! Gas model
64+
lw_gas_model_name = "ECCKD", ! Gas model
65+
do_surface_sw_spectral_flux = false,
66+
do_fu_lw_ice_optics_bug = false,
67+
do_sw_delta_scaling_with_gases = false,
68+
do_canopy_fluxes_lw = true,
69+
do_canopy_fluxes_sw = true,
70+
do_cloud_aerosol_per_sw_g_point=true,
71+
do_cloud_aerosol_per_lw_g_point=true,
72+
!gas_optics_sw_override_file_name = "ecckd-1.4_sw_climate_vfine-96b_ckd-definition.nc",
73+
!
74+
! SURFACE ALBEDO AND EMISSIVITY
75+
do_nearest_spectral_sw_albedo = false,
76+
sw_albedo_wavelength_bound(1:5) = 0.25e-6, 0.44e-6, 0.69e-6, 1.19e-6, 2.38e-6,
77+
i_sw_albedo_index(1:6) = 1,2,3,4,5,6,
78+
do_nearest_spectral_lw_emiss = false,
79+
lw_emiss_wavelength_bound(1:2) = 8.0e-6, 13.0e-6,
80+
i_lw_emiss_index(1:3) = 1,2,1,
81+
!
82+
! AEROSOL PROPERTIES
83+
!aerosol_optics_override_file_name = 'aerosol_ifs_48R1.nc'
84+
! 12 IFS aerosol classes stored in aerosol_ifs_rrtm.nc: 1-3 Sea salt,
85+
! 4-6 Boucher desert dust, 7 hydrophilic organics, 8 hydrophobic
86+
! organics, 9&10 hydrophobic black carbon, 11 ammonium sulphate, 12
87+
! inactive SO2
88+
n_aerosol_types = 12, ! Aerosols are deactivated if this is zero
89+
!
90+
! Indices to the aerosol optical properties in aerosol_ifs_rrtm.nc,
91+
! for each class, where negative numbers index hydrophilic aerosol
92+
! types and positive numbers index hydrophobic aerosol types
93+
i_aerosol_type_map = -1, -2, -3, 7, 8, 9, -4, 10, 11, 11, -5, 14,
94+
/

0 commit comments

Comments
 (0)
Please sign in to comment.