From 679e8a11d1498ce6112701e5c7b6313e14f72c0a Mon Sep 17 00:00:00 2001 From: Daniel Rieger Date: Thu, 10 Oct 2024 09:57:32 +0000 Subject: [PATCH 1/3] Refactor optional concentration_scaling in ecckd --- radiation/radiation_ecckd.F90 | 45 +++++++++++++------------ radiation/radiation_ecckd_interface.F90 | 4 +-- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/radiation/radiation_ecckd.F90 b/radiation/radiation_ecckd.F90 index 2089b8de..b8f650d0 100644 --- a/radiation/radiation_ecckd.F90 +++ b/radiation/radiation_ecckd.F90 @@ -456,7 +456,7 @@ end subroutine read_spectral_solar_cycle ! at nlev layers subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nmaxgas, & & pressure_hl, temperature_fl, mole_fraction_fl, & - & optical_depth_fl, rayleigh_od_fl, concentration_scaling) + & optical_depth_fl, rayleigh_od_fl, opt_concentration_scaling) use yomhook, only : lhook, dr_hook, jphook use radiation_constants, only : AccelDueToGravity @@ -473,7 +473,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm ! Gas mole fractions at full levels (mol mol-1), dimensioned (ncol,nlev,nmaxgas) real(jprb), intent(in) :: mole_fraction_fl(ncol,nlev,nmaxgas) ! Optional concentration scaling of each gas - real(jprb), optional, intent(in) :: concentration_scaling(nmaxgas) + real(jprb), optional, intent(in) :: opt_concentration_scaling(nmaxgas) ! Output variables @@ -495,6 +495,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm real(jprb) :: multiplier(nlev), simple_multiplier(nlev), global_multiplier, temperature1 real(jprb) :: scaling + real(jprb) :: concentration_scaling(nmaxgas) ! Indices and weights in temperature, pressure and concentration interpolation real(jprb) :: pindex1, tindex1, cindex1 @@ -514,6 +515,8 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm if (lhook) call dr_hook('radiation_ecckd:calc_optical_depth',0,hook_handle) global_multiplier = 1.0_jprb / (AccelDueToGravity * 0.001_jprb * AirMolarMass) + concentration_scaling = 1.0_jprb + if (present(opt_concentration_scaling)) concentration_scaling = opt_concentration_scaling do jcol = istartcol,iendcol @@ -556,9 +559,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm molar_abs => this%single_gas(jgas)%molar_abs multiplier = simple_multiplier * mole_fraction_fl(jcol,:,igascode) - if (present(concentration_scaling)) then - multiplier = multiplier * concentration_scaling(igascode) - end if + multiplier = multiplier * concentration_scaling(igascode) do jlev = 1,nlev optical_depth_fl(:,jlev,jcol) = optical_depth_fl(:,jlev,jcol) & @@ -571,14 +572,9 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm case (IConcDependenceRelativeLinear) molar_abs => this%single_gas(jgas)%molar_abs - if (present(concentration_scaling)) then - multiplier = simple_multiplier & + multiplier = simple_multiplier & & * (mole_fraction_fl(jcol,:,igascode)*concentration_scaling(igascode) & & - single_gas%reference_mole_frac) - else - multiplier = simple_multiplier * (mole_fraction_fl(jcol,:,igascode) & - & - single_gas%reference_mole_frac) - end if do jlev = 1,nlev optical_depth_fl(:,jlev,jcol) = optical_depth_fl(:,jlev,jcol) & @@ -601,11 +597,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm case (IConcDependenceLUT) - if (present(concentration_scaling)) then - scaling = concentration_scaling(igascode) - else - scaling = 1.0_jprb - end if + scaling = concentration_scaling(igascode) ! Logarithmic interpolation in concentration space molar_abs_conc => this%single_gas(jgas)%molar_abs_conc @@ -667,7 +659,7 @@ end subroutine calc_optical_depth_ckd_model ! Vectorized variant of above routine subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol, nmaxgas, & & pressure_hl, temperature_fl, mole_fraction_fl, & - & optical_depth_fl, rayleigh_od_fl) + & optical_depth_fl, rayleigh_od_fl, opt_concentration_scaling) use yomhook, only : lhook, dr_hook, jphook use radiation_constants, only : AccelDueToGravity @@ -683,6 +675,8 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol real(jprb), intent(in) :: temperature_fl(istartcol:iendcol,nlev) ! Gas mole fractions at full levels (mol mol-1), dimensioned (ncol,nlev,nmaxgas) real(jprb), intent(in) :: mole_fraction_fl(ncol,nlev,nmaxgas) + ! Optional concentration scaling of each gas + real(jprb), optional, intent(in) :: opt_concentration_scaling(nmaxgas) ! Output variables @@ -703,6 +697,8 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol !real(jprb) :: od_single_gas(this%ng) real(jprb) :: multiplier, simple_multiplier(ncol,nlev), global_multiplier, temperature1 + real(jprb) :: scaling + real(jprb) :: concentration_scaling(nmaxgas) ! Indices and weights in temperature, pressure and concentration interpolation real(jprb) :: pindex1, tindex1, cindex1 @@ -725,6 +721,8 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol if (lhook) call dr_hook('radiation_ecckd:calc_optical_depth_vec',0,hook_handle) global_multiplier = 1.0_jprb / (AccelDueToGravity * 0.001_jprb * AirMolarMass) + concentration_scaling = 1._jprb + if (present(opt_concentration_scaling)) concentration_scaling = opt_concentration_scaling od_fl(:,:,:) = 0.0_jprb @@ -770,7 +768,8 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol do jlev = 1,nlev do jg = 1, this%ng do jcol = istartcol,iendcol - multiplier = simple_multiplier(jcol,jlev) * mole_fraction_fl(jcol,jlev,igascode) + multiplier = simple_multiplier(jcol,jlev) * mole_fraction_fl(jcol,jlev,igascode) & + & * concentration_scaling(igascode) od_fl(jcol,jg,jlev) = od_fl(jcol,jg,jlev) & & + (multiplier*tw1(jcol,jlev)) * (pw1(jcol,jlev) * molar_abs(jg,ip1(jcol,jlev),it1(jcol,jlev)) & @@ -787,8 +786,9 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol do jlev = 1,nlev do jg = 1, this%ng do jcol = istartcol,iendcol - multiplier = simple_multiplier(jcol,jlev) * (mole_fraction_fl(jcol,jlev,igascode) & - & - single_gas%reference_mole_frac) + multiplier = simple_multiplier(jcol,jlev) * (mole_fraction_fl(jcol,jlev,igascode) & + & * concentration_scaling(igascode) & + & - single_gas%reference_mole_frac) od_fl(jcol,jg,jlev) = od_fl(jcol,jg,jlev) & & + (multiplier*tw1(jcol,jlev)) * (pw1(jcol,jlev) * molar_abs(jg,ip1(jcol,jlev),it1(jcol,jlev)) & @@ -818,6 +818,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol end do case (IConcDependenceLUT) + scaling = concentration_scaling(igascode) ! Logarithmic interpolation in concentration space molar_abs_conc => this%single_gas(jgas)%molar_abs_conc mole_frac1 = exp(single_gas%log_mole_frac1) @@ -825,7 +826,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol do jlev = 1,nlev do jcol = istartcol,iendcol ! Take care of mole_fraction == 0 - log_conc = log(max(mole_fraction_fl(jcol,jlev,igascode), mole_frac1)) + log_conc = log(max(mole_fraction_fl(jcol,jlev,igascode)*scaling, mole_frac1)) cindex1 = (log_conc - single_gas%log_mole_frac1) / single_gas%d_log_mole_frac cindex1 = 1.0_jprb + max(0.0_jprb, min(cindex1, single_gas%n_mole_frac-1.0001_jprb)) ic1(jcol,jlev) = int(cindex1) @@ -840,7 +841,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol do jcol = istartcol,iendcol od_fl(jcol,jg,jlev) = od_fl(jcol,jg,jlev) & - & + (simple_multiplier(jcol,jlev) * mole_fraction_fl(jcol,jlev,igascode)) * ( & + & + (simple_multiplier(jcol,jlev) * mole_fraction_fl(jcol,jlev,igascode) *scaling) * ( & & (cw1(jcol,jlev) * tw1(jcol,jlev) * pw1(jcol,jlev)) * & & molar_abs_conc(jg,ip1(jcol,jlev),it1(jcol,jlev),ic1(jcol,jlev)) & & +(cw1(jcol,jlev) * tw1(jcol,jlev) * pw2(jcol,jlev)) * & diff --git a/radiation/radiation_ecckd_interface.F90 b/radiation/radiation_ecckd_interface.F90 index 2e014e34..61f73b57 100644 --- a/radiation/radiation_ecckd_interface.F90 +++ b/radiation/radiation_ecckd_interface.F90 @@ -265,7 +265,7 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, & call config%gas_optics_sw%calc_optical_depth(ncol,nlev,istartcol,iendcol, & & NMaxGases, thermodynamics%pressure_hl, & & temperature_fl, gas%mixing_ratio, & - & od_sw, rayleigh_od_fl=ssa_sw, concentration_scaling=concentration_scaling) + & od_sw, rayleigh_od_fl=ssa_sw, opt_concentration_scaling=concentration_scaling) end if ! At this point od_sw = absorption optical depth and ssa_sw = @@ -303,7 +303,7 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, & call config%gas_optics_lw%calc_optical_depth(ncol,nlev,istartcol,iendcol, & & NMaxGases, thermodynamics%pressure_hl, & & temperature_fl, gas%mixing_ratio, & - & od_lw, concentration_scaling=concentration_scaling) + & od_lw, opt_concentration_scaling=concentration_scaling) end if ! Calculate the Planck function for each g point From 980e0334a6eac2102a6fc438180e464177a50bdd Mon Sep 17 00:00:00 2001 From: Daniel Rieger Date: Mon, 2 Dec 2024 15:07:32 +0000 Subject: [PATCH 2/3] Revert interface change, introduce local_concentration_scaling instead --- radiation/radiation_ecckd.F90 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/radiation/radiation_ecckd.F90 b/radiation/radiation_ecckd.F90 index b8f650d0..1c5fc5ee 100644 --- a/radiation/radiation_ecckd.F90 +++ b/radiation/radiation_ecckd.F90 @@ -456,7 +456,7 @@ end subroutine read_spectral_solar_cycle ! at nlev layers subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nmaxgas, & & pressure_hl, temperature_fl, mole_fraction_fl, & - & optical_depth_fl, rayleigh_od_fl, opt_concentration_scaling) + & optical_depth_fl, rayleigh_od_fl, concentration_scaling) use yomhook, only : lhook, dr_hook, jphook use radiation_constants, only : AccelDueToGravity @@ -473,7 +473,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm ! Gas mole fractions at full levels (mol mol-1), dimensioned (ncol,nlev,nmaxgas) real(jprb), intent(in) :: mole_fraction_fl(ncol,nlev,nmaxgas) ! Optional concentration scaling of each gas - real(jprb), optional, intent(in) :: opt_concentration_scaling(nmaxgas) + real(jprb), optional, intent(in) :: concentration_scaling(nmaxgas) ! Output variables @@ -495,7 +495,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm real(jprb) :: multiplier(nlev), simple_multiplier(nlev), global_multiplier, temperature1 real(jprb) :: scaling - real(jprb) :: concentration_scaling(nmaxgas) + real(jprb) :: local_concentration_scaling(nmaxgas) ! Indices and weights in temperature, pressure and concentration interpolation real(jprb) :: pindex1, tindex1, cindex1 @@ -515,8 +515,8 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm if (lhook) call dr_hook('radiation_ecckd:calc_optical_depth',0,hook_handle) global_multiplier = 1.0_jprb / (AccelDueToGravity * 0.001_jprb * AirMolarMass) - concentration_scaling = 1.0_jprb - if (present(opt_concentration_scaling)) concentration_scaling = opt_concentration_scaling + local_concentration_scaling = 1.0_jprb + if (present(concentration_scaling)) local_concentration_scaling = concentration_scaling do jcol = istartcol,iendcol @@ -559,7 +559,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm molar_abs => this%single_gas(jgas)%molar_abs multiplier = simple_multiplier * mole_fraction_fl(jcol,:,igascode) - multiplier = multiplier * concentration_scaling(igascode) + multiplier = multiplier * local_concentration_scaling(igascode) do jlev = 1,nlev optical_depth_fl(:,jlev,jcol) = optical_depth_fl(:,jlev,jcol) & @@ -573,7 +573,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm molar_abs => this%single_gas(jgas)%molar_abs multiplier = simple_multiplier & - & * (mole_fraction_fl(jcol,:,igascode)*concentration_scaling(igascode) & + & * (mole_fraction_fl(jcol,:,igascode)*local_concentration_scaling(igascode) & & - single_gas%reference_mole_frac) do jlev = 1,nlev @@ -597,7 +597,7 @@ subroutine calc_optical_depth_ckd_model(this, ncol, nlev, istartcol, iendcol, nm case (IConcDependenceLUT) - scaling = concentration_scaling(igascode) + scaling = local_concentration_scaling(igascode) ! Logarithmic interpolation in concentration space molar_abs_conc => this%single_gas(jgas)%molar_abs_conc @@ -659,7 +659,7 @@ end subroutine calc_optical_depth_ckd_model ! Vectorized variant of above routine subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol, nmaxgas, & & pressure_hl, temperature_fl, mole_fraction_fl, & - & optical_depth_fl, rayleigh_od_fl, opt_concentration_scaling) + & optical_depth_fl, rayleigh_od_fl, concentration_scaling) use yomhook, only : lhook, dr_hook, jphook use radiation_constants, only : AccelDueToGravity @@ -676,7 +676,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol ! Gas mole fractions at full levels (mol mol-1), dimensioned (ncol,nlev,nmaxgas) real(jprb), intent(in) :: mole_fraction_fl(ncol,nlev,nmaxgas) ! Optional concentration scaling of each gas - real(jprb), optional, intent(in) :: opt_concentration_scaling(nmaxgas) + real(jprb), optional, intent(in) :: concentration_scaling(nmaxgas) ! Output variables @@ -698,7 +698,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol real(jprb) :: multiplier, simple_multiplier(ncol,nlev), global_multiplier, temperature1 real(jprb) :: scaling - real(jprb) :: concentration_scaling(nmaxgas) + real(jprb) :: local_concentration_scaling(nmaxgas) ! Indices and weights in temperature, pressure and concentration interpolation real(jprb) :: pindex1, tindex1, cindex1 @@ -721,8 +721,8 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol if (lhook) call dr_hook('radiation_ecckd:calc_optical_depth_vec',0,hook_handle) global_multiplier = 1.0_jprb / (AccelDueToGravity * 0.001_jprb * AirMolarMass) - concentration_scaling = 1._jprb - if (present(opt_concentration_scaling)) concentration_scaling = opt_concentration_scaling + local_concentration_scaling = 1._jprb + if (present(concentration_scaling)) local_concentration_scaling = concentration_scaling od_fl(:,:,:) = 0.0_jprb @@ -769,7 +769,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol do jg = 1, this%ng do jcol = istartcol,iendcol multiplier = simple_multiplier(jcol,jlev) * mole_fraction_fl(jcol,jlev,igascode) & - & * concentration_scaling(igascode) + & * local_concentration_scaling(igascode) od_fl(jcol,jg,jlev) = od_fl(jcol,jg,jlev) & & + (multiplier*tw1(jcol,jlev)) * (pw1(jcol,jlev) * molar_abs(jg,ip1(jcol,jlev),it1(jcol,jlev)) & @@ -787,7 +787,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol do jg = 1, this%ng do jcol = istartcol,iendcol multiplier = simple_multiplier(jcol,jlev) * (mole_fraction_fl(jcol,jlev,igascode) & - & * concentration_scaling(igascode) & + & * local_concentration_scaling(igascode) & & - single_gas%reference_mole_frac) od_fl(jcol,jg,jlev) = od_fl(jcol,jg,jlev) & @@ -818,7 +818,7 @@ subroutine calc_optical_depth_ckd_model_vec(this, ncol, nlev, istartcol, iendcol end do case (IConcDependenceLUT) - scaling = concentration_scaling(igascode) + scaling = local_concentration_scaling(igascode) ! Logarithmic interpolation in concentration space molar_abs_conc => this%single_gas(jgas)%molar_abs_conc mole_frac1 = exp(single_gas%log_mole_frac1) From f929ac40d557fb180fba02e61bc2903eb60f5a91 Mon Sep 17 00:00:00 2001 From: Daniel Rieger Date: Mon, 2 Dec 2024 15:15:08 +0000 Subject: [PATCH 3/3] Revert interface change also in calling sr --- radiation/radiation_ecckd_interface.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radiation/radiation_ecckd_interface.F90 b/radiation/radiation_ecckd_interface.F90 index 61f73b57..2e014e34 100644 --- a/radiation/radiation_ecckd_interface.F90 +++ b/radiation/radiation_ecckd_interface.F90 @@ -265,7 +265,7 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, & call config%gas_optics_sw%calc_optical_depth(ncol,nlev,istartcol,iendcol, & & NMaxGases, thermodynamics%pressure_hl, & & temperature_fl, gas%mixing_ratio, & - & od_sw, rayleigh_od_fl=ssa_sw, opt_concentration_scaling=concentration_scaling) + & od_sw, rayleigh_od_fl=ssa_sw, concentration_scaling=concentration_scaling) end if ! At this point od_sw = absorption optical depth and ssa_sw = @@ -303,7 +303,7 @@ subroutine gas_optics(ncol,nlev,istartcol,iendcol, & call config%gas_optics_lw%calc_optical_depth(ncol,nlev,istartcol,iendcol, & & NMaxGases, thermodynamics%pressure_hl, & & temperature_fl, gas%mixing_ratio, & - & od_lw, opt_concentration_scaling=concentration_scaling) + & od_lw, concentration_scaling=concentration_scaling) end if ! Calculate the Planck function for each g point