LCOV - code coverage report
Current view: top level - physics/rrtmgp/ext/rrtmgp-kernels - mo_gas_optics_rrtmgp_kernels.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 210 219 95.9 %
Date: 2024-12-17 17:57:11 Functions: 9 9 100.0 %

          Line data    Source code
       1             : ! This code is part of
       2             : ! RRTM for GCM Applications - Parallel (RRTMGP)
       3             : !
       4             : ! Eli Mlawer and Robert Pincus
       5             : ! Andre Wehe and Jennifer Delamere
       6             : ! email:  rrtmgp@aer.com
       7             : !
       8             : ! Copyright 2015-,  Atmospheric and Environmental Research,
       9             : ! Regents of the University of Colorado, Trustees of Columbia University.  All right reserved.
      10             : !
      11             : ! Use and duplication is permitted under the terms of the
      12             : !    BSD 3-clause license, see http://opensource.org/licenses/BSD-3-Clause
      13             : ! -------------------------------------------------------------------------------------------------
      14             : !>
      15             : !> ## Numeric calculations for gas optics. Absorption and Rayleigh optical depths, Planck source functions.
      16             : !>
      17             : !>   - Interpolation coefficients are computed, then used in subsequent routines. 
      18             : !>   - All applications will call compute_tau_absorption(); 
      19             : !>     compute_tau_rayleigh() and/or compute_Planck_source() will be called depending on the 
      20             : !>     configuration of the k-distribution. 
      21             : !>   - The details of the interpolation scheme are not particaulrly important as long as arrays including 
      22             : !>     tables are passed consisently between kernels. 
      23             : !>
      24             : ! -------------------------------------------------------------------------------------------------
      25             : 
      26             : module mo_gas_optics_rrtmgp_kernels
      27             :   use mo_rte_kind,      only : wp, wl
      28             :   use mo_rte_util_array,only : zero_array
      29             :   implicit none
      30             :   private
      31             :   public :: interpolation, compute_tau_absorption, compute_tau_rayleigh, compute_Planck_source
      32             : contains
      33             :   ! --------------------------------------------------------------------------------------
      34             :   !> Compute interpolation coefficients
      35             :   !> for calculations of major optical depths, minor optical depths, Rayleigh,
      36             :   !> and Planck fractions
      37     1135399 :   subroutine interpolation( &
      38             :                 ncol,nlay,ngas,nflav,neta, npres, ntemp, &
      39     1135399 :                 flavor,                                  &
      40     1135399 :                 press_ref_log, temp_ref,press_ref_log_delta,    &
      41             :                 temp_ref_min,temp_ref_delta,press_ref_trop_log, &
      42     1135399 :                 vmr_ref,                                        &
      43     1135399 :                 play,tlay,col_gas,                              &
      44     1135399 :                 jtemp,fmajor,fminor,col_mix,tropo,jeta,jpress) bind(C, name="rrtmgp_interpolation")
      45             :     ! input dimensions
      46             :     integer,                            intent(in) :: ncol,nlay
      47             :       !! physical domain size
      48             :     integer,                            intent(in) :: ngas,nflav,neta,npres,ntemp
      49             :       !! k-distribution table dimensions 
      50             :     integer,     dimension(2,nflav),    intent(in) :: flavor
      51             :       !! index into vmr_ref of major gases for each flavor
      52             :     real(wp),    dimension(npres),      intent(in) :: press_ref_log
      53             :       !! log of pressure dimension in RRTMGP tables 
      54             :     real(wp),    dimension(ntemp),      intent(in) :: temp_ref
      55             :       !! temperature dimension in RRTMGP tables 
      56             :     real(wp),                           intent(in) :: press_ref_log_delta, &
      57             :                                                       temp_ref_min, temp_ref_delta, &
      58             :                                                       press_ref_trop_log
      59             :       !! constants related to RRTMGP tables
      60             :     real(wp),    dimension(2,0:ngas,ntemp), intent(in) :: vmr_ref
      61             :       !! reference volume mixing ratios used in compute "binary species parameter" eta
      62             : 
      63             :     ! inputs from profile or parent function
      64             :     real(wp),    dimension(ncol,nlay),        intent(in) :: play, tlay
      65             :       !! input pressure (Pa?) and temperature (K)
      66             :     real(wp),    dimension(ncol,nlay,0:ngas), intent(in) :: col_gas
      67             :       !! input column gas amount - molecules/cm^2 
      68             :     ! outputs
      69             :     integer,     dimension(ncol,nlay), intent(out) :: jtemp, jpress
      70             :       !! temperature and pressure interpolation indexes 
      71             :     logical(wl), dimension(ncol,nlay), intent(out) :: tropo
      72             :       !! use lower (or upper) atmosphere tables 
      73             :     integer,     dimension(2,    ncol,nlay,nflav), intent(out) :: jeta
      74             :       !! Index for binary species interpolation 
      75             : #if !defined(__INTEL_LLVM_COMPILER) && __INTEL_COMPILER >= 1910
      76             :     ! A performance-hitting workaround for the vectorization problem reported in
      77             :     ! https://github.com/earth-system-radiation/rte-rrtmgp/issues/159
      78             :     ! The known affected compilers are Intel Fortran Compiler Classic
      79             :     ! 2021.4, 2021.5 and 2022.1. We do not limit the workaround to these
      80             :     ! versions because it is not clear when the compiler bug will be fixed, see
      81             :     ! https://community.intel.com/t5/Intel-Fortran-Compiler/Compiler-vectorization-bug/m-p/1362591.
      82             :     ! We, however, limit the workaround to the Classic versions only since the
      83             :     ! problem is not confirmed for the Intel Fortran Compiler oneAPI (a.k.a
      84             :     ! 'ifx'), which does not mean there is none though.
      85             :     real(wp),    dimension(:,       :,   :,    :), intent(out) :: col_mix
      86             : #else
      87             :     real(wp),    dimension(2,    ncol,nlay,nflav), intent(out) :: col_mix
      88             :       !! combination of major species's column amounts (first index is strat/trop)
      89             : #endif
      90             :     real(wp),    dimension(2,2,2,ncol,nlay,nflav), intent(out) :: fmajor
      91             :       !! Interpolation weights in pressure, eta, strat/trop 
      92             :     real(wp),    dimension(2,2,  ncol,nlay,nflav), intent(out) :: fminor
      93             :       !! Interpolation fraction in eta, strat/trop 
      94             :     ! -----------------
      95             :     ! local
      96     2270798 :     real(wp), dimension(ncol,nlay) :: ftemp, fpress ! interpolation fraction for temperature, pressure
      97             :     real(wp) :: locpress       ! needed to find location in pressure grid
      98             :     real(wp) :: ratio_eta_half ! ratio of vmrs of major species that defines eta=0.5
      99             :                                ! for given flavor and reference temperature level
     100             :     real(wp) :: eta, feta      ! binary_species_parameter, interpolation variable for eta
     101             :     real(wp) :: loceta         ! needed to find location in eta grid
     102             :     real(wp) :: ftemp_term
     103             :     ! -----------------
     104             :     ! local indexes
     105             :     integer :: icol, ilay, iflav, igases(2), itropo, itemp
     106             : 
     107   107862905 :     do ilay = 1, nlay
     108  1759339505 :       do icol = 1, ncol
     109             :         ! index and factor for temperature interpolation
     110  1651476600 :         jtemp(icol,ilay) = int((tlay(icol,ilay) - (temp_ref_min - temp_ref_delta)) / temp_ref_delta)
     111  1651476600 :         jtemp(icol,ilay) = min(ntemp - 1, max(1, jtemp(icol,ilay))) ! limit the index range
     112  1651476600 :         ftemp(icol,ilay) = (tlay(icol,ilay) - temp_ref(jtemp(icol,ilay))) / temp_ref_delta
     113             : 
     114             :         ! index and factor for pressure interpolation
     115  1651476600 :         locpress = 1._wp + (log(play(icol,ilay)) - press_ref_log(1)) / press_ref_log_delta
     116  1651476600 :         jpress(icol,ilay) = min(npres-1, max(1, int(locpress)))
     117  1651476600 :         fpress(icol,ilay) = locpress - float(jpress(icol,ilay))
     118             : 
     119             :         ! determine if in lower or upper part of atmosphere
     120  1758204106 :         tropo(icol,ilay) = log(play(icol,ilay)) > press_ref_trop_log
     121             :       end do
     122             :     end do
     123             : 
     124    12100126 :     do iflav = 1, nflav
     125    32894181 :       igases(:) = flavor(:,iflav)
     126  1042784464 :       do ilay = 1, nlay
     127 17005922865 :         do icol = 1, ncol
     128             :         ! itropo = 1 lower atmosphere; itropo = 2 upper atmosphere
     129 15964273800 :         itropo = merge(1,2,tropo(icol,ilay))
     130             :         ! loop over implemented combinations of major species
     131 48923505738 :           do itemp = 1, 2
     132             :             ! compute interpolation fractions needed for lower, then upper reference temperature level
     133             :             ! compute binary species parameter (eta) for flavor and temperature and
     134             :             !  associated interpolation index and factors
     135 95785642800 :             ratio_eta_half = vmr_ref(itropo,igases(1),(jtemp(icol,ilay)+itemp-1)) / &
     136 >12771*10^7 :                              vmr_ref(itropo,igases(2),(jtemp(icol,ilay)+itemp-1))
     137 31928547600 :             col_mix(itemp,icol,ilay,iflav) = col_gas(icol,ilay,igases(1)) + ratio_eta_half * col_gas(icol,ilay,igases(2))
     138             :             ! Keep this commented lines. Fortran does allow for
     139             :             ! substantial optimizations and in this merge cases may
     140             :             ! happen that all expressions are evaluated and so create
     141             :             ! a division by zero. In the if construct this should be
     142             :             ! save. Merge is the way to do it in general inside of
     143             :             ! loops, but sometimes it may not work.
     144             :             !
     145             :             ! eta = merge(col_gas(icol,ilay,igases(1)) / col_mix(itemp,icol,ilay,iflav), 0.5_wp, &
     146             :             !             col_mix(itemp,icol,ilay,iflav) > 2._wp * tiny(col_mix))
     147             :             !
     148             :             ! In essence: do not turn it back to merge(...)!
     149 31928547600 :             if (col_mix(itemp,icol,ilay,iflav) > 2._wp * tiny(col_mix)) then
     150 31928547600 :               eta = col_gas(icol,ilay,igases(1)) / col_mix(itemp,icol,ilay,iflav)
     151             :             else
     152             :               eta = 0.5_wp
     153             :             endif
     154 31928547600 :             loceta = eta * float(neta-1)
     155 31928547600 :             jeta(itemp,icol,ilay,iflav) = min(int(loceta)+1, neta-1)
     156 31928547600 :             feta = mod(loceta, 1.0_wp)
     157             :             ! compute interpolation fractions needed for minor species
     158             :             ! ftemp_term = (1._wp-ftemp(icol,ilay)) for itemp = 1, ftemp(icol,ilay) for itemp=2
     159 31928547600 :             ftemp_term = (real(2-itemp, wp) + real(2*itemp-3, wp) * ftemp(icol,ilay))
     160 31928547600 :             fminor(1,itemp,icol,ilay,iflav) = (1._wp-feta) * ftemp_term
     161 31928547600 :             fminor(2,itemp,icol,ilay,iflav) =        feta  * ftemp_term
     162             :             ! compute interpolation fractions needed for major species
     163 31928547600 :             fmajor(1,1,itemp,icol,ilay,iflav) = (1._wp-fpress(icol,ilay)) * fminor(1,itemp,icol,ilay,iflav)
     164 31928547600 :             fmajor(2,1,itemp,icol,ilay,iflav) = (1._wp-fpress(icol,ilay)) * fminor(2,itemp,icol,ilay,iflav)
     165 31928547600 :             fmajor(1,2,itemp,icol,ilay,iflav) =        fpress(icol,ilay)  * fminor(1,itemp,icol,ilay,iflav)
     166 47892821400 :             fmajor(2,2,itemp,icol,ilay,iflav) =        fpress(icol,ilay)  * fminor(2,itemp,icol,ilay,iflav)
     167             :           end do ! reference temperatures
     168             :         end do ! icol
     169             :       end do ! ilay
     170             :     end do ! iflav
     171             : 
     172     1135399 :   end subroutine interpolation
     173             :   ! --------------------------------------------------------------------------------------
     174             :   !
     175             :   !> Compute minor and major species optical depth using pre-computed interpolation coefficients
     176             :   !>   (jeta,jtemp,jpress) and weights (fmajor, fminor)
     177             :   !
     178     1135399 :   subroutine compute_tau_absorption(                &
     179             :                 ncol,nlay,nbnd,ngpt,                &  ! dimensions
     180             :                 ngas,nflav,neta,npres,ntemp,        &
     181             :                 nminorlower, nminorklower,          & ! number of minor contributors, total num absorption coeffs
     182             :                 nminorupper, nminorkupper,          &
     183             :                 idx_h2o,                            &
     184     1135399 :                 gpoint_flavor,                      &
     185     1135399 :                 band_lims_gpt,                      &
     186     1135399 :                 kmajor,                             &
     187     1135399 :                 kminor_lower,                       &
     188     1135399 :                 kminor_upper,                       &
     189     1135399 :                 minor_limits_gpt_lower,             &
     190     1135399 :                 minor_limits_gpt_upper,             &
     191     1135399 :                 minor_scales_with_density_lower,    &
     192     1135399 :                 minor_scales_with_density_upper,    &
     193     1135399 :                 scale_by_complement_lower,          &
     194     1135399 :                 scale_by_complement_upper,          &
     195     1135399 :                 idx_minor_lower,                    &
     196     1135399 :                 idx_minor_upper,                    &
     197     1135399 :                 idx_minor_scaling_lower,            &
     198     1135399 :                 idx_minor_scaling_upper,            &
     199     1135399 :                 kminor_start_lower,                 &
     200     1135399 :                 kminor_start_upper,                 &
     201     1135399 :                 tropo,                              &
     202     1135399 :                 col_mix,fmajor,fminor,              &
     203     1135399 :                 play,tlay,col_gas,                  &
     204     1135399 :                 jeta,jtemp,jpress,                  &
     205     1135399 :                 tau) bind(C, name="rrtmgp_compute_tau_absorption")
     206             :     ! ---------------------
     207             :     ! input dimensions
     208             :     integer,                                intent(in) :: ncol,nlay,nbnd,ngpt         !! array sizes 
     209             :     integer,                                intent(in) :: ngas,nflav,neta,npres,ntemp !! tables sizes 
     210             :     integer,                                intent(in) :: nminorlower, nminorklower,nminorupper, nminorkupper
     211             :                                                           !! table sizes
     212             :     integer,                                intent(in) :: idx_h2o                     !! index of water vapor in col_gas
     213             :     ! ---------------------
     214             :     ! inputs from object
     215             :     integer,     dimension(2,ngpt),                  intent(in) :: gpoint_flavor
     216             :       !! major gas flavor (pair) by upper/lower, g-point
     217             :     integer,     dimension(2,nbnd),                  intent(in) :: band_lims_gpt
     218             :       !! beginning and ending g-point for each band 
     219             :     real(wp),    dimension(ntemp,neta,npres+1,ngpt), intent(in) :: kmajor
     220             :       !! absorption coefficient table - major gases 
     221             :     real(wp),    dimension(ntemp,neta,nminorklower), intent(in) :: kminor_lower
     222             :       !! absorption coefficient table - minor gases, lower atmosphere 
     223             :     real(wp),    dimension(ntemp,neta,nminorkupper), intent(in) :: kminor_upper
     224             :       !! absorption coefficient table - minor gases, upper atmosphere 
     225             :     integer,     dimension(2,nminorlower),           intent(in) :: minor_limits_gpt_lower
     226             :       !! beginning and ending g-point for each minor gas 
     227             :     integer,     dimension(2,nminorupper),           intent(in) :: minor_limits_gpt_upper
     228             :     logical(wl), dimension(  nminorlower),           intent(in) :: minor_scales_with_density_lower
     229             :       !! generic treatment of minor gases - scales with density (e.g. continuum, collision-induced absorption)?
     230             :     logical(wl), dimension(  nminorupper),           intent(in) :: minor_scales_with_density_upper
     231             :     logical(wl), dimension(  nminorlower),           intent(in) :: scale_by_complement_lower
     232             :       !! generic treatment of minor gases - scale by density (e.g. self-continuum) or complement?  
     233             :     logical(wl), dimension(  nminorupper),           intent(in) :: scale_by_complement_upper
     234             :     integer,     dimension(  nminorlower),           intent(in) :: idx_minor_lower  
     235             :       !! index of each minor gas in col_gas
     236             :     integer,     dimension(  nminorupper),           intent(in) :: idx_minor_upper
     237             :     integer,     dimension(  nminorlower),           intent(in) :: idx_minor_scaling_lower 
     238             :       !! for this minor gas, index of the "scaling gas" in col_gas 
     239             :     integer,     dimension(  nminorupper),           intent(in) :: idx_minor_scaling_upper
     240             :     integer,     dimension(  nminorlower),           intent(in) :: kminor_start_lower 
     241             :       !! starting g-point index in minor gas absorption table
     242             :     integer,     dimension(  nminorupper),           intent(in) :: kminor_start_upper
     243             :     logical(wl), dimension(ncol,nlay),               intent(in) :: tropo
     244             :       !! use upper- or lower-atmospheric tables? 
     245             :     ! ---------------------
     246             :     ! inputs from profile or parent function
     247             :     real(wp), dimension(2,    ncol,nlay,nflav       ), intent(in) :: col_mix
     248             :       !! combination of major species's column amounts - computed in interpolation() 
     249             :     real(wp), dimension(2,2,2,ncol,nlay,nflav       ), intent(in) :: fmajor
     250             :       !! interpolation weights for major gases - computed in interpolation() 
     251             :     real(wp), dimension(2,2,  ncol,nlay,nflav       ), intent(in) :: fminor
     252             :       !! interpolation weights for minor gases - computed in interpolation() 
     253             :     real(wp), dimension(            ncol,nlay       ), intent(in) :: play, tlay 
     254             :       !! input temperature and pressure 
     255             :     real(wp), dimension(            ncol,nlay,0:ngas), intent(in) :: col_gas
     256             :       !! input column gas amount (molecules/cm^2) 
     257             :     integer,  dimension(2,    ncol,nlay,nflav       ), intent(in) :: jeta
     258             :       !! interpolation indexes in eta - computed in interpolation() 
     259             :     integer,  dimension(            ncol,nlay       ), intent(in) :: jtemp
     260             :       !! interpolation indexes in temperature - computed in interpolation() 
     261             :     integer,  dimension(            ncol,nlay       ), intent(in) :: jpress
     262             :       !! interpolation indexes in pressure  - computed in interpolation() 
     263             :     ! ---------------------
     264             :     ! output - optical depth
     265             :     real(wp), dimension(ncol,nlay,ngpt), intent(inout) :: tau !! aborption optional depth 
     266             :     ! ---------------------
     267             :     ! Local variables
     268             :     !
     269             :     logical                    :: top_at_1
     270     2270798 :     integer, dimension(ncol,2) :: itropo_lower, itropo_upper
     271             :     ! ----------------------------------------------------------------
     272             : 
     273             :     ! ---------------------
     274             :     ! Layer limits of upper, lower atmospheres
     275             :     ! ---------------------
     276     1135399 :     top_at_1 = play(1,1) < play(1, nlay)
     277     1135399 :     if(top_at_1) then
     278     1135399 :       itropo_lower(:, 1) = minloc(play, dim=2, mask=tropo)
     279    18704299 :       itropo_lower(:, 2) = nlay
     280    18704299 :       itropo_upper(:, 1) = 1
     281  1759339505 :       itropo_upper(:, 2) = maxloc(play, dim=2, mask=(.not. tropo))
     282             :     else
     283           0 :       itropo_lower(:, 1) = 1
     284           0 :       itropo_lower(:, 2) = minloc(play, dim=2, mask= tropo)
     285           0 :       itropo_upper(:, 1) = maxloc(play, dim=2, mask=(.not. tropo))
     286           0 :       itropo_upper(:, 2) = nlay
     287             :     end if
     288             :     ! ---------------------
     289             :     ! Major Species
     290             :     ! ---------------------
     291             :     call gas_optical_depths_major(   &
     292             :           ncol,nlay,nbnd,ngpt,       & ! dimensions
     293             :           nflav,neta,npres,ntemp,    &
     294             :           gpoint_flavor,             &
     295             :           band_lims_gpt,             &
     296             :           kmajor,                    &
     297             :           col_mix,fmajor,            &
     298             :           jeta,tropo,jtemp,jpress,   &
     299     1135399 :           tau)
     300             :     ! ---------------------
     301             :     ! Minor Species - lower
     302             :     ! ---------------------
     303             :     call gas_optical_depths_minor(     &
     304             :            ncol,nlay,ngpt,             & ! dimensions
     305             :            ngas,nflav,ntemp,neta,      &
     306             :            nminorlower,nminorklower,   &
     307             :            idx_h2o,                    &
     308             :            gpoint_flavor(1,:),         &
     309             :            kminor_lower,               &
     310             :            minor_limits_gpt_lower,     &
     311             :            minor_scales_with_density_lower, &
     312             :            scale_by_complement_lower,  &
     313             :            idx_minor_lower,            &
     314             :            idx_minor_scaling_lower,    &
     315             :            kminor_start_lower,         &
     316             :            play, tlay,                 &
     317             :            col_gas,fminor,jeta,        &
     318             :            itropo_lower,jtemp,         &
     319   140238263 :            tau)
     320             :     ! ---------------------
     321             :     ! Minor Species - upper
     322             :     ! ---------------------
     323             :     call gas_optical_depths_minor(     &
     324             :            ncol,nlay,ngpt,             & ! dimensions
     325             :            ngas,nflav,ntemp,neta,      &
     326             :            nminorupper,nminorkupper,   &
     327             :            idx_h2o,                    &
     328             :            gpoint_flavor(2,:),         &
     329             :            kminor_upper,               &
     330             :            minor_limits_gpt_upper,     &
     331             :            minor_scales_with_density_upper, &
     332             :            scale_by_complement_upper,  &
     333             :            idx_minor_upper,            &
     334             :            idx_minor_scaling_upper,    &
     335             :            kminor_start_upper,         &
     336             :            play, tlay,                 &
     337             :            col_gas,fminor,jeta,        &
     338             :            itropo_upper,jtemp,         &
     339   140238263 :            tau)
     340     1135399 :   end subroutine compute_tau_absorption
     341             :   ! --------------------------------------------------------------------------------------
     342             : 
     343             :   ! --------------------------------------------------------------------------------------
     344             :   !
     345             :   ! compute minor species optical depths
     346             :   !
     347     1135399 :   subroutine gas_optical_depths_major(ncol,nlay,nbnd,ngpt,&
     348             :                                       nflav,neta,npres,ntemp,      & ! dimensions
     349     1135399 :                                       gpoint_flavor, band_lims_gpt,   & ! inputs from object
     350     1135399 :                                       kmajor,                         &
     351     1135399 :                                       col_mix,fmajor,                 &
     352     1135399 :                                       jeta,tropo,jtemp,jpress,        & ! local input
     353     1135399 :                                       tau)
     354             :     ! input dimensions
     355             :     integer, intent(in) :: ncol, nlay, nbnd, ngpt, nflav,neta,npres,ntemp  ! dimensions
     356             : 
     357             :     ! inputs from object
     358             :     integer,  dimension(2,ngpt),  intent(in) :: gpoint_flavor
     359             :     integer,  dimension(2,nbnd),  intent(in) :: band_lims_gpt ! start and end g-point for each band
     360             :     real(wp), dimension(ntemp,neta,npres+1,ngpt), intent(in) :: kmajor
     361             : 
     362             :     ! inputs from profile or parent function
     363             :     real(wp),    dimension(2,    ncol,nlay,nflav), intent(in) :: col_mix
     364             :     real(wp),    dimension(2,2,2,ncol,nlay,nflav), intent(in) :: fmajor
     365             :     integer,     dimension(2,    ncol,nlay,nflav), intent(in) :: jeta
     366             :     logical(wl), dimension(ncol,nlay), intent(in) :: tropo
     367             :     integer,     dimension(ncol,nlay), intent(in) :: jtemp, jpress
     368             : 
     369             :     ! outputs
     370             :     real(wp), dimension(ncol,nlay,ngpt), intent(inout) :: tau
     371             :     ! -----------------
     372             :     ! local variables
     373     2270798 :     real(wp) :: tau_major(ngpt) ! major species optical depth
     374             :     ! local index
     375             :     integer :: icol, ilay, iflav, ibnd, itropo
     376             :     integer :: gptS, gptE
     377             : 
     378             :     ! optical depth calculation for major species
     379    18523257 :     do ibnd = 1, nbnd
     380    17387858 :       gptS = band_lims_gpt(1, ibnd)
     381    17387858 :       gptE = band_lims_gpt(2, ibnd)
     382  1652981909 :       do ilay = 1, nlay
     383 26974487710 :         do icol = 1, ncol
     384             :           ! itropo = 1 lower atmosphere; itropo = 2 upper atmosphere
     385 25322641200 :           itropo = merge(1,2,tropo(icol,ilay))
     386 25322641200 :           iflav = gpoint_flavor(itropo, gptS) !eta interpolation depends on band's flavor
     387           0 :           tau_major(gptS:gptE) = &
     388             :             ! interpolation in temperature, pressure, and eta
     389             :             interpolate3D_byflav(col_mix(:,icol,ilay,iflav),                                     &
     390             :                                  fmajor(:,:,:,icol,ilay,iflav), kmajor,                          &
     391             :                                  band_lims_gpt(1, ibnd), band_lims_gpt(2, ibnd),                 &
     392 25322641200 :                                  jeta(:,icol,ilay,iflav), jtemp(icol,ilay),jpress(icol,ilay)+itropo)
     393 >22953*10^7 :             tau(icol,ilay,gptS:gptE) = tau(icol,ilay,gptS:gptE) + tau_major(gptS:gptE)
     394             :         end do
     395             :       end do
     396             :     end do
     397             : 
     398     1135399 :   end subroutine gas_optical_depths_major
     399             : 
     400             :   ! ----------------------------------------------------------
     401             :   !
     402             :   ! compute minor species optical depths
     403             :   !
     404     2270798 :   subroutine gas_optical_depths_minor(ncol,nlay,ngpt,        &
     405             :                                       ngas,nflav,ntemp,neta, &
     406             :                                       nminor,nminork,        &
     407             :                                       idx_h2o,               &
     408     2270798 :                                       gpt_flv,               &
     409     2270798 :                                       kminor,                &
     410     2270798 :                                       minor_limits_gpt,      &
     411     2270798 :                                       minor_scales_with_density,    &
     412     2270798 :                                       scale_by_complement,   &
     413     2270798 :                                       idx_minor, idx_minor_scaling, &
     414     2270798 :                                       kminor_start,          &
     415     2270798 :                                       play, tlay,            &
     416     2270798 :                                       col_gas,fminor,jeta,   &
     417     2270798 :                                       layer_limits,jtemp,    &
     418     2270798 :                                       tau)
     419             :     integer,                                     intent(in   ) :: ncol,nlay,ngpt
     420             :     integer,                                     intent(in   ) :: ngas,nflav
     421             :     integer,                                     intent(in   ) :: ntemp,neta,nminor,nminork
     422             :     integer,                                     intent(in   ) :: idx_h2o
     423             :     integer,     dimension(ngpt),                intent(in   ) :: gpt_flv
     424             :     real(wp),    dimension(ntemp,neta,nminork),  intent(in   ) :: kminor
     425             :     integer,     dimension(2,nminor),            intent(in   ) :: minor_limits_gpt
     426             :     logical(wl), dimension(  nminor),            intent(in   ) :: minor_scales_with_density
     427             :     logical(wl), dimension(  nminor),            intent(in   ) :: scale_by_complement
     428             :     integer,     dimension(  nminor),            intent(in   ) :: kminor_start
     429             :     integer,     dimension(  nminor),            intent(in   ) :: idx_minor, idx_minor_scaling
     430             :     real(wp),    dimension(ncol,nlay),           intent(in   ) :: play, tlay
     431             :     real(wp),    dimension(ncol,nlay,0:ngas),    intent(in   ) :: col_gas
     432             :     real(wp),    dimension(2,2,ncol,nlay,nflav), intent(in   ) :: fminor
     433             :     integer,     dimension(2,  ncol,nlay,nflav), intent(in   ) :: jeta
     434             :     integer,     dimension(ncol, 2),             intent(in   ) :: layer_limits
     435             :     integer,     dimension(ncol,nlay),           intent(in   ) :: jtemp
     436             :     real(wp),    dimension(ncol,nlay,ngpt),      intent(inout) :: tau
     437             :     ! -----------------
     438             :     ! local variables
     439             :     real(wp), parameter :: PaTohPa = 0.01_wp
     440             :     real(wp) :: vmr_fact, dry_fact             ! conversion from column abundance to dry vol. mixing ratio;
     441             :     real(wp) :: scaling                        ! optical depth
     442             :     integer  :: icol, ilay, iflav, imnr
     443             :     integer  :: gptS, gptE
     444     2270798 :     real(wp), dimension(ngpt) :: tau_minor
     445             :     ! -----------------
     446             :     !
     447             :     ! Guard against layer limits being 0 -- that means don't do anything i.e. there are no
     448             :     !   layers with pressures in the upper or lower atmosphere respectively
     449             :     ! First check skips the routine entirely if all columns are out of bounds...
     450             :     !
     451             : 
     452     2270798 :     if(any(layer_limits(:,1) > 0)) then
     453    70654441 :       do imnr = 1, size(scale_by_complement,dim=1) ! loop over minor absorbers in each band
     454  1130644741 :         do icol = 1, ncol
     455             :           !
     456             :           ! This check skips individual columns with no pressures in range
     457             :           !
     458  1128373943 :           if(layer_limits(icol,1) > 0) then
     459 50868404580 :             do ilay = layer_limits(icol,1), layer_limits(icol,2)
     460             :               !
     461             :               ! Scaling of minor gas absortion coefficient begins with column amount of minor gas
     462             :               !
     463 49808414280 :               scaling = col_gas(icol,ilay,idx_minor(imnr))
     464             :               !
     465             :               ! Density scaling (e.g. for h2o continuum, collision-induced absorption)
     466             :               !
     467 49808414280 :               if (minor_scales_with_density(imnr)) then
     468             :                 !
     469             :                 ! NOTE: P needed in hPa to properly handle density scaling.
     470             :                 !
     471 33845628712 :                 scaling = scaling * (PaTohPa*play(icol,ilay)/tlay(icol,ilay))
     472 33845628712 :                 if(idx_minor_scaling(imnr) > 0) then  ! there is a second gas that affects this gas's absorption
     473 31919150504 :                   vmr_fact = 1._wp / col_gas(icol,ilay,0)
     474 31919150504 :                   dry_fact = 1._wp / (1._wp + col_gas(icol,ilay,idx_h2o) * vmr_fact)
     475             :                   ! scale by density of special gas
     476 31919150504 :                   if (scale_by_complement(imnr)) then ! scale by densities of all gases but the special one
     477 15959575252 :                     scaling = scaling * (1._wp - col_gas(icol,ilay,idx_minor_scaling(imnr)) * vmr_fact * dry_fact)
     478             :                   else
     479 15959575252 :                     scaling = scaling *         (col_gas(icol,ilay,idx_minor_scaling(imnr)) * vmr_fact * dry_fact)
     480             :                   endif
     481             :                 endif
     482             :               endif
     483             :               !
     484             :               ! Interpolation of absorption coefficient and calculation of optical depth
     485             :               !
     486             :               ! Which gpoint range does this minor gas affect?
     487 49808414280 :               gptS = minor_limits_gpt(1,imnr)
     488 49808414280 :               gptE = minor_limits_gpt(2,imnr)
     489 49808414280 :               iflav = gpt_flv(gptS)
     490           0 :               tau_minor(gptS:gptE) = scaling *                   &
     491             :                                       interpolate2D_byflav(fminor(:,:,icol,ilay,iflav), &
     492             :                                                            kminor, &
     493             :                                                            kminor_start(imnr), kminor_start(imnr)+(gptE-gptS), &
     494 >46920*10^7 :                                                            jeta(:,icol,ilay,iflav), jtemp(icol,ilay))
     495 >47026*10^7 :               tau(icol,ilay,gptS:gptE) = tau(icol,ilay,gptS:gptE) + tau_minor(gptS:gptE)
     496             :             enddo
     497             :           end if
     498             :         enddo
     499             :       enddo
     500             :     end if
     501             : 
     502     2270798 :   end subroutine gas_optical_depths_minor
     503             :   ! ----------------------------------------------------------
     504             :   !
     505             :   ! compute Rayleigh scattering optical depths
     506             :   !
     507      389263 :   subroutine compute_tau_rayleigh(ncol,nlay,nbnd,ngpt,         &
     508             :                                   ngas,nflav,neta,npres,ntemp, &
     509      389263 :                                   gpoint_flavor,band_lims_gpt, &
     510      389263 :                                   krayl,                       &
     511      389263 :                                   idx_h2o, col_dry,col_gas,    &
     512      389263 :                                   fminor,jeta,tropo,jtemp,     &
     513      389263 :                                   tau_rayleigh) bind(C, name="rrtmgp_compute_tau_rayleigh")
     514             :     integer,                                     intent(in ) :: ncol,nlay,nbnd,ngpt
     515             :       !! input dimensions 
     516             :     integer,                                     intent(in ) :: ngas,nflav,neta,npres,ntemp
     517             :       !! table dimensions 
     518             :     integer,     dimension(2,ngpt),              intent(in ) :: gpoint_flavor 
     519             :       !! major gas flavor (pair) by upper/lower, g-point
     520             :     integer,     dimension(2,nbnd),              intent(in ) :: band_lims_gpt
     521             :       !! start and end g-point for each band
     522             :     real(wp),    dimension(ntemp,neta,ngpt,2),   intent(in ) :: krayl
     523             :       !! Rayleigh scattering coefficients 
     524             :     integer,                                     intent(in ) :: idx_h2o
     525             :       !! index of water vapor in col_gas
     526             :     real(wp),    dimension(ncol,nlay),           intent(in ) :: col_dry
     527             :       !! column amount of dry air 
     528             :     real(wp),    dimension(ncol,nlay,0:ngas),    intent(in ) :: col_gas
     529             :       !! input column gas amount  (molecules/cm^2)
     530             :     real(wp),    dimension(2,2,ncol,nlay,nflav), intent(in ) :: fminor
     531             :       !! interpolation weights for major gases - computed in interpolation() 
     532             :     integer,     dimension(2,  ncol,nlay,nflav), intent(in ) :: jeta
     533             :       !! interpolation indexes in eta - computed in interpolation() 
     534             :     logical(wl), dimension(ncol,nlay),           intent(in ) :: tropo
     535             :       !! use upper- or lower-atmospheric tables? 
     536             :     integer,     dimension(ncol,nlay),           intent(in ) :: jtemp
     537             :       !! interpolation indexes in temperature - computed in interpolation() 
     538             :     ! outputs
     539             :     real(wp),    dimension(ncol,nlay,ngpt),      intent(out) :: tau_rayleigh
     540             :       !! Rayleigh optical depth 
     541             :     ! -----------------
     542             :     ! local variables
     543      778526 :     real(wp) :: k(ngpt) ! rayleigh scattering coefficient
     544             :     integer  :: icol, ilay, iflav, ibnd, gptS, gptE
     545             :     integer  :: itropo
     546             :     ! -----------------
     547             : 
     548     5838945 :     do ibnd = 1, nbnd
     549     5449682 :       gptS = band_lims_gpt(1, ibnd)
     550     5449682 :       gptE = band_lims_gpt(2, ibnd)
     551   518109053 :       do ilay = 1, nlay
     552  8224610590 :         do icol = 1, ncol
     553  7706890800 :           itropo = merge(1,2,tropo(icol,ilay)) ! itropo = 1 lower atmosphere;itropo = 2 upper atmosphere
     554  7706890800 :           iflav = gpoint_flavor(itropo, gptS) !eta interpolation depends on band's flavor
     555           0 :           k(gptS:gptE) = interpolate2D_byflav(fminor(:,:,icol,ilay,iflav), &
     556             :                                               krayl(:,:,:,itropo),      &
     557  7706890800 :                                               gptS, gptE, jeta(:,icol,ilay,iflav), jtemp(icol,ilay))
     558           0 :           tau_rayleigh(icol,ilay,gptS:gptE) = k(gptS:gptE) * &
     559 69874287308 :                                               (col_gas(icol,ilay,idx_h2o)+col_dry(icol,ilay))
     560             :         end do
     561             :       end do
     562             :     end do
     563             : 
     564      389263 :   end subroutine compute_tau_rayleigh
     565             : 
     566             :   ! ----------------------------------------------------------
     567      746136 :   subroutine compute_Planck_source(                        &
     568             :                     ncol, nlay, nbnd, ngpt,                &
     569             :                     nflav, neta, npres, ntemp, nPlanckTemp,&
     570      746136 :                     tlay, tlev, tsfc, sfc_lay,             &
     571      746136 :                     fmajor, jeta, tropo, jtemp, jpress,    &
     572      746136 :                     gpoint_bands, band_lims_gpt,           &
     573      746136 :                     pfracin, temp_ref_min, totplnk_delta, totplnk, gpoint_flavor, &
     574      746136 :                     sfc_src, lay_src, lev_src_inc, lev_src_dec, sfc_source_Jac) bind(C, name="rrtmgp_compute_Planck_source")
     575             :     integer,                                    intent(in) :: ncol, nlay, nbnd, ngpt
     576             :       !! input dimensions 
     577             :     integer,                                    intent(in) :: nflav, neta, npres, ntemp, nPlanckTemp
     578             :       !! table dimensions 
     579             :     real(wp),    dimension(ncol,nlay  ),        intent(in) :: tlay !! temperature at layer centers (K)
     580             :     real(wp),    dimension(ncol,nlay+1),        intent(in) :: tlev !! temperature at interfaces (K)
     581             :     real(wp),    dimension(ncol       ),        intent(in) :: tsfc !! surface temperture 
     582             :     integer,                                    intent(in) :: sfc_lay !! index into surface layer 
     583             :     ! Interpolation variables
     584             :     real(wp),    dimension(2,2,2,ncol,nlay,nflav), intent(in) :: fmajor
     585             :       !! interpolation weights for major gases - computed in interpolation() 
     586             :     integer,     dimension(2,    ncol,nlay,nflav), intent(in) :: jeta
     587             :       !! interpolation indexes in eta - computed in interpolation() 
     588             :     logical(wl), dimension(            ncol,nlay), intent(in) :: tropo
     589             :       !! use upper- or lower-atmospheric tables? 
     590             :     integer,     dimension(            ncol,nlay), intent(in) :: jtemp, jpress
     591             :       !! interpolation indexes in temperature and pressure - computed in interpolation() 
     592             :     ! Table-specific
     593             :     integer, dimension(ngpt),                     intent(in) :: gpoint_bands  !! band to which each g-point belongs
     594             :     integer, dimension(2, nbnd),                  intent(in) :: band_lims_gpt !! start and end g-point for each band
     595             :     real(wp),                                     intent(in) :: temp_ref_min, totplnk_delta !! interpolation constants
     596             :     real(wp), dimension(ntemp,neta,npres+1,ngpt), intent(in) :: pfracin       !! Fraction of the Planck function in each g-point
     597             :     real(wp), dimension(nPlanckTemp,nbnd),        intent(in) :: totplnk       !! Total Planck function by band at each temperature 
     598             :     integer,  dimension(2,ngpt),                  intent(in) :: gpoint_flavor !! major gas flavor (pair) by upper/lower, g-point
     599             : 
     600             :     real(wp), dimension(ncol,     ngpt), intent(out) :: sfc_src  !! Planck emssion from the surface 
     601             :     real(wp), dimension(ncol,nlay,ngpt), intent(out) :: lay_src  !! Planck emssion from layer centers
     602             :     real(wp), dimension(ncol,nlay,ngpt), intent(out) :: lev_src_inc, lev_src_dec
     603             :       !! Planck emission at layer boundaries, using spectral mapping in the direction of propagation 
     604             :     real(wp), dimension(ncol,     ngpt), intent(out) :: sfc_source_Jac 
     605             :       !! Jacobian (derivative) of the surface Planck source with respect to surface temperature 
     606             :     ! -----------------
     607             :     ! local
     608             :     real(wp), parameter                             :: delta_Tsurf = 1.0_wp
     609             : 
     610             :     integer  :: ilay, icol, igpt, ibnd, itropo, iflav
     611             :     integer  :: gptS, gptE
     612             :     real(wp), dimension(2), parameter :: one = [1._wp, 1._wp]
     613     1492272 :     real(wp) :: pfrac          (ncol,nlay  ,ngpt)
     614     1492272 :     real(wp) :: planck_function(ncol,nlay+1,nbnd)
     615             :     ! -----------------
     616             : 
     617             :     ! Calculation of fraction of band's Planck irradiance associated with each g-point
     618    12684312 :     do ibnd = 1, nbnd
     619    11938176 :       gptS = band_lims_gpt(1, ibnd)
     620    11938176 :       gptE = band_lims_gpt(2, ibnd)
     621  1134872856 :       do ilay = 1, nlay
     622 18749877120 :         do icol = 1, ncol
     623             :           ! itropo = 1 lower atmosphere; itropo = 2 upper atmosphere
     624 17615750400 :           itropo = merge(1,2,tropo(icol,ilay))
     625 17615750400 :           iflav = gpoint_flavor(itropo, gptS) !eta interpolation depends on band's flavor
     626           0 :           pfrac(icol,ilay,gptS:gptE) = &
     627             :             ! interpolation in temperature, pressure, and eta
     628             :             interpolate3D_byflav(one, fmajor(:,:,:,icol,ilay,iflav), pfracin, &
     629             :                           band_lims_gpt(1, ibnd), band_lims_gpt(2, ibnd),                 &
     630 >15966*10^7 :                           jeta(:,icol,ilay,iflav), jtemp(icol,ilay),jpress(icol,ilay)+itropo)
     631             :         end do ! column
     632             :       end do   ! layer
     633             :     end do     ! band
     634             : 
     635             :     !
     636             :     ! Planck function by band for the surface
     637             :     ! Compute surface source irradiance for g-point, equals band irradiance x fraction for g-point
     638             :     !
     639    12458736 :     do icol = 1, ncol
     640   199114200 :       planck_function(icol,1,1:nbnd) = interpolate1D(tsfc(icol), temp_ref_min, totplnk_delta, totplnk)
     641   199114200 :       planck_function(icol,2,1:nbnd) = interpolate1D(tsfc(icol) + delta_Tsurf, temp_ref_min, totplnk_delta, totplnk)
     642             :       !
     643             :       ! Map to g-points
     644             :       !
     645   199860336 :       do ibnd = 1, nbnd
     646   187401600 :         gptS = band_lims_gpt(1, ibnd)
     647   187401600 :         gptE = band_lims_gpt(2, ibnd)
     648  1698327000 :         do igpt = gptS, gptE
     649  1499212800 :             sfc_src(icol,igpt) = pfrac(icol,sfc_lay,igpt) * planck_function(icol,1,ibnd)
     650             :             sfc_source_Jac(icol, igpt) = pfrac(icol,sfc_lay,igpt) * &
     651  1686614400 :                                 (planck_function(icol, 2, ibnd) - planck_function(icol,1,ibnd))
     652             :         end do
     653             :       end do
     654             :     end do !icol
     655             : 
     656    70882920 :     do ilay = 1, nlay
     657  1171867320 :       do icol = 1, ncol
     658             :         ! Compute layer source irradiance for g-point, equals band irradiance x fraction for g-point
     659 18786871584 :         planck_function(icol,ilay,1:nbnd) = interpolate1D(tlay(icol,ilay), temp_ref_min, totplnk_delta, totplnk)
     660             :       end do
     661             :     end do
     662             : 
     663             :     !
     664             :     ! Map to g-points
     665             :     !
     666    12684312 :     do ibnd = 1, nbnd
     667    11938176 :       gptS = band_lims_gpt(1, ibnd)
     668    11938176 :       gptE = band_lims_gpt(2, ibnd)
     669   108189720 :       do igpt = gptS, gptE
     670  9084951936 :         do ilay = 1, nlay
     671 >14999*10^7 :           do icol = 1, ncol
     672 >14990*10^7 :             lay_src(icol,ilay,igpt) = pfrac(icol,ilay,igpt) * planck_function(icol,ilay,ibnd)
     673             :           end do
     674             :         end do
     675             :       end do
     676             :     end do
     677             : 
     678             :     ! compute level source irradiances for each g-point, one each for upward and downward paths
     679    70882920 :     do ilay = 1, nlay
     680  1171867320 :       do icol = 1, ncol
     681 18716734800 :       planck_function(icol,     1,1:nbnd) = interpolate1D(tlev(icol,     1),temp_ref_min, totplnk_delta, totplnk)
     682 18786871584 :       planck_function(icol,ilay+1,1:nbnd) = interpolate1D(tlev(icol,ilay+1),temp_ref_min, totplnk_delta, totplnk)
     683             :       end do
     684             :     end do
     685             : 
     686             :     !
     687             :     ! Map to g-points
     688             :     !
     689    12684312 :     do ibnd = 1, nbnd
     690    11938176 :       gptS = band_lims_gpt(1, ibnd)
     691    11938176 :       gptE = band_lims_gpt(2, ibnd)
     692   108189720 :       do igpt = gptS, gptE
     693  9084951936 :         do ilay = 1, nlay
     694 >14999*10^7 :           do icol = 1, ncol
     695 >14092*10^7 :             lev_src_inc(icol,ilay,igpt) = pfrac(icol,ilay,igpt) *planck_function(icol,ilay+1,ibnd)
     696 >14990*10^7 :             lev_src_dec(icol,ilay,igpt) = pfrac(icol,ilay,igpt) *planck_function(icol,ilay  ,ibnd)
     697             :           end do
     698             :         end do
     699             :       end do
     700             :     end do
     701             : 
     702      746136 :   end subroutine compute_Planck_source
     703             :   ! ----------------------------------------------------------
     704             :   !
     705             :   ! One dimensional interpolation -- return all values along second table dimension
     706             :   !
     707  3326378400 :   pure function interpolate1D(val, offset, delta, table) result(res)
     708             :     ! input
     709             :     real(wp), intent(in) :: val,    & ! axis value at which to evaluate table
     710             :                             offset, & ! minimum of table axis
     711             :                             delta     ! step size of table axis
     712             :     real(wp), dimension(:,:), &
     713             :               intent(in) :: table ! dimensions (axis, values)
     714             :     ! output
     715             :     real(wp), dimension(size(table,dim=2)) :: res
     716             : 
     717             :     ! local
     718             :     real(wp) :: val0 ! fraction index adjusted by offset and delta
     719             :     integer :: index ! index term
     720             :     real(wp) :: frac ! fractional term
     721             :     ! -------------------------------------
     722  3326378400 :     val0 = (val - offset) / delta
     723  3326378400 :     frac = val0 - int(val0) ! get fractional part
     724  3326378400 :     index = min(size(table,dim=1)-1, max(1, int(val0)+1)) ! limit the index range
     725 56548432800 :     res(:) = table(index,:) + frac * (table(index+1,:) - table(index,:))
     726  3326378400 :   end function interpolate1D
     727             :   ! ----------------------------------------------------------
     728             :   !   This function returns a range of values from a subset (in gpoint) of the k table
     729             :   !
     730 57515305080 :   pure function interpolate2D_byflav(fminor, k, gptS, gptE, jeta, jtemp) result(res)
     731             :     real(wp), dimension(2,2), intent(in) :: fminor ! interpolation fractions for minor species
     732             :                                        ! index(1) : reference eta level (temperature dependent)
     733             :                                        ! index(2) : reference temperature level
     734             :     real(wp), dimension(:,:,:), intent(in) :: k ! (g-point, eta, temp)
     735             :     integer,                    intent(in) :: gptS, gptE, jtemp ! interpolation index for temperature
     736             :     integer, dimension(2),      intent(in) :: jeta ! interpolation index for binary species parameter (eta)
     737             :     real(wp), dimension(gptE-gptS+1)       :: res ! the result
     738             : 
     739             :     ! Local variable
     740             :     integer :: igpt
     741             :     ! each code block is for a different reference temperature
     742             : 
     743 >53856*10^7 :     do igpt = 1, gptE-gptS+1
     744 >19241*10^8 :       res(igpt) = fminor(1,1) * k(jtemp  , jeta(1)  , gptS+igpt-1) + &
     745 >48104*10^7 :                   fminor(2,1) * k(jtemp  , jeta(1)+1, gptS+igpt-1) + &
     746 >96209*10^7 :                   fminor(1,2) * k(jtemp+1, jeta(2)  , gptS+igpt-1) + &
     747 >39059*10^8 :                   fminor(2,2) * k(jtemp+1, jeta(2)+1, gptS+igpt-1)
     748             :     end do
     749             : 
     750 57515305080 :   end function interpolate2D_byflav
     751             :   ! ----------------------------------------------------------
     752 42938391600 :   pure function interpolate3D_byflav(scaling, fmajor, k, gptS, gptE, jeta, jtemp, jpress) result(res)
     753             :     real(wp), dimension(2),     intent(in) :: scaling
     754             :     real(wp), dimension(2,2,2), intent(in) :: fmajor ! interpolation fractions for major species
     755             :                                                      ! index(1) : reference eta level (temperature dependent)
     756             :                                                      ! index(2) : reference pressure level
     757             :                                                      ! index(3) : reference temperature level
     758             :     real(wp), dimension(:,:,:,:),intent(in) :: k ! (temp,eta,press,gpt)
     759             :     integer,                     intent(in) :: gptS, gptE
     760             :     integer, dimension(2),       intent(in) :: jeta ! interpolation index for binary species parameter (eta)
     761             :     integer,                     intent(in) :: jtemp ! interpolation index for temperature
     762             :     integer,                     intent(in) :: jpress ! interpolation index for pressure
     763             :     real(wp), dimension(gptS:gptE)          :: res ! the result
     764             : 
     765             :     ! Local variable
     766             :     integer :: igpt
     767             :     ! each code block is for a different reference temperature
     768 >38644*10^7 :     do igpt = gptS, gptE
     769 >34350*10^7 :       res(igpt) =  &
     770             :         scaling(1) * &
     771 >13740*10^8 :         ( fmajor(1,1,1) * k(jtemp, jeta(1)  , jpress-1, igpt) + &
     772 >34350*10^7 :           fmajor(2,1,1) * k(jtemp, jeta(1)+1, jpress-1, igpt) + &
     773 >34350*10^7 :           fmajor(1,2,1) * k(jtemp, jeta(1)  , jpress  , igpt) + &
     774             :           fmajor(2,2,1) * k(jtemp, jeta(1)+1, jpress  , igpt) ) + &
     775             :         scaling(2) * &
     776 >68701*10^7 :         ( fmajor(1,1,2) * k(jtemp+1, jeta(2)  , jpress-1, igpt) + &
     777 >34350*10^7 :           fmajor(2,1,2) * k(jtemp+1, jeta(2)+1, jpress-1, igpt) + &
     778             :           fmajor(1,2,2) * k(jtemp+1, jeta(2)  , jpress  , igpt) + &
     779 >34780*10^8 :           fmajor(2,2,2) * k(jtemp+1, jeta(2)+1, jpress  , igpt) )
     780             :     end do
     781 42938391600 :   end function interpolate3D_byflav
     782             : 
     783             : end module mo_gas_optics_rrtmgp_kernels

Generated by: LCOV version 1.14