Ignore:
Timestamp:
Mar 19, 2024, 3:34:21 PM (2 months ago)
Author:
idelkadi
Message:

Ecrad update in LMDZ / Implementation of Ecrad double call in LMDZ

  • version 1.6.1 (commit 210d7911380f53a788c3cad73b3cf9b4e022ef87)
  • interface routines between lmdz and ecrad grouped in a new "lmdz" directory
  • double call method redesigned so as to go through the Ecrad initialization and configuration part only once for the entire simulation
  • clean-up in the read.F routine: delete unitules arguments
  • modification of default gas model in namelist (default: ECCKD)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/phylmd/ecrad/radiation/radiation_two_stream.F90

    r4773 r4853  
    2222!   2023-09-28  R Hogan  Increased security for single-precision SW "k"
    2323
     24#include "ecrad_config.h"
     25
    2426module radiation_two_stream
    2527
     
    4345
    4446contains
    45 
    46 #ifdef FAST_EXPONENTIAL
    47   !---------------------------------------------------------------------
    48   ! Fast exponential for negative arguments: a Pade approximant that
    49   ! doesn't go negative for negative arguments, applied to arg/8, and
    50   ! the result is then squared three times
    51   elemental function exp_fast(arg) result(ex)
    52     real(jprd) :: arg, ex
    53     ex = 1.0_jprd / (1.0_jprd + arg*(-0.125_jprd &
    54          + arg*(0.0078125_jprd - 0.000325520833333333_jprd * arg)))
    55     ex = ex*ex
    56     ex = ex*ex
    57     ex = ex*ex
    58   end function exp_fast
    59 #else
    60 #define exp_fast exp
    61 #endif
    6247
    6348  !---------------------------------------------------------------------
     
    214199        k_exponent = sqrt(max((gamma1(jg) - gamma2(jg)) * (gamma1(jg) + gamma2(jg)), &
    215200             1.0e-12_jprd)) ! Eq 18 of Meador & Weaver (1980)
    216         exponential = exp_fast(-k_exponent*od(jg))
     201        exponential = exp(-k_exponent*od(jg))
    217202        exponential2 = exponential*exponential
    218203        reftrans_factor = 1.0 / (k_exponent + gamma1(jg) + (k_exponent - gamma1(jg))*exponential2)
     
    306291#endif
    307292
    308 ! Added for DWD (2020)
    309 !NEC$ shortloop
    310293    do jg = 1, ng
    311294      factor = (LwDiffusivityWP * 0.5_jprb) * ssa(jg)
     
    315298           1.0e-12_jprb)) ! Eq 18 of Meador & Weaver (1980)
    316299      if (od(jg) > 1.0e-3_jprb) then
    317         exponential = exp_fast(-k_exponent*od(jg))
     300        exponential = exp(-k_exponent*od(jg))
    318301        exponential2 = exponential*exponential
    319302        reftrans_factor = 1.0_jprb / (k_exponent + gamma1 + (k_exponent - gamma1)*exponential2)
     
    392375#endif
    393376
    394     transmittance = exp_fast(-LwDiffusivityWP*od)
    395 
    396 ! Added for DWD (2020)
    397 !NEC$ shortloop
     377#ifndef DWD_TWO_STREAM_OPTIMIZATIONS
     378    transmittance = exp(-LwDiffusivityWP*od)
     379#endif
     380
    398381    do jg = 1, ng
    399382      ! Compute upward and downward emission assuming the Planck
     
    401384      ! (e.g. Wiscombe , JQSRT 1976).
    402385      coeff = LwDiffusivityWP*od(jg)
     386#ifdef DWD_TWO_STREAM_OPTIMIZATIONS
     387      transmittance(jg) = exp(-coeff)
     388#endif
    403389      if (od(jg) > 1.0e-3_jprb) then
    404390        ! Simplified from calc_reflectance_transmittance_lw above
     
    516502        k_gamma4 = k_exponent*gamma4
    517503        ! Check for mu0 <= 0!
    518         exponential0 = exp_fast(-od_over_mu0)
     504        exponential0 = exp(-od_over_mu0)
    519505        trans_dir_dir(jg) = exponential0
    520         exponential = exp_fast(-k_exponent*od(jg))
     506        exponential = exp(-k_exponent*od(jg))
    521507       
    522508        exponential2 = exponential*exponential
     
    609595    ! The three transfer coefficients from the two-stream
    610596    ! differentiatial equations
     597#ifndef DWD_TWO_STREAM_OPTIMIZATIONS
    611598    real(jprb), dimension(ng) :: gamma1, gamma2, gamma3, gamma4
    612599    real(jprb), dimension(ng) :: alpha1, alpha2, k_exponent
    613600    real(jprb), dimension(ng) :: exponential ! = exp(-k_exponent*od)
     601#else
     602    real(jprb) :: gamma1, gamma2, gamma3, gamma4
     603    real(jprb) :: alpha1, alpha2, k_exponent
     604    real(jprb) :: exponential ! = exp(-k_exponent*od)
     605#endif
    614606   
    615607    real(jprb) :: reftrans_factor, factor
     
    625617#endif
    626618
     619#ifndef DWD_TWO_STREAM_OPTIMIZATIONS
    627620    ! GCC 9.3 strange error: intermediate values of ~ -8000 cause a
    628621    ! FPE when vectorizing exp(), but not in non-vectorized loop, nor
    629622    ! with larger negative values!
    630623    trans_dir_dir = max(-max(od * (1.0_jprb/mu0), 0.0_jprb),-1000.0_jprb)
    631     trans_dir_dir = exp_fast(trans_dir_dir)
    632 
    633 ! Added for DWD (2020)
    634 !NEC$ shortloop
     624    trans_dir_dir = exp(trans_dir_dir)
     625
    635626    do jg = 1, ng
    636627
     
    659650    end do
    660651
    661     exponential = exp_fast(-k_exponent*od)
    662 
    663 !NEC$ shortloop
     652    exponential = exp(-k_exponent*od)
     653
    664654    do jg = 1, ng
    665655      k_mu0 = k_exponent(jg)*mu0
     
    705695      trans_dir_diff(jg) = max(0.0_jprb, min(trans_dir_diff(jg), mu0*(1.0_jprb-trans_dir_dir(jg))-ref_dir(jg)))
    706696    end do
    707    
     697
     698#else
     699    ! GPU-capable and vector-optimized version for ICON
     700    do jg = 1, ng
     701
     702      trans_dir_dir(jg) = max(-max(od(jg) * (1.0_jprb/mu0),0.0_jprb),-1000.0_jprb)
     703      trans_dir_dir(jg) = exp(trans_dir_dir(jg))
     704
     705      ! Zdunkowski "PIFM" (Zdunkowski et al., 1980; Contributions to
     706      ! Atmospheric Physics 53, 147-66)
     707      factor = 0.75_jprb*asymmetry(jg)
     708
     709      gamma1 = 2.0_jprb  - ssa(jg) * (1.25_jprb + factor)
     710      gamma2 = ssa(jg) * (0.75_jprb - factor)
     711      gamma3 = 0.5_jprb  - mu0*factor
     712      gamma4 = 1.0_jprb - gamma3
     713
     714      alpha1 = gamma1*gamma4 + gamma2*gamma3 ! Eq. 16
     715      alpha2 = gamma1*gamma3 + gamma2*gamma4 ! Eq. 17
     716#ifdef PARKIND1_SINGLE
     717      k_exponent = sqrt(max((gamma1 - gamma2) * (gamma1 + gamma2), 1.0e-6_jprb))  ! Eq 18
     718#else
     719      k_exponent = sqrt(max((gamma1 - gamma2) * (gamma1 + gamma2), 1.0e-12_jprb)) ! Eq 18
     720#endif
     721
     722      exponential = exp(-k_exponent*od(jg))
     723
     724      k_mu0 = k_exponent*mu0
     725      one_minus_kmu0_sqr = 1.0_jprb - k_mu0*k_mu0
     726      k_gamma3 = k_exponent*gamma3
     727      k_gamma4 = k_exponent*gamma4
     728      exponential2 = exponential*exponential
     729      k_2_exponential = 2.0_jprb * k_exponent * exponential
     730      reftrans_factor = 1.0_jprb / (k_exponent + gamma1 + (k_exponent - gamma1)*exponential2)
     731       
     732      ! Meador & Weaver (1980) Eq. 25
     733      ref_diff(jg) = gamma2 * (1.0_jprb - exponential2) * reftrans_factor
     734       
     735      ! Meador & Weaver (1980) Eq. 26
     736      trans_diff(jg) = k_2_exponential * reftrans_factor
     737       
     738      ! Here we need mu0 even though it wasn't in Meador and Weaver
     739      ! because we are assuming the incoming direct flux is defined to
     740      ! be the flux into a plane perpendicular to the direction of the
     741      ! sun, not into a horizontal plane
     742      reftrans_factor = mu0 * ssa(jg) * reftrans_factor &
     743            &  / merge(one_minus_kmu0_sqr, epsilon(1.0_jprb), abs(one_minus_kmu0_sqr) > epsilon(1.0_jprb))
     744     
     745      ! Meador & Weaver (1980) Eq. 14, multiplying top & bottom by
     746      ! exp(-k_exponent*od) in case of very high optical depths
     747      ref_dir(jg) = reftrans_factor &
     748           &  * ( (1.0_jprb - k_mu0) * (alpha2 + k_gamma3) &
     749           &     -(1.0_jprb + k_mu0) * (alpha2 - k_gamma3)*exponential2 &
     750           &     -k_2_exponential*(gamma3 - alpha2*mu0)*trans_dir_dir(jg) )
     751       
     752      ! Meador & Weaver (1980) Eq. 15, multiplying top & bottom by
     753      ! exp(-k_exponent*od), minus the 1*exp(-od/mu0) term
     754      ! representing direct unscattered transmittance.
     755      trans_dir_diff(jg) = reftrans_factor * ( k_2_exponential*(gamma4 + alpha1*mu0) &
     756           & - trans_dir_dir(jg) &
     757           & * ( (1.0_jprb + k_mu0) * (alpha1 + k_gamma4) &
     758           &    -(1.0_jprb - k_mu0) * (alpha1 - k_gamma4) * exponential2) )
     759
     760      ! Final check that ref_dir + trans_dir_diff <= 1
     761      ref_dir(jg)        = max(0.0_jprb, min(ref_dir(jg), mu0*(1.0_jprb-trans_dir_dir(jg))))
     762      trans_dir_diff(jg) = max(0.0_jprb, min(trans_dir_diff(jg), mu0*(1.0_jprb-trans_dir_dir(jg))-ref_dir(jg)))
     763
     764    end do
     765#endif
     766
    708767#ifdef DO_DR_HOOK_TWO_STREAM
    709768    if (lhook) call dr_hook('radiation_two_stream:calc_ref_trans_sw',1,hook_handle)
     
    757816      k_exponent = sqrt(max((gamma1(jg) - gamma2(jg)) * (gamma1(jg) + gamma2(jg)), &
    758817           &       1.0e-12_jprd)) ! Eq 18
    759       exponential = exp_fast(-k_exponent*od(jg))
     818      exponential = exp(-k_exponent*od(jg))
    760819      exponential2 = exponential*exponential
    761820      k_2_exponential = 2.0_jprd * k_exponent * exponential
     
    766825      ! Until 1.1.8, used LwDiffusivity instead of 2.0, although the
    767826      ! effect is very small
    768       !      frac_scat_diffuse(jg) = 1.0_jprb - min(1.0_jprb,exp_fast(-LwDiffusivity*od(jg)) &
     827      !      frac_scat_diffuse(jg) = 1.0_jprb - min(1.0_jprb,exp(-LwDiffusivity*od(jg)) &
    769828      !           &  / max(1.0e-8_jprb, k_2_exponential * reftrans_factor))
    770829      frac_scat_diffuse(jg) = 1.0_jprb &
    771            &  - min(1.0_jprb,exp_fast(-2.0_jprb*od(jg)) &
     830           &  - min(1.0_jprb,exp(-2.0_jprb*od(jg)) &
    772831           &  / max(1.0e-8_jprb, k_2_exponential * reftrans_factor))
    773832    end do
Note: See TracChangeset for help on using the changeset viewer.