!!!!!  ==============================================================  !!!!!
!!!!!               lw-rrtm3 radiation package description             !!!!!
!!!!!  ==============================================================  !!!!!
!                                                                          !
!   this package includes ncep's modifications of the rrtm-lw radiation    !
!   code from aer inc.                                                     !
!                                                                          !
!    the lw-rrtm3 package includes these parts:                            !
!                                                                          !
!       'radlw_rrtm3_param.f'                                              !
!       'radlw_rrtm3_datatb.f'                                             !
!       'radlw_rrtm3_main.f'                                               !
!                                                                          !
!    the 'radlw_rrtm3_param.f' contains:                                   !
!                                                                          !
!       'module_radlw_cntr_para'   -- control parameters set up            !
!       'module_radlw_parameters'  -- band parameters set up               !
!                                                                          !
!    the 'radlw_rrtm3_datatb.f' contains:                                  !
!                                                                          !
!       'module_radlw_avplank'     -- plank flux data                      !
!       'module_radlw_ref'         -- reference temperature and pressure   !
!       'module_radlw_cldprlw'     -- cloud property coefficients          !
!       'module_radlw_kgbnn'       -- absorption coeffients for 16         !
!                                     bands, where nn = 01-16              !
!                                                                          !
!    the 'radlw_rrtm3_main.f' contains:                                    !
!                                                                          !
!       'module_radlw_main'        -- main lw radiation transfer           !
!                                                                          !
!    in the main module 'module_radlw_main' there are only two             !
!    externally callable subroutines:                                      !
!                                                                          !
!                                                                          !
!       'lwrad'     -- main lw radiation routine                           !
!          inputs:                                                         !
!           (play,plev,tlay,tlev,qnm,o3mr,gasvmr,                          !
!            clouds,icseed,aerosols,sfemis,sfgtmp,                         !
!            npts, nlay, nlp1, iflip, lprnt,                               !
!          outputs:                                                        !
!            hlwc,topflx,sfcflx,                                           !
!!         optional outputs:                                               !
!            HLW0,HLWB,FLXPRF)                                             !
!                                                                          !
!       'rlwinit'   -- initialization routine                              !
!          inputs:                                                         !
!           ( icwp, me, nlay, iovr, isubc )                                !
!          outputs:                                                        !
!           (none)                                                         !
!                                                                          !
!    all the lw radiation subprograms become contained subprograms         !
!    in module 'module_radlw_main' and many of them are not directly       !
!    accessable from places outside the module.                            !
!                                                                          !
!    derived data type constructs used:                                    !
!                                                                          !
!     1. radiation flux at toa: (from module 'module_radlw_parameters')    !
!          topflw_type   -  derived data type for toa rad fluxes           !
!            upfxc              total sky upward flux at toa               !
!            upfx0              clear sky upward flux at toa               !
!                                                                          !
!     2. radiation flux at sfc: (from module 'module_radlw_parameters')    !
!          sfcflw_type   -  derived data type for sfc rad fluxes           !
!            upfxc              total sky upward flux at sfc               !
!            upfx0              clear sky upward flux at sfc               !
!            dnfxc              total sky downward flux at sfc             !
!            dnfx0              clear sky downward flux at sfc             !
!                                                                          !
!     3. radiation flux profiles(from module 'module_radlw_parameters')    !
!          proflw_type    -  derived data type for rad vertical prof       !
!            upfxc              level upward flux for total sky            !
!            dnfxc              level downward flux for total sky          !
!            upfx0              level upward flux for clear sky            !
!            dnfx0              level downward flux for clear sky          !
!                                                                          !
!    external modules referenced:                                          !
!                                                                          !
!       'module machine'                                                   !
!       'module physcons'                                                  !
!       'mersenne_twister'                                                 !
!                                                                          !
!    compilation sequence is:                                              !
!                                                                          !
!       'radlw_rrtm3_param.f'                                              !
!       'radlw_rrtm3_datatb.f'                                             !
!       'radlw_rrtm3_main.f'                                               !
!                                                                          !
!    and all should be put in front of routines that use lw modules        !
!                                                                          !
!==========================================================================!
!                                                                          !
!    the original aer's program declarations:                              !
!                                                                          !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!                                                                          |
!  Copyright 2002-2007, Atmospheric & Environmental Research, Inc. (AER).  |
!  This software may be used, copied, or redistributed as long as it is    |
!  not sold and this copyright notice is reproduced on each copy made.     |
!  This model is provided as is without any express or implied warranties. |
!                       (http://www.rtweb.aer.com/)                        |
!                                                                          |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!                                                                          !
! ************************************************************************ !
!                                                                          !
!                              rrtmg_lw                                    !
!                                                                          !
!                                                                          !
!                   a rapid radiative transfer model                       !
!                       for the longwave region                            ! 
!             for application to general circulation models                !
!                                                                          !
!                                                                          !
!            atmospheric and environmental research, inc.                  !
!                        131 hartwell avenue                               !
!                        lexington, ma 02421                               !
!                                                                          !
!                           eli j. mlawer                                  !
!                        jennifer s. delamere                              !
!                         michael j. iacono                                !
!                         shepard a. clough                                !
!                                                                          !
!                                                                          !
!                       email:  miacono@aer.com                            !
!                       email:  emlawer@aer.com                            !
!                       email:  jdelamer@aer.com                           !
!                                                                          !
!        the authors wish to acknowledge the contributions of the          !
!        following people:  steven j. taubman, karen cady-pereira,         !
!        patrick d. brown, ronald e. farren, luke chen, robert bergstrom.  !
!                                                                          !
! ************************************************************************ !
!                                                                          !
!    references:                                                           !
!    (rrtm_lw/rrtmg_lw):                                                   !
!      clough, s.A., m.w. shephard, e.j. mlawer, j.s. delamere,            !
!      m.j. iacono, k. cady-pereira, s. boukabara, and p.d. brown:         !
!      atmospheric radiative transfer modeling: a summary of the aer       !
!      codes, j. quant. spectrosc. radiat. transfer, 91, 233-244, 2005.    !
!                                                                          !
!      mlawer, e.j., s.j. taubman, p.d. brown, m.j. iacono, and s.a.       !
!      clough:  radiative transfer for inhomogeneous atmospheres: rrtm,    !
!      a validated correlated-k model for the longwave.  j. geophys. res., !
!      102, 16663-16682, 1997.                                             !
!                                                                          !
!    (mcica):                                                              !
!      pincus, r., h. w. barker, and j.-j. morcrette: a fast, flexible,    !
!      approximation technique for computing radiative transfer in         !
!      inhomogeneous cloud fields, j. geophys. res., 108(d13), 4376,       !
!      doi:10.1029/2002JD003322, 2003.                                     !
!                                                                          !
! ************************************************************************ !
!                                                                          !
!    aer's revision history:                                               !
!     this version of rrtmg_lw has been modified from rrtm_lw to use a     !
!     reduced set of g-points for application to gcms.                     !
!                                                                          !
! --  original version (derived from rrtm_lw), reduction of g-points,      !
!     other revisions for use with gcms.                                   !
!        1999: m. j. iacono, aer, inc.                                     !
! --  adapted for use with ncar/cam3.                                      !
!        may 2004: m. j. iacono, aer, inc.                                 !
! --  revised to add mcica capability.                                     !
!        nov 2005: m. j. iacono, aer, inc.                                 !
! --  conversion to f90 formatting for consistency with rrtmg_sw.          !
!        feb 2007: m. j. iacono, aer, inc.                                 !
! --  modifications to formatting to use assumed-shape arrays.             !
!        aug 2007: m. j. iacono, aer, inc.                                 !
!                                                                          !
! ************************************************************************ !
!                                                                          !
!    ncep modifications history log:                                       !
!                                                                          !
!       nov 1999,  ken campana       -- received the original code from    !
!                    aer (1998 ncar ccm version), updated to link up with  !
!                    ncep mrf model                                        !
!       jun 2000,  ken campana       -- added option to switch random and  !
!                    maximum/random cloud overlap                          !
!           2001,  shrinivas moorthi -- further updates for mrf model      !
!       may 2001,  yu-tai hou        -- updated on trace gases and cloud   !
!                    property based on rrtm_v3.0 codes.                    !
!       dec 2001,  yu-tai hou        -- rewritten code into fortran 90 std !
!                    set ncep radiation structure standard that contains   !
!                    three plug-in compatable fortran program files:       !
!                    'radlw_param.f', 'radlw_datatb.f', 'radlw_main.f'     !
!                    fixed bugs in subprograms taugb14, taugb2, etc. added !
!                    out-of-bounds protections. (a detailed note of        !
!                    up_to_date modifications/corrections by ncep was sent !
!                    to aer in 2002)                                       !
!       jun 2004,  yu-tai hou        -- added mike iacono's apr 2004       !
!                    modification of variable diffusivity angles.          !
!       apr 2005,  yu-tai hou        -- minor modifications on module      !
!                    structures include rain/snow effect (this version of  !
!                    code was given back to aer in jun 2006)               !
!       mar 2007,  yu-tai hou        -- added aerosol effect for ncep      !
!                    models using the generallized aerosol optical property!
!                    scheme for gfs model.                                 !
!       apr 2007,  yu-tai hou        -- added spectral band heating as an  !
!                    optional output to support the 500 km gfs model's     !
!                    upper stratospheric radiation calculations. and       !
!                    restructure optional outputs for easy access by       !
!                    different models.                                     !
!       oct 2008,  yu-tai hou        -- modified to include new features   !
!                    from aer's newer release v4.4-v4.7, including the     !
!                    mcica sub-grid cloud option. add rain/snow optical    !
!                    properties support to cloudy sky calculations.        !
!                    correct errors in mcica cloud optical properties for  !
!                    ebert & curry scheme (iflagice=1) that needs band     !
!                    index conversion. simplified and unified sw and lw    !
!                    sub-column cloud subroutines into one module by using !
!                    optional parameters.                                  !
!       mar 2009,  yu-tai hou        -- replaced the original random number!
!                    generator coming from the original code with ncep w3  !
!                    library to simplify the program and moved sub-column  !
!                    cloud subroutines inside the main module. added       !
!                    option of user provided permutation seeds that could  !
!                    be randomly generated from forecast time stamp.       !
!       oct 2009,  yu-tai hou        -- modified subrtines "cldprop" and   !
!                    "rlwinit" according updats from aer's rrtmg_lw v4.8.  !
!       nov 2009,  yu-tai hou        -- modified subrtine "taumol" according
!                    updats from aer's rrtmg_lw version 4.82. notice the   !
!                    cloud ice/liquid are assumed as in-cloud quantities,  !
!                    not as grid averaged quantities.                      !
!                                                                          !
!!!!!  ==============================================================  !!!!!
!!!!!                         end descriptions                         !!!!!
!!!!!  ==============================================================  !!!!!


!========================================!
      module module_radlw_main           !
!........................................!
!
      use machine,          only : kind_phys
      use physcons,         only : con_g, con_cp, con_avgd, con_amd,    &
     &                             con_amw, con_amo3
      use mersenne_twister, only : random_setseed, random_number,       &
     &                             random_stat

      use module_radlw_parameters
      use module_radlw_cntr_para
!
      use module_radlw_avplank,          only : totplnk
      use module_radlw_ref,              only : preflog, tref, chi_mls
!
      implicit none
!
      private
!
!  ...  version tag and last revision date
!     character(24), parameter :: VTAGLW='RRTM-LW v2.3g   Apr 2004'
!     character(24), parameter :: VTAGLW='RRTM-LW v2.3g   Mar 2007'
!     character(24), parameter :: VTAGLW='RRTMG-LW v4.4   Oct 2008'
!     character(24), parameter :: VTAGLW='RRTMG-LW v4.71  Mar 2009'
!     character(24), parameter :: VTAGLW='RRTMG-LW v4.8   Oct 2009'
      character(24), parameter :: VTAGLW='RRTMG-LW v4.82  Nov 2009'

!  ---  constant values
      real (kind=kind_phys), parameter :: eps     = 1.0e-6
      real (kind=kind_phys), parameter :: oneminus= 1.0-eps
!     real (kind=kind_phys), parameter :: cldmin  = 1.0e-80
      real (kind=kind_phys), parameter :: cldmin  = 1.0e-08
      real (kind=kind_phys), parameter :: bpade   = 1.0/0.278  ! pade approx constant
      real (kind=kind_phys), parameter :: stpfac  = 296.0/1013.0
      real (kind=kind_phys), parameter :: wtdiff  = 0.5        ! weight for radiance to flux conversion
      real (kind=kind_phys), parameter :: tblint  = ntbl       ! lookup table conversion factor
      real (kind=kind_phys), parameter :: f_zero  = 0.0
      real (kind=kind_phys), parameter :: f_one   = 1.0

!  ...  atomic weights for conversion from mass to volume mixing ratios
      real (kind=kind_phys), parameter :: amdw    = con_amd/con_amw
      real (kind=kind_phys), parameter :: amdo3   = con_amd/con_amo3

!  ...  band indices
      integer, dimension(nbands) :: nspa, nspb

      data nspa / 1, 1, 9, 9, 9, 1, 9, 1, 9, 1, 1, 9, 9, 1, 9, 9 /
      data nspb / 1, 1, 5, 5, 5, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0 /

!  ...  band wavenumber intervals
!     real (kind=kind_phys) :: wavenum1(nbands), wavenum2(nbands)
!     data wavenum1/                                                    &
!    &         10.,  350.,  500.,  630.,  700.,  820.,  980., 1080.,    &
!err &       1180., 1390., 1480., 1800., 2080., 2250., 2390., 2600. /
!    &       1180., 1390., 1480., 1800., 2080., 2250., 2380., 2600. /
!     data wavenum2/                                                    &
!    &        350.,  500.,  630.,  700.,  820.,  980., 1080., 1180.,    &
!err &       1390., 1480., 1800., 2080., 2250., 2390., 2600., 3250. /
!    &       1390., 1480., 1800., 2080., 2250., 2380., 2600., 3250. /
      real (kind=kind_phys) :: delwave(nbands)
      data delwave / 340., 150., 130.,  70., 120., 160., 100., 100.,    &
     &               210.,  90., 320., 280., 170., 130., 220., 650. /

!  ---  reset diffusivity angle for Bands 2-3 and 5-9 to vary (between 1.50
!       and 1.80) as a function of total column water vapor.  the function
!       has been defined to minimize flux and cooling rate errors in these bands
!       over a wide range of precipitable water values.
      real (kind=kind_phys), dimension(nbands) :: a0, a1, a2

      data a0 / 1.66,  1.55,  1.58,  1.66,  1.54, 1.454,  1.89,  1.33,  &
     &         1.668,  1.66,  1.66,  1.66,  1.66,  1.66,  1.66,  1.66 /
      data a1 / 0.00,  0.25,  0.22,  0.00,  0.13, 0.446, -0.10,  0.40,  &
     &        -0.006,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00 /
      data a2 / 0.00, -12.0, -11.7,  0.00, -0.72,-0.243,  0.19,-0.062,  &
     &         0.414,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00,  0.00 /

!! ---  logical flags for optional output fields

      logical :: lhlwb  = .false.
      logical :: lhlw0  = .false.
      logical :: lflxprf= .false.

!  ---  those data will be set up only once by "rlwinit"

!  ...  fluxfac, heatfac are factors for fluxes (in w/m**2) and heating
!       rates (in k/day, or k/sec set by subroutine 'rlwinit')
!       semiss0 are default surface emissivity for each bands

      real (kind=kind_phys) :: fluxfac, heatfac, semiss0(nbands)

      real (kind=kind_phys) :: tau_tbl(0:ntbl)  !clr-sky opt dep (for cldy transfer)
      real (kind=kind_phys) :: exp_tbl(0:ntbl)  !transmittance lookup table
      real (kind=kind_phys) :: tfn_tbl(0:ntbl)  !tau transition function; i.e. the
                                                !transition of planck func from mean lyr
                                                !temp to lyr boundary temp as a func of
                                                !opt dep. "linear in tau" method is used.

!  ...  iovrlw  is the clouds overlapping control flag
!            =0: random overlapping clouds
!            =1: maximum/random overlapping clouds
!            =2: maximum overlap cloud (isubcol>0 only)

      integer :: iovrlw

!  ---  the following variables are used for sub-column cloud scheme

      integer, parameter :: ipsdlw0 = ngptlw     ! initial permutation seed
      integer, parameter :: isdlim  = 1.0e+9     ! limit for random seed

!  ...  isubcol is the sub-column cloud approximation control flag
!        =0: no sub-col cloud treatment, use grid-mean cloud quantities
!        =1: mcica sub-col, prescribed seeds for generating random numbers
!        =2: mcica sub-col, use array icseed that contains user provided
!            permutation seeds for generating random numbers
!  ...  ipsdlw is the permutation seed for sub-column clouds scheme (isubcol=1)

      integer :: isubcol, ipsdlw

!  ---  public accessable subprograms

      public lwrad, rlwinit


! ================
      contains
! ================


! --------------------------------
      subroutine lwrad                                                  &
! --------------------------------

!  ---  inputs:
     &     ( play,plev,tlay,tlev,qnm,o3mr,gasvmr,                       &
     &       clouds,icseed,aerosols,sfemis,sfgtmp,                      &
     &       npts, nlay, nlp1, iflip, lprnt,                            &
!  ---  outputs:
     &       hlwc,topflx,sfcflx                                         &
!! ---  optional:
     &,      HLW0,HLWB,FLXPRF                                           &
     &     )

!  ====================  defination of variables  ====================  !
!                                                                       !
!  input variables:                                                     !
!     play (npts,nlay) : layer mean pressures (mb)                      !
!     plev (npts,nlp1) : interface pressures (mb)                       !
!     tlay (npts,nlay) : layer mean temperature (k)                     !
!     tlev (npts,nlp1) : interface temperatures (k)                     !
!     qnm  (npts,nlay) : layer specific humidity (gm/gm)   *see inside  !
!     o3mr (npts,nlay) : layer ozone concentration (gm/gm) *see inside  !
!     gasvmr(npts,nlay,:): atmospheric gases amount:                    !
!                       (check module_radiation_gases for definition)   !
!       gasvmr(:,:,1)  -   co2 volume mixing ratio                      !
!       gasvmr(:,:,2)  -   n2o volume mixing ratio                      !
!       gasvmr(:,:,3)  -   ch4 volume mixing ratio                      !
!       gasvmr(:,:,4)  -   o2  volume mixing ratio                      !
!       gasvmr(:,:,5)  -   co  volume mixing ratio                      !
!       gasvmr(:,:,6)  -   cfc11 volume mixing ratio                    !
!       gasvmr(:,:,7)  -   cfc12 volume mixing ratio                    !
!       gasvmr(:,:,8)  -   cfc22 volume mixing ratio                    !
!       gasvmr(:,:,9)  -   ccl4  volume mixing ratio                    !
!     clouds(npts,nlay,:): layer cloud profiles:                        !
!                       (check module_radiation_clouds for definition)  !
!                ---  for  iflagliq > 0  ---                            !
!       clouds(:,:,1)  -   layer total cloud fraction                   !
!       clouds(:,:,2)  -   layer in-cloud liq water path   (g/m**2)     !
!       clouds(:,:,3)  -   mean eff radius for liq cloud   (micron)     !
!       clouds(:,:,4)  -   layer in-cloud ice water path   (g/m**2)     !
!       clouds(:,:,5)  -   mean eff radius for ice cloud   (micron)     !
!       clouds(:,:,6)  -   layer rain drop water path      (g/m**2)     !
!       clouds(:,:,7)  -   mean eff radius for rain drop   (micron)     !
!       clouds(:,:,8)  -   layer snow flake water path     (g/m**2)     !
!   ** fu's scheme need to be normalized by snow density (g/m**3/1.0e6) !
!       clouds(:,:,9)  -   mean eff radius for snow flake  (micron)     !
!                ---  for  iflagliq = 0  ---                            !
!       clouds(:,:,1)  -   layer total cloud fraction                   !
!       clouds(:,:,2)  -   layer cloud optical depth                    !
!       clouds(:,:,3)  -   layer cloud single scattering albedo         !
!       clouds(:,:,4)  -   layer cloud asymmetry factor                 !
!     icseed(npts)   : auxiliary special cloud related array            !
!                      when module variable isubcol=2, it provides      !
!                      permutation seed for each column profile that    !
!                      are used for generating random numbers.          !
!                      when isubcol /=2, it will not be used.           !
!     aerosols(npts,nlay,nbands,:) : aerosol optical properties         !
!                       (check module_radiation_aerosols for definition)!
!        (:,:,:,1)     - optical depth                                  !
!        (:,:,:,2)     - single scattering albedo                       !
!        (:,:,:,3)     - asymmetry parameter                            !
!     sfemis (npts)  : surface emissivity                               !
!     sfgtmp (npts)  : surface ground temperature (k)                   !
!     npts           : total number of horizontal points                !
!     nlay, nlp1     : total number of vertical layers, levels          !
!     iflip          : control flag for in/out vertical index           !
!                      =0: vertical index from toa to surface           !
!                      =1: vertical index from surface to toa           !
!     lprnt          : cntl flag for diagnostic print out               !
!                                                                       !
!  control parameters in module "module_radlw_cntr_para":               !
!     ilwrate        : heating rate unit selections                     !
!                      =1: output in k/day                              !
!                      =2: output in k/second                           !
!     iaerlw         : control flag for aerosols                        !
!                      =0: do not include aerosol effect                !
!                      >0: include aerosol effect                       !
!     irgaslw        : control flag for rare gases (ch4,n2o,o2,co, etc.)!
!                      =0: do not include rare gases                    !
!                      =1: include all rare gases                       !
!     icfclw         : control flag for cfc gases                       !
!                      =0: do not include cfc gases                     !
!                      =1: include all cfc gases                        !
!     iflagliq       : liq-cloud optical properties contrl flag         !
!                      =0: input cld opt dep, ignor iflagice            !
!                      =1: input cld liqp & reliq, hu & stamnes (1993)  !
!     iflagice       : ice-cloud optical properties contrl flag         !
!                       * * * if iflagliq == 0, iflafice is ignored     !
!                      =1: input cld icep & reice, ebert & curry (1997) !
!                      =2: input cld icep & reice, streamer (1996)      !
!                      =3: input cld icep & reice, fu (1998)            !
!                                                                       !
!  output variables:                                                    !
!     hlwc  (npts,nlay): total sky heating rate (k/day or k/sec)        !
!     topflx(npts)     : radiation fluxes at top, component:            !
!                        (check module_radlw_paramters for definition)  !
!        upfxc           - total sky upward flux at top (w/m2)          !
!        upfx0           - clear sky upward flux at top (w/m2)          !
!     sfcflx(npts)     : radiation fluxes at sfc, component:            !
!                        (check module_radlw_paramters for definition)  !
!        upfxc           - total sky upward flux at sfc (w/m2)          !
!        upfx0           - clear sky upward flux at sfc (w/m2)          !
!        dnfxc           - total sky downward flux at sfc (w/m2)        !
!        dnfx0           - clear sky downward flux at sfc (w/m2)        !
!                                                                       !
!! optional output variables:                                           !
!     hlwb(npts,nlay,nbands): spectral band total sky heating rates     !
!     hlw0  (npts,nlay): clear sky heating rate (k/day or k/sec)        !
!     flxprf(npts,nlp1): level radiative fluxes (w/m2), components:     !
!                        (check module_radlw_paramters for definition)  !
!        upfxc           - total sky upward flux                        !
!        dnfxc           - total sky dnward flux                        !
!        upfx0           - clear sky upward flux                        !
!        dnfx0           - clear sky dnward flux                        !
!                                                                       !
!  module parameters, control variables:                                !
!     nbands           - number of longwave spectral bands              !
!     maxgas           - maximum number of absorbing gaseous            !
!     maxxsec          - maximum number of cross-sections               !
!     ngptlw           - total number of g-point subintervals           !
!     ng##             - number of g-points in band (##=1-16)           !
!     ngb(ngptlw)      - band indices for each g-point                  !
!     bpade            - pade approximation constant (1/0.278)          !
!     nspa,nspb(nbands)- number of lower/upper ref atm's per band       !
!     delwave(nbands)  - longwave band width (wavenumbers)              !
!     iovrlw           - cloud overlapping control flag                 !
!            =0: random overlapping clouds                              !
!            =1: maximum/random overlapping clouds                      !
!            =2: maximum overlap cloud (used for isubcol>0 only)        !
!     ipsdlw           - permutation seed for mcica sub-col clds        !
!     isubcol          - sub-column cloud apprx control flag setup in   !
!                        subroutine 'rlwinit'                           !
!            =0: no sub-col cloud treatment, use grid-mean cloud        !
!            =1: mcica sub-col, prescribed seed for random number       !
!            =2: mcica sub-col, use array icseed that contains user     !
!                provided permutation seed for generating random numbers!
!                                                                       !
!  major local variables:                                               !
!     pavel  (nlay)         - layer pressures (mb)                      !
!     delp   (nlay)         - layer pressure thickness (mb)             !
!     tavel  (nlay)         - layer temperatures (k)                    !
!     tz     (0:nlay)       - level (interface) temperatures (k)        !
!     semiss (nbands)       - surface emissivity for each band          !
!     wx     (nlay,maxxsec) - cross-section molecules concentration     !
!     coldry (nlay)         - dry air column amount                     !
!                                   (1.e-20*molecules/cm**2)            !
!     cldfrc (0:nlp1)       - layer cloud fraction                      !
!     taucmc (nlay,ngptlw)  - layer cloud optical depth for each g-point!
!     cldfmc (nlay,ngptlw)  - layer cloud fraction for each g-point     !
!     tauaer (nlay,nbands)  - aerosol optical depths                    !
!     fracs  (nlay,ngptlw)  - planck fractions                          !
!     tautot (nlay,ngptlw)  - total optical depths (gaseous+aerosols)   !
!     colamt (nlay,maxgas)  - column amounts of absorbing gases         !
!                             1-maxgas are for watervapor, carbon       !
!                             dioxide, ozone, nitrous oxide, methane,   !
!                             oxigen, carbon monoxide, respectively     !
!                             (molecules/cm**2)                         !
!     pwvcm                 - column precipitable water vapor (cm)      !
!     secdiff(nbands)       - variable diffusivity angle defined as     !
!                             an exponential function of the column     !
!                             water amount in bands 2-3 and 5-9.        !
!                             this reduces the bias of several w/m2 in  !
!                             downward surface flux in high water       !
!                             profiles caused by using the constant     !
!                             diffusivity angle of 1.66.         (mji)  !
!     facij  (nlay)         - indicator of interpolation factors        !
!                             =0/1: indicate lower/higher temp & height !
!     selffac(nlay)         - scale factor for self-continuum, equals   !
!                          (w.v. density)/(atm density at 296K,1013 mb) !
!     selffrac(nlay)        - factor for temp interpolation of ref      !
!                             self-continuum data                       !
!     indself(nlay)         - index of the lower two appropriate ref    !
!                             temp for the self-continuum interpolation !
!     forfac (nlay)         - scale factor for w.v. foreign-continuum   !
!     forfrac(nlay)         - factor for temp interpolation of ref      !
!                             w.v. foreign-continuum data               !
!     indfor (nlay)         - index of the lower two appropriate ref    !
!                             temp for the foreign-continuum interp     !
!     laytrop               - tropopause layer index at which switch is !
!                             made from one conbination kew species to  !
!                             another.                                  !
!     jp(nlay),jt(nlay),jt1(nlay)                                       !
!                           - lookup table indexes                      !
!     totuflux(0:nlay)      - total-sky upward longwave flux (w/m2)     !
!     totdflux(0:nlay)      - total-sky downward longwave flux (w/m2)   !
!     htr(nlay)             - total-sky heating rate (k/day or k/sec)   !
!     totuclfl(0:nlay)      - clear-sky upward longwave flux (w/m2)     !
!     totdclfl(0:nlay)      - clear-sky downward longwave flux (w/m2)   !
!     htrcl(nlay)           - clear-sky heating rate (k/day or k/sec)   !
!     fnet    (0:nlay)      - net longwave flux (w/m2)                  !
!     fnetc   (0:nlay)      - clear-sky net longwave flux (w/m2)        !
!                                                                       !
!                                                                       !
!  ======================    end of definitions    ===================  !

!  ---  inputs:
      integer, intent(in) :: npts, nlay, nlp1, iflip, icseed(:)

      logical,  intent(in) :: lprnt

      real (kind=kind_phys), dimension(:,:), intent(in) :: plev, tlev,  &
     &       play, tlay, qnm, o3mr

      real (kind=kind_phys), dimension(:,:,:),intent(in) :: gasvmr,     &
     &       clouds

      real (kind=kind_phys), dimension(:),    intent(in) :: sfemis,     &
     &       sfgtmp

      real (kind=kind_phys), dimension(:,:,:,:),intent(in) :: aerosols

!  ---  outputs:
      real (kind=kind_phys), dimension(:,:), intent(out) :: hlwc

      type (topflw_type),    dimension(:),   intent(out) :: topflx
      type (sfcflw_type),    dimension(:),   intent(out) :: sfcflx

!! ---  optional outputs:
      real (kind=kind_phys),dimension(:,:,:),optional,intent(out):: hlwb
      real (kind=kind_phys),dimension(:,:),optional,intent(out):: hlw0
      type (proflw_type),   dimension(:,:),optional,intent(out):: flxprf

!  ---  locals:
      real (kind=kind_phys), dimension(0:nlp1) :: cldfrc

      real (kind=kind_phys), dimension(0:nlay) :: totuflux, totdflux,   &
     &       totuclfl, totdclfl, tz

      real (kind=kind_phys), dimension(nlay)   :: htr, htrcl

      real (kind=kind_phys), dimension(nlay)   :: pavel, tavel, delp,   &
     &       clwp, ciwp, relw, reiw, cda1, cda2, cda3, cda4,            &
     &       coldry, colbrd, h2ovmr, o3vmr, fac00, fac01, fac10, fac11, &
     &       selffac, selffrac, forfac, forfrac, minorfrac, scaleminor, &
     &       scaleminorn2, temcol

      real (kind=kind_phys), dimension(nlay,ngptlw) :: fracs, tautot,   &
     &       taucmc, cldfmc

      real (kind=kind_phys), dimension(0:nlay,nbands) :: pklev

      real (kind=kind_phys), dimension(nlay,nbands)   :: pklay,         &
     &       tauaer, htrb

      real (kind=kind_phys), dimension(nbands)        :: pkbnd,         &
     &       semiss, secdiff

!  ---  column amount of absorbing gases:
!       (:,m) m = 1-h2o, 2-co2, 3-o3, 4-n2o, 5-ch4, 6-o2, 7-co
      real (kind=kind_phys) :: colamt(nlay,maxgas)

!  ---  column cfc cross-section amounts:
!       (:,m) m = 1-ccl4, 2-cfc11, 3-cfc12, 4-cfc22
      real (kind=kind_phys) :: wx(nlay,maxxsec)

!  ---  reference ratios of binary species parameter in lower atmosphere:
!       (:,m,:) m = 1-h2o/co2, 2-h2o/o3, 3-h2o/n2o, 4-h2o/ch4, 5-n2o/co2, 6-o3/co2
      real (kind=kind_phys) :: rfrate(nlay,nrates,2)

      real (kind=kind_phys) :: fp, ft, ft1, tem0, tem1, tem2, pwvcm,    &
     &       summol, tlayfr, tlevfr, plog, stemp, tsfcfr

      integer, dimension(npts) :: ipseed
      integer, dimension(nlay) :: jp, jt, jt1, indself, indfor, indminor
      integer                  :: laytrop, jp1, indlay, indlev, indsfc, &
     &                            iplon, i, j, k, k1
      logical :: lcf1

!
!===> ... begin here
!

!  --- ...  initialization

      lhlwb  = present ( hlwb )
      lhlw0  = present ( hlw0 )
      lflxprf= present ( flxprf )
 
      colamt(:,:) = f_zero

!  --- ...  change random number seed value for each radiation invocation

      if     ( isubcol == 1 ) then     ! advance prescribed permutation seed
        do i = 1, npts
          ipseed(i) = ipsdlw + i
        enddo
        ipsdlw = mod( ipsdlw+npts, isdlim )
      elseif ( isubcol == 2 ) then     ! use input array of permutaion seeds
        do i = 1, npts
          ipseed(i) = icseed(i)
        enddo
      endif

!     if ( lprnt ) then
!       print *,'  In radlw, isubcol, ipsdlw,ipseed =',                 &
!    &          isubcol, ipsdlw, ipseed
!     endif

!  --- ...  loop over horizontal npts profiles
 
      lab_do_iplon : do iplon = 1, npts

        if (sfemis(iplon) > eps .and. sfemis(iplon) <= 1.0) then  ! input surface emissivity
          do j = 1, nbands
            semiss(j) = sfemis(iplon)
          enddo
        else                                                      ! use default values
          do j = 1, nbands
            semiss(j) = semiss0(j)
          enddo
        endif

        stemp = sfgtmp(iplon)          ! surface ground temp

!  --- ...  prepare atmospheric profile for use in rrtm
!           the vertical index of internal array is from surface to top

!  --- ...  molecular amounts are input or converted to volume mixing ratio
!           and later then converted to molecular amount (molec/cm2) by the
!           dry air column coldry (in molec/cm2) which is calculated from the
!           layer pressure thickness (in mb), based on the hydrostatic equation
!  --- ...  and includes a correction to account for h2o in the layer.

        if (iflip == 0) then        ! input from toa to sfc

          tem1 = 100.0 * con_g
          tem2 = 1.0e-20 * 1.0e3 * con_avgd
          tz(0) = tlev(iplon,nlp1)

          do k = 1, nlay
            k1 = nlp1 - k
            pavel(k)= play(iplon,k1)
            delp(k) = plev(iplon,k1+1) - plev(iplon,k1)
            tavel(k)= tlay(iplon,k1)
            tz(k)   = tlev(iplon,k1)

!  --- ...  set absorber amount
!test use
!           h2ovmr(k)= max(f_zero,qnm(iplon,k1)*amdw)                   ! input mass mixing ratio
!           h2ovmr(k)= max(f_zero,qnm(iplon,k1))                        ! input vol mixing ratio
!           o3vmr (k)= max(f_zero,o3mr(iplon,k1))                       ! input vol mixing ratio
!ncep model use
            h2ovmr(k)= max(f_zero,qnm(iplon,k1)                         &
     &                           *amdw/(f_one-qnm(iplon,k1)))           ! input specific humidity
            o3vmr (k)= max(f_zero,o3mr(iplon,k1)*amdo3)                 ! input mass mixing ratio

!  --- ...  tem0 is the molecular weight of moist air
            tem0 = (f_one - h2ovmr(k))*con_amd + h2ovmr(k)*con_amw
            coldry(k) = tem2*delp(k) / (tem1*tem0*(f_one+h2ovmr(k)))
            temcol(k) = 1.0e-12 * coldry(k)

            colamt(k,1) = max(f_zero,    coldry(k)*h2ovmr(k))          ! h2o
            colamt(k,2) = max(temcol(k), coldry(k)*gasvmr(iplon,k1,1)) ! co2
            colamt(k,3) = max(temcol(k), coldry(k)*o3vmr(k))           ! o3
          enddo

!  --- ...  set up col amount for rare gases, convert from volume mixing ratio
!           to molec/cm2 based on coldry (scaled to 1.0e-20)

          if (irgaslw == 1) then
            do k = 1, nlay
              k1 = nlp1 - k
              colamt(k,4)=max(temcol(k), coldry(k)*gasvmr(iplon,k1,2))  ! n2o
              colamt(k,5)=max(temcol(k), coldry(k)*gasvmr(iplon,k1,3))  ! ch4
              colamt(k,6)=max(f_zero,    coldry(k)*gasvmr(iplon,k1,4))  ! o2
              colamt(k,7)=max(f_zero,    coldry(k)*gasvmr(iplon,k1,5))  ! co
            enddo
          else
            do k = 1, nlay
              colamt(k,4) = f_zero     ! n2o
              colamt(k,5) = f_zero     ! ch4
              colamt(k,6) = f_zero     ! o2
              colamt(k,7) = f_zero     ! co
            enddo
          endif

          if (icfclw == 1) then
            do k = 1, nlay
              k1 = nlp1 - k
              wx(k,1) = max( f_zero, coldry(k)*gasvmr(iplon,k1,9) )   ! ccl4
              wx(k,2) = max( f_zero, coldry(k)*gasvmr(iplon,k1,6) )   ! cf11
              wx(k,3) = max( f_zero, coldry(k)*gasvmr(iplon,k1,7) )   ! cf12
              wx(k,4) = max( f_zero, coldry(k)*gasvmr(iplon,k1,8) )   ! cf22
            enddo
          else
            wx(:,:) = f_zero
          endif

!  --- ...  set aerosol optical properties

          if (iaerlw > 0) then
            do k = 1, nlay
              k1 = nlp1 - k
              do j = 1, nbands
                tauaer(k,j) = aerosols(iplon,k1,j,1)                    &
     &                      * (f_one - aerosols(iplon,k1,j,2))
              enddo
            enddo
          else
            tauaer(:,:) = f_zero
          endif

          if (iflagliq > 0) then   ! use prognostic cloud method
            do k = 1, nlay
              k1 = nlp1 - k
              cldfrc(k)= clouds(iplon,k1,1)
              clwp(k)  = clouds(iplon,k1,2)
              relw(k)  = clouds(iplon,k1,3)
              ciwp(k)  = clouds(iplon,k1,4)
              reiw(k)  = clouds(iplon,k1,5)
              cda1(k)  = clouds(iplon,k1,6)
              cda2(k)  = clouds(iplon,k1,7)
              cda3(k)  = clouds(iplon,k1,8)
              cda4(k)  = clouds(iplon,k1,9)
            enddo
          else                       ! use diagnostic cloud method
            do k = 1, nlay
              k1 = nlp1 - k
              cldfrc(k)= clouds(iplon,k1,1)
              cda1(k)  = clouds(iplon,k1,2)
            enddo
          endif                      ! end if_iflagliq

          cldfrc(0)    = f_one       ! padding value only
          cldfrc(nlp1) = f_zero      ! padding value only

!  --- ...  compute precipitable water vapor for diffusivity angle adjustments

          tem1 = f_zero
          tem2 = f_zero
          do k = 1, nlay
            tem1 = tem1 + coldry(k) + colamt(k,1)
            tem2 = tem2 + colamt(k,1)
          enddo

          tem0 = 10.0 * tem2 / (amdw * tem1 * con_g)
          pwvcm = tem0 * plev(iplon,nlp1)

        else                        ! input from sfc to toa

          tem1 = 100.0 * con_g
          tem2 = 1.0e-20 * 1.0e3 * con_avgd
          tz(0) = tlev(iplon,1)

          do k = 1, nlay
            pavel(k)= play(iplon,k)
            delp(k) = plev(iplon,k) - plev(iplon,k+1)
            tavel(k)= tlay(iplon,k)
            tz(k)   = tlev(iplon,k+1)

!  --- ...  set absorber amount
!test use
!           h2ovmr(k)= max(f_zero,qnm(iplon,k)*amdw)                    ! input mass mixing ratio
!           h2ovmr(k)= max(f_zero,qnm(iplon,k))                         ! input vol mixing ratio
!           o3vmr (k)= max(f_zero,o3mr(iplon,k))                        ! input vol mixing ratio
!ncep model use
            h2ovmr(k)= max(f_zero,qnm(iplon,k)                          &
     &                           *amdw/(f_one-qnm(iplon,k)))            ! input specific humidity
            o3vmr (k)= max(f_zero,o3mr(iplon,k)*amdo3)                  ! input mass mixing ratio

!  --- ...  tem0 is the molecular weight of moist air
            tem0 = (f_one - h2ovmr(k))*con_amd + h2ovmr(k)*con_amw
            coldry(k) = tem2*delp(k) / (tem1*tem0*(f_one+h2ovmr(k)))
            temcol(k) = 1.0e-12 * coldry(k)

            colamt(k,1) = max(f_zero,    coldry(k)*h2ovmr(k))          ! h2o
            colamt(k,2) = max(temcol(k), coldry(k)*gasvmr(iplon,k,1))  ! co2
            colamt(k,3) = max(temcol(k), coldry(k)*o3vmr(k))           ! o3
          enddo

!  --- ...  set up col amount for rare gases, convert from volume mixing ratio
!           to molec/cm2 based on coldry (scaled to 1.0e-20)

          if (irgaslw == 1) then
            do k = 1, nlay
              colamt(k,4)=max(temcol(k), coldry(k)*gasvmr(iplon,k,2))  ! n2o
              colamt(k,5)=max(temcol(k), coldry(k)*gasvmr(iplon,k,3))  ! ch4
              colamt(k,6)=max(f_zero,    coldry(k)*gasvmr(iplon,k,4))  ! o2
              colamt(k,7)=max(f_zero,    coldry(k)*gasvmr(iplon,k,5))  ! co
            enddo
          else
            do k = 1, nlay
              colamt(k,4) = f_zero     ! n2o
              colamt(k,5) = f_zero     ! ch4
              colamt(k,6) = f_zero     ! o2
              colamt(k,7) = f_zero     ! co
            enddo
          endif

          if (icfclw == 1) then
            do k = 1, nlay
              wx(k,1) = max( f_zero, coldry(k)*gasvmr(iplon,k,9) )   ! ccl4
              wx(k,2) = max( f_zero, coldry(k)*gasvmr(iplon,k,6) )   ! cf11
              wx(k,3) = max( f_zero, coldry(k)*gasvmr(iplon,k,7) )   ! cf12
              wx(k,4) = max( f_zero, coldry(k)*gasvmr(iplon,k,8) )   ! cf22
            enddo
          else
            wx(:,:) = f_zero
          endif

!  --- ...  set aerosol optical properties

          if (iaerlw > 0) then
            do j = 1, nbands
              do k = 1, nlay
                tauaer(k,j) = aerosols(iplon,k,j,1)                     &
     &                      * (f_one - aerosols(iplon,k,j,2))
              enddo
            enddo
          else
            tauaer(:,:) = f_zero
          endif

          if (iflagliq > 0) then   ! use prognostic cloud method
            do k = 1, nlay
              cldfrc(k)= clouds(iplon,k,1)
              clwp(k)  = clouds(iplon,k,2)
              relw(k)  = clouds(iplon,k,3)
              ciwp(k)  = clouds(iplon,k,4)
              reiw(k)  = clouds(iplon,k,5)
              cda1(k)  = clouds(iplon,k,6)
              cda2(k)  = clouds(iplon,k,7)
              cda3(k)  = clouds(iplon,k,8)
              cda4(k)  = clouds(iplon,k,9)
            enddo
          else                       ! use diagnostic cloud method
            do k = 1, nlay
              cldfrc(k)= clouds(iplon,k,1)
              cda1(k)  = clouds(iplon,k,2)
            enddo
          endif                      ! end if_iflagliq

          cldfrc(0)    = f_one       ! padding value only
          cldfrc(nlp1) = f_zero      ! padding value only

!  --- ...  compute precipitable water vapor for diffusivity angle adjustments

          tem1 = f_zero
          tem2 = f_zero
          do k = 1, nlay
            tem1 = tem1 + coldry(k) + colamt(k,1)
            tem2 = tem2 + colamt(k,1)
          enddo

          tem0 = 10.0 * tem2 / (amdw * tem1 * con_g)
          pwvcm = tem0 * plev(iplon,1)

        endif                       ! if_iflip

!  --- ...  compute column amount for broadening gases

        do k = 1, nlay
          summol = f_zero
          do i = 2, maxgas
            summol = summol + colamt(k,i)
          enddo
          colbrd(k) = coldry(k) - summol
        enddo

!  --- ...  compute diffusivity angle adjustments

        tem1 = 1.80
        tem2 = 1.50
        do j = 1, nbands
          if (j==1 .or. j==4 .or. j==10) then
            secdiff(j) = 1.66
          else
            secdiff(j) = min( tem1, max( tem2,                          &
     &                   a0(j)+a1(j)*exp(a2(j)*pwvcm) ))
          endif
        enddo

!     if (lprnt) then
!      print *,'  coldry',coldry
!      print *,' wx(*,1) ',(wx(k,1),k=1,NLAY)
!      print *,' wx(*,2) ',(wx(k,2),k=1,NLAY)
!      print *,' wx(*,3) ',(wx(k,3),k=1,NLAY)
!      print *,' wx(*,4) ',(wx(k,4),k=1,NLAY)
!      print *,' iplon ',iplon
!      print *,'  pavel ',pavel
!      print *,'  delp ',delp
!      print *,'  tavel ',tavel
!      print *,'  tz ',tz
!      print *,' h2ovmr ',h2ovmr
!      print *,' o3vmr ',o3vmr
!     endif

!  --- ...  for cloudy atmosphere, use cldprop to set cloud optical properties

        lcf1 = .false.
        lab_do_k0 : do k = 1, nlay
          if ( cldfrc(k) > eps ) then
            lcf1 = .true.
            exit lab_do_k0
          endif
        enddo  lab_do_k0

        call cldprop                                                    &
!  ---  inputs:
     &     ( cldfrc,clwp,relw,ciwp,reiw,cda1,cda2,cda3,cda4,            &
     &       lcf1, nlay, ipseed(iplon),                                 &
!  ---  outputs:
     &       taucmc, cldfmc                                             &
     &     )

!     if (lprnt) then
!      print *,' after cldprop'
!      print *,' clwp',clwp
!      print *,' ciwp',ciwp
!      print *,' relw',relw
!      print *,' reiw',reiw
!      print *,' taucl',cda1
!      print *,' cldfrac',cldfrc
!     endif

!  --- ...  calculate information needed by the radiative transfer routine
!           that is specific to this atmosphere, especially some of the
!           coefficients and indices needed to compute the optical depths
!           by interpolating data from stored reference atmospheres.

        indsfc = min(180, max(1, int(stemp-159.0) ))
        indlev = min(180, max(1, int(tz(0)-159.0) ))
        tsfcfr = stemp - int(stemp)
        tlevfr = tz(0) - int(tz(0))
        do i = 1, nbands
          tem1 = totplnk(indsfc+1,i) - totplnk(indsfc,i)
          tem2 = totplnk(indlev+1,i) - totplnk(indlev,i)
          pkbnd(i) = semiss(i) * (totplnk(indsfc,i) + tsfcfr*tem1)
          pklev(0,i) = totplnk(indlev,i) + tlevfr*tem2
        enddo

!  --- ...  begin layer loop
!           calculate the integrated Planck functions for each band at the
!           surface, level, and layer temperatures.

        laytrop = 0

        do k = 1, nlay

          indlay = min(180, max(1, int(tavel(k)-159.0) ))
          tlayfr = tavel(k) - int(tavel(k))

          indlev = min(180, max(1, int(tz(k)-159.0) ))
          tlevfr = tz(k) - int(tz(k))

!  --- ...  begin spectral band loop

          do i = 1, nbands
            pklay(k,i) = totplnk(indlay,i) + tlayfr                     &
     &                 * (totplnk(indlay+1,i) - totplnk(indlay,i))
            pklev(k,i) = totplnk(indlev,i) + tlevfr                     &
     &                 * (totplnk(indlev+1,i) - totplnk(indlev,i))
          enddo

!  --- ...  find the two reference pressures on either side of the
!           layer pressure. store them in jp and jp1. store in fp the
!           fraction of the difference (in ln(pressure)) between these
!           two values that the layer pressure lies.

          plog = log(pavel(k))
          jp(k)= max(1, min(58, int(36.0 - 5.0*(plog+0.04)) ))
          jp1  = jp(k) + 1
!  --- ...  limit pressure extrapolation at the top
          fp   = max(f_zero, min(f_one, 5.0*(preflog(jp(k))-plog) ))
!org      fp   = 5.0 * (preflog(jp(k)) - plog)

!  --- ...  determine, for each reference pressure (jp and jp1), which
!           reference temperature (these are different for each
!           reference pressure) is nearest the layer temperature but does
!           not exceed it. store these indices in jt and jt1, resp.
!           store in ft (resp. ft1) the fraction of the way between jt
!           (jt1) and the next highest reference temperature that the
!           layer temperature falls.

          tem1 = (tavel(k)-tref(jp(k))) / 15.0
          tem2 = (tavel(k)-tref(jp1    )) / 15.0
          jt (k) = max(1, min(4, int(3.0 + tem1) ))
          jt1(k) = max(1, min(4, int(3.0 + tem2) ))
!  --- ...  restrict extrapolation ranges by limiting abs(det t) < 37.5 deg
          ft  = max(-0.5, min(1.5, tem1 - float(jt (k) - 3) ))
          ft1 = max(-0.5, min(1.5, tem2 - float(jt1(k) - 3) ))
!org      ft  = tem1 - float(jt (k) - 3)
!org      ft1 = tem2 - float(jt1(k) - 3)

!  --- ...  we have now isolated the layer ln pressure and temperature,
!           between two reference pressures and two reference temperatures
!           (for each reference pressure).  we multiply the pressure
!           fraction fp with the appropriate temperature fractions to get
!           the factors that will be needed for the interpolation that yields
!           the optical depths (performed in routines taugbn for band n)

          tem1 = f_one - fp
          fac10(k) = tem1 * ft
          fac00(k) = tem1 * (f_one - ft)
          fac11(k) = fp * ft1
          fac01(k) = fp * (f_one - ft1)

          forfac(k) = pavel(k)*stpfac / (tavel(k)*(1.0 + h2ovmr(k)))
          selffac(k) = h2ovmr(k) * forfac(k)

!  --- ...  set up factors needed to separately include the minor gases
!           in the calculation of absorption coefficient

          scaleminor(k) = pavel(k) / tavel(k)
          scaleminorn2(k) = (pavel(k) / tavel(k))                       &
     &                    * (colbrd(k)/(coldry(k) + colamt(k,1)))
          tem1 = (tavel(k) - 180.8) / 7.2
          indminor(k) = min(18, max(1, int(tem1)))
          minorfrac(k) = tem1 - float(indminor(k))

!  --- ...  if the pressure is less than ~100mb, perform a different
!           set of species interpolations.

          if (plog > 4.56) then

            laytrop =  laytrop + 1

            tem1 = (332.0 - tavel(k)) / 36.0
            indfor(k) = min(2, max(1, int(tem1)))
            forfrac(k) = tem1 - float(indfor(k))

!  --- ...  set up factors needed to separately include the water vapor
!           self-continuum in the calculation of absorption coefficient.

            tem1 = (tavel(k) - 188.0) / 7.2
            indself(k) = min(9, max(1, int(tem1)-7))
            selffrac(k) = tem1 - float(indself(k) + 7)

!  --- ...  setup reference ratio to be used in calculation of binary
!           species parameter in lower atmosphere.

            rfrate(k,1,1) = chi_mls(1,jp(k)) / chi_mls(2,jp(k))
            rfrate(k,1,2) = chi_mls(1,jp(k)+1) / chi_mls(2,jp(k)+1)

            rfrate(k,2,1) = chi_mls(1,jp(k)) / chi_mls(3,jp(k))
            rfrate(k,2,2) = chi_mls(1,jp(k)+1) / chi_mls(3,jp(k)+1)

            rfrate(k,3,1) = chi_mls(1,jp(k)) / chi_mls(4,jp(k))
            rfrate(k,3,2) = chi_mls(1,jp(k)+1) / chi_mls(4,jp(k)+1)

            rfrate(k,4,1) = chi_mls(1,jp(k)) / chi_mls(6,jp(k))
            rfrate(k,4,2) = chi_mls(1,jp(k)+1) / chi_mls(6,jp(k)+1)

            rfrate(k,5,1) = chi_mls(4,jp(k)) / chi_mls(2,jp(k))
            rfrate(k,5,2) = chi_mls(4,jp(k)+1) / chi_mls(2,jp(k)+1)

          else

            tem1 = (tavel(k) - 188.0) / 36.0
            indfor(k) = 3
            forfrac(k) = tem1 - f_one

            indself(k) = 0
            selffrac(k) = f_zero

!  --- ...  setup reference ratio to be used in calculation of binary
!           species parameter in upper atmosphere.

            rfrate(k,1,1) = chi_mls(1,jp(k)) / chi_mls(2,jp(k))
            rfrate(k,1,2) = chi_mls(1,jp(k)+1) / chi_mls(2,jp(k)+1)

            rfrate(k,6,1) = chi_mls(3,jp(k)) / chi_mls(2,jp(k))
            rfrate(k,6,2) = chi_mls(3,jp(k)+1) / chi_mls(2,jp(k)+1)

          endif

!  --- ...  rescale selffac and forfac for use in taumol

          selffac(k) = colamt(k,1) * selffac(k)
          forfac(k)  = colamt(k,1) * forfac(k)

        enddo   ! end do_k layer loop

!     if (lprnt) then
!      print *,'laytrop',laytrop
!      print *,'colh2o',(colamt(k,1),k=1,NLAY)
!      print *,'colco2',(colamt(k,2),k=1,NLAY)
!      print *,'colo3', (colamt(k,3),k=1,NLAY)
!      print *,'coln2o',(colamt(k,4),k=1,NLAY)
!      print *,'colch4',(colamt(k,5),k=1,NLAY)
!      print *,'fac00',fac00
!      print *,'fac01',fac01
!      print *,'fac10',fac10
!      print *,'fac11',fac11
!      print *,'jp',jp
!      print *,'jt',jt
!      print *,'jt1',jt1
!      print *,'selffac',selffac
!      print *,'selffrac',selffrac
!      print *,'indself',indself
!      print *,'forfac',forfac
!      print *,'forfrac',forfrac
!      print *,'indfor',indfor
!     endif

!  --- ...  calculate the gaseous optical depths and Planck fractions for
!           each longwave spectral band.

        call taumol                                                     &
!  ---  inputs:
     &     ( laytrop,pavel,coldry,colamt,colbrd,wx,tauaer,              &
     &       rfrate,fac00,fac01,fac10,fac11,jp,jt,jt1,                  &
     &       selffac,selffrac,indself,forfac,forfrac,indfor,            &
     &       minorfrac,scaleminor,scaleminorn2,indminor,                &
     &       nlay,                                                      &
!  ---  outputs:
     &       fracs, tautot                                              &
     &     )

!     if (lprnt) then
!     print *,' after taumol'
!     do k = 1, nlay
!       write(6,121) k
!121    format(' k =',i3,5x,'FRACS')
!       write(6,122) (fracs(k,j),j=1,ngptlw)
!122    format(10e14.7)
!       write(6,123) k
!123    format(' k =',i3,5x,'TAUTOT')
!       write(6,122) (tautot(k,j),j=1,ngptlw)
!     enddo
!     endif

!  --- ... call the radiative transfer routine based on cloud scheme
!          selection. clear sky calculation is done at the same time.

        if (isubcol <= 0) then

          if (iovrlw <= 0) then

            call rtrn                                                   &
!  ---  inputs:
     &     ( semiss,delp,cldfrc,taucmc,secdiff,                         &
     &       pklay,pklev,pkbnd,fracs,tautot,                            &
     &       nlay, nlp1,                                                &
!  ---  outputs:
     &       totuflux,totdflux,htr, totuclfl,totdclfl,htrcl, htrb       &
     &     )

          else

            call rtrnmr                                                 &
!  ---  inputs:
     &     ( semiss,delp,cldfrc,taucmc,secdiff,                         &
     &       pklay,pklev,pkbnd,fracs,tautot,                            &
     &       nlay, nlp1,                                                &
!  ---  outputs:
     &       totuflux,totdflux,htr, totuclfl,totdclfl,htrcl, htrb       &
     &     )

          endif   ! end if_iovrlw_block

        else

          call rtrnmc                                                   &
!  ---  inputs:
     &     ( semiss,delp,cldfmc,taucmc,secdiff,                         &
     &       pklay,pklev,pkbnd,fracs,tautot,                            &
     &       nlay, nlp1,                                                &
!  ---  outputs:
     &       totuflux,totdflux,htr, totuclfl,totdclfl,htrcl, htrb       &
     &     )

        endif   ! end if_isubcol_block

!  --- ...  output total-sky and clear-sky fluxes and heating rates

        topflx(iplon)%upfxc = totuflux(nlay)
        topflx(iplon)%upfx0 = totuclfl(nlay)

        sfcflx(iplon)%upfxc = totuflux(0)
        sfcflx(iplon)%upfx0 = totuclfl(0)
        sfcflx(iplon)%dnfxc = totdflux(0)
        sfcflx(iplon)%dnfx0 = totdclfl(0)

        if (iflip == 0) then        ! output from toa to sfc

!! --- ...  optional fluxes
          if ( lflxprf ) then
            do k = 0, nlay
              k1 = nlp1 - k
              flxprf(iplon,k1)%upfxc = totuflux(k)
              flxprf(iplon,k1)%dnfxc = totdflux(k)
              flxprf(iplon,k1)%upfx0 = totuclfl(k)
              flxprf(iplon,k1)%dnfx0 = totdclfl(k)
            enddo
          endif

          do k = 1, nlay
            k1 = nlp1 - k
            hlwc(iplon,k1) = htr(k)
          enddo

!! --- ...  optional clear sky heating rate
          if ( lhlw0 ) then
            do k = 1, nlay
              k1 = nlp1 - k
              hlw0(iplon,k1) = htrcl(k)
            enddo
          endif

!! --- ...  optional spectral band heating rate
          if ( lhlwb ) then
            do j = 1, nbands
            do k = 1, nlay
              k1 = nlp1 - k
              hlwb(iplon,k1,j) = htrb(k,j)
            enddo
            enddo
          endif

        else                        ! output from sfc to toa

!! --- ...  optional fluxes
          if ( lflxprf ) then
            do k = 0, nlay
              flxprf(iplon,k+1)%upfxc = totuflux(k)
              flxprf(iplon,k+1)%dnfxc = totdflux(k)
              flxprf(iplon,k+1)%upfx0 = totuclfl(k)
              flxprf(iplon,k+1)%dnfx0 = totdclfl(k)
            enddo
          endif

          do k = 1, nlay
            hlwc(iplon,k) = htr(k)
          enddo

!! --- ...  optional clear sky heating rate
          if ( lhlw0 ) then
            do k = 1, nlay
              hlw0(iplon,k) = htrcl(k)
            enddo
          endif

!! --- ...  optional spectral band heating rate
          if ( lhlwb ) then
            do j = 1, nbands
            do k = 1, nlay
              hlwb(iplon,k,j) = htrb(k,j)
            enddo
            enddo
          endif

        endif                       ! if_iflip

      enddo  lab_do_iplon

!...................................
      end subroutine lwrad
!-----------------------------------



!-----------------------------------
      subroutine rlwinit                                                &
!...................................

!  ---  inputs:
     &     ( icwp, me, nlay, iovr, isubc )
!  ---  outputs: (none)

!  ===================  program usage description  ===================  !
!                                                                       !
! purpose:  initialize non-varying module variables, conversion factors,!
! and look-up tables.                                                   !
!                                                                       !
! subprograms called:  none                                             !
!                                                                       !
!  ====================  defination of variables  ====================  !
!                                                                       !
!  inputs:                                                              !
!    icwp     -  flag of cloud schemes used by model                    !
!                =0: diagnostic scheme gives cloud tau, omiga, and g    !
!                =1: prognostic scheme gives cloud liq/ice path, etc.   !
!    me       - print control for parallel process                      !
!    nlay     - number of vertical layers                               !
!    iovr     - cloud overlapping control flag                          !
!                =0: random overlapping clouds                          !
!                =1: maximum/random overlapping clouds                  !
!                =2: maximum overlap cloud (isubcol>0 only)             !
!    isubc    - mcica sub-column cloud approximation control flag       !
!                =0: no sub-column cloud approximation                  !
!                =1: mcica sub-col approx. with prescribed initial seed !
!                =2: mcica sub-col approx. with specified initial seed  !
!                                                                       !
!  outputs: (none)                                                      !
!                                                                       !
!  control flags in module "module_radlw_cntr_para":                    !
!     ilwrate - heating rate unit selections                            !
!               =1: output in k/day                                     !
!               =2: output in k/second                                  !
!     iaerlw  - control flag for aerosols                               !
!               =0: do not include aerosol effect                       !
!               >0: include aerosol effect                              !
!     irgaslw - control flag for rare gases (ch4,n2o,o2, etc.)          !
!               =0: do not include rare gases                           !
!               =1: include all rare gases                              !
!     icfclw  - control flag for cfc gases                              !
!               =0: do not include cfc gases                            !
!               =1: include all cfc gases                               !
!     iflagliq- cloud optical properties contrl flag                    !
!               =0: input cloud opt depth from diagnostic scheme        !
!               >0: input cwp,cip, and other cloud content parameters   !
!                                                                       !
!  *******************************************************************  !
!  original code description                                            !
!                                                                       !
!  original version:       michael j. iacono; july, 1998                !
!  first revision for ncar ccm:               september, 1998           !
!  second revision for rrtm_v3.0:             september, 2002           !
!                                                                       !
!  this subroutine performs calculations necessary for the initialization
!  of the longwave model.  lookup tables are computed for use in the lw !
!  radiative transfer, and input absorption coefficient data for each   !
!  spectral band are reduced from 256 g-point intervals to 140.         !
!                                                                       !
!  *******************************************************************  !
!                                                                       !
! definitions:                                                          !
!   arrays for 10000-point look-up tables:                              !
!   tau_tbl - clear-sky optical depth (used in cloudy radiative transfer!
!   exp_tbl - exponential lookup table for tansmittance                 !
!   tfn_tbl - tau transition function; i.e. the transition of the Planck!
!             function from that for the mean layer temperature to that !
!             for the layer boundary temperature as a function of optical
!             depth. the "linear in tau" method is used to make the table
!                                                                       !
!  *******************************************************************  !
!                                                                       !
!  ======================  end of description block  =================  !

!  ---  inputs:
      integer, intent(in) :: icwp, me, nlay, iovr, isubc

!  ---  outputs: none

!  ---  locals:
      real (kind=kind_phys), parameter :: expeps = 1.e-20

      real (kind=kind_phys) :: tfn, pival, explimit

      integer               :: i

!
!===> ... begin here
!
      iovrlw  = iovr     ! assign module variable of overlap flag

      isubcol = isubc    ! assign module variable sub_col clds flag

      if ( iovrlw<0 .or. iovrlw>2 ) then
        print *,'  *** Error in specification of cloud overlap flag',   &
     &          ' IOVRLW=',iovrlw,' in RLWINIT !!'
        stop
      elseif ( iovrlw==2 .and. isubcol==0 ) then
        if (me == 0) then
          print *,'  *** IOVRLW=2 - maximum cloud overlap, is not yet', &
     &          ' available for ISUBC=0 setting!!'
          print *,'      The program uses maximum/random overlap',      &
     &          ' instead.'
        endif

        iovrlw = 1
      endif

      if (me == 0) then
        print *,' - Using AER Longwave Radiation, Version: ', VTAGLW

        if (iaerlw > 0) then
          print *,'   --- Using input aerosol parameters for LW'
        else
          print *,'   --- Aerosol effect is NOT included in LW, all'    &
     &           ,' internal aerosol parameters are set to zeros'
        endif

        if (irgaslw == 1) then
          print *,'   --- Include rare gases N2O, CH4, O2, absorptions',&
     &            ' in LW'
        else
          print *,'   --- Rare gases effect is NOT included in LW'
        endif

        if (icfclw == 1) then
          print *,'   --- Include CFC gases absorptions in LW'
        else
          print *,'   --- CFC gases effect is NOT included in LW'
        endif

        if ( isubcol == 0 ) then
          print *,'   --- Using standard grid average clouds, no ',     &
     &            'sub-column clouds approximation applied'
        elseif ( isubcol == 1 ) then
          print *,'   --- Using MCICA sub-colum clouds approximation ', &
     &            'with a prescribed sequence of permutaion seeds'
        elseif ( isubcol == 2 ) then
          print *,'   --- Using MCICA sub-colum clouds approximation ', &
     &            'with provided input array of permutation seeds'
        else
          print *,'  *** Error in specification of sub-column cloud ',  &
     &            ' control flag isubc =',isubcol,' !!'
          stop
        endif
      endif

!  --- ...  set initial permutaion seed

      ipsdlw = ipsdlw0

!  --- ...  check cloud flags for consistency

      if ((icwp == 0 .and. iflagliq /= 0) .or.                          &
     &    (icwp == 1 .and. iflagliq == 0)) then
        print *,'  *** Model cloud scheme inconsistent with LW',        &
     &          ' radiation cloud radiative property setup !!'
        stop
      endif

      if ( iflagliq<0 .or. iflagliq>1 .or.                              &
     &     iflagice<0 .or. iflagice>3 ) then
        print *,'  *** Error in specifying LW IFLAGLIQ or IFLAGICE :',  &
     &           iflagliq, iflagice
        stop
      endif

!  --- ...  setup default surface emissivity for each band here

      semiss0(:) = f_one

!  --- ...  setup constant factors for flux and heating rate
!           the 1.0e-2 is to convert pressure from mb to N/m**2

      pival = 2.0 * asin(f_one)
      fluxfac = pival * 2.0d4
!     fluxfac = 62831.85307179586                   ! = 2 * pi * 1.0e4

      if (ilwrate == 1) then
!       heatfac = 8.4391
!       heatfac = con_g * 86400. * 1.0e-2 / con_cp  !   (in k/day)
        heatfac = con_g * 864.0 / con_cp            !   (in k/day)
      else
        heatfac = con_g * 1.0e-2 / con_cp           !   (in k/second)
      endif

!  --- ...  compute lookup tables for transmittance, tau transition
!           function, and clear sky tau (for the cloudy sky radiative
!           transfer).  tau is computed as a function of the tau
!           transition function, transmittance is calculated as a
!           function of tau, and the tau transition function is
!           calculated using the linear in tau formulation at values of
!           tau above 0.01.  tf is approximated as tau/6 for tau < 0.01.
!           all tables are computed at intervals of 0.001.  the inverse
!           of the constant used in the pade approximation to the tau
!           transition function is set to b.

      tau_tbl(0) = f_zero
      exp_tbl(0) = f_one
      tfn_tbl(0) = f_zero

      tau_tbl(ntbl) = 1.e10
      exp_tbl(ntbl) = expeps
      tfn_tbl(ntbl) = f_one

      explimit = aint( -log(tiny(exp_tbl(0))) )

      do i = 1, ntbl-1
!org    tfn = float(i) / float(ntbl)
!org    tau_tbl(i) = bpade * tfn / (f_one - tfn)
        tfn = real(i, kind_phys) / real(ntbl-i, kind_phys)
        tau_tbl(i) = bpade * tfn
        if (tau_tbl(i) >= explimit) then
          exp_tbl(i) = expeps
        else
          exp_tbl(i) = exp( -tau_tbl(i) )
        endif

        if (tau_tbl(i) < 0.06) then
          tfn_tbl(i) = tau_tbl(i) / 6.0
        else
          tfn_tbl(i) = f_one - 2.0*( (f_one / tau_tbl(i))               &
     &               - ( exp_tbl(i) / (f_one - exp_tbl(i)) ) )
        endif
      enddo

!...................................
      end subroutine rlwinit
!-----------------------------------


! ----------------------------
      subroutine cldprop                                                &
! ............................
!  ---  inputs:
     &     ( cfrac,cliqp,reliq,cicep,reice,cdat1,cdat2,cdat3,cdat4,     &
     &       lcf1, nlay, ipseed,                                        &
!  ---  outputs:
     &       taucmc, cldfmc                                             &
     &     )

!  ===================  program usage description  ===================  !
!                                                                       !
! purpose:  compute the cloud optical depth(s) for each cloudy layer    !
! and g-point interval.                                                 !
!                                                                       !
! subprograms called:  none                                             !
!                                                                       !
!  ====================  defination of variables  ====================  !
!                                                                       !
!  inputs:                                                       -size- !
!    cfrac - real, layer cloud fraction                          0:nlp1 !
!        .....  for iflagliq > 0  (prognostic cloud sckeme)  - - -      !
!    cliqp - real, layer in-cloud liq water path (g/m**2)          nlay !
!    reliq - real, mean eff radius for liq cloud (micron)          nlay !
!    cicep - real, layer in-cloud ice water path (g/m**2)          nlay !
!    reice - real, mean eff radius for ice cloud (micron)          nlay !
!    cdat1 - real, layer rain drop water path  (g/m**2)            nlay !
!    cdat2 - real, effective radius for rain drop (microm)         nlay !
!    cdat3 - real, layer snow flake water path (g/m**2)            nlay !
!              (if use fu's formula it needs to be normalized by        !
!              snow density (g/m**3/1.0e6) to get unit of micron)       !
!    cdat4 - real, effective radius for snow flakes (micron)       nlay !
!        .....  for iflagliq = 0  (diagnostic cloud sckeme)  - - -      !
!    cdat1 - real, input cloud optical depth                       nlay !
!    cdat2 - real, layer cloud single scattering albedo            nlay !
!    cdat3 - real, layer cloud asymmetry factor                    nlay !
!    cdat4 - real, optional use                                    nlay !
!    cliqp - not used                                              nlay !
!    reliq - not used                                              nlay !
!    cicep - not used                                              nlay !
!    reice - not used                                              nlay !
!                                                                       !
!    lcf1  - logical, =t: cloudy column; =f: clear column.           1  !
!    nlay  - integer, number of vertical layers                      1  !
!    ipseed- permutation seed for generating random numbers (isubcol>0) !
!                                                                       !
!  outputs:                                                             !
!    taucmc - real, cloud optical depth                      nlay*ngptlw!
!    cldfmc - real, cloud fraction for each sub-column       nlay*ngptlw!
!                                                                       !
!                                                                       !
!    explanation of the method for each value of iflagliq, and iflagice.!
!    set up in module "module_radlw_cntr_para"                          !
!                                                                       !
!     iflagliq=0 : input cloud optical property (tau, ssa, asy).        !
!                  (used for diagnostic cloud method)                   !
!     iflagliq>0 : input cloud liq/ice path and effective radius, also  !
!                  require the user of 'iflagice' to specify the method !
!                  used to compute aborption due to water/ice parts.    !
!  ...................................................................  !
!                                                                       !
!     iflagliq=1:  the water droplet effective radius (microns) is input!
!                  and the opt depths due to water clouds are computed  !
!                  as in hu and stamnes, j., clim., 6, 728-742, (1993). !
!                  the values for absorption coefficients appropriate for
!                  the spectral bands in rrtm have been obtained for a  !
!                  range of effective radii by an averaging procedure   !
!                  based on the work of j. pinto (private communication).
!                  linear interpolation is used to get the absorption   !
!                  coefficients for the input effective radius.         !
!                                                                       !
!     iflagice=1:  the cloud ice path (g/m2) and ice effective radius   !
!                  (microns) are input and the optical depths due to ice!
!                  clouds are computed as in ebert and curry, jgr, 97,  !
!                  3831-3836 (1992).  the spectral regions in this work !
!                  have been matched with the spectral bands in rrtm to !
!                  as great an extent as possible:                      !
!                     e&c 1      ib = 5      rrtm bands 9-16            !
!                     e&c 2      ib = 4      rrtm bands 6-8             !
!                     e&c 3      ib = 3      rrtm bands 3-5             !
!                     e&c 4      ib = 2      rrtm band 2                !
!                     e&c 5      ib = 1      rrtm band 1                !
!     iflagice=2:  the cloud ice path (g/m2) and ice effective radius   !
!                  (microns) are input and the optical depths due to ice!
!                  clouds are computed as in rt code, streamer v3.0     !
!                  (ref: key j., streamer user's guide, cooperative     !
!                  institute for meteorological satellite studies, 2001,!
!                  96 pp.) valid range of values for re are between 5.0 !
!                  and 131.0 micron.                                    !
!     iflagice=3:  the ice generalized effective size (dge) is input and!
!                  the optical properties, are calculated as in q. fu,  !
!                  j. climate, (1998). q. fu provided high resolution   !
!                  tales which were appropriately averaged for the bands!
!                  in rrtm_lw. linear interpolation is used to get the  !
!                  coeff from the stored tables. valid range of values  !
!                  for deg are between 5.0 and 140.0 micron.            !
!                                                                       !
!  other cloud control module variables:                                !
!                                                                       !
!     isubcol =0: standard cloud scheme, no sub-col cloud approximation !
!             >0: mcica sub-col cloud scheme using ipseed as permutation!
!                 seed for generating rundom numbers                    !
!                                                                       !
!     iovrlw    : control flag for cloud overlapping method             !
!            (isubcol=1): =0:random; =1:maximum/random: =2:maximum      !
!            (isubcol=0): cloud overlap is managed by subr. rtrn/rtrnmr !
!                                                                       !
!  ======================  end of description block  =================  !
!
      use module_radlw_cldprlw

!  ---  inputs:
      integer, intent(in) :: nlay, ipseed
      logical, intent(in) :: lcf1

      real (kind=kind_phys), dimension(0:), intent(in) :: cfrac
      real (kind=kind_phys), dimension(:),  intent(in) :: cliqp, reliq, &
     &       cicep, reice, cdat1, cdat2, cdat3, cdat4

!  ---  outputs:
      real (kind=kind_phys), dimension(:,:),intent(out):: taucmc, cldfmc

!  ---  locals:
      real (kind=kind_phys), dimension(nlay,ngptlw) :: cliqmc, cicemc,  &
     &       cranmc, csnwmc

      real (kind=kind_phys), dimension(nlay)      :: cldf

      real (kind=kind_phys) ::   dgeice, factor, fint,                  &
     &       tauliq, cldliq, refliq, tauice, cldice, refice,            &
     &       tauran, cldran, refran, tausnw, cldsnw, refsnw,            &
     &       abscoliq, abscoice

      integer :: ia, ib, ic, ig, k, index

!
!===> ...  begin here
!
      do ig = 1, ngptlw
        do k = 1, nlay
          taucmc(k,ig) = f_zero
          cldfmc(k,ig) = f_zero
        enddo
      enddo

      if ( .not. lcf1 ) return     ! if clear-sky column, return

!  --- ...  compute cloud radiative properties for a cloudy column

      if ( isubcol > 0 ) then      ! mcica sub-col clouds approx

        do k = 1, nlay
          if ( cfrac(k) < cldmin ) then
            cldf(k) = f_zero
          else
            cldf(k) = cfrac(k)
          endif
        enddo

!  --- ...  call sub-column cloud generator

        call mcica_subcol                                               &
!  ---  inputs:
     &     ( cldf, cicep, cliqp, cdat1, cdat2, cdat3,                   &
     &       nlay, ngptlw, ipseed, iflagliq,                            &
!  ---  output:
     &       cldfmc, cicemc, cliqmc, cranmc, csnwmc, taucmc             &
     &     )

        if ( iflagliq == 0 ) return

      else                         ! isubcol = 0, standard approach

        if ( iflagliq == 0 ) then
          do ig = 1, ngptlw
            do k = 1, nlay
              taucmc(k,ig) = cdat1(k)
            enddo
          enddo

          return
        else
          do k = 1, nlay
            cldfmc(k,1) = cfrac(k)
            cliqmc(k,1) = cliqp(k)
            cicemc(k,1) = cicep(k)
            cranmc(k,1) = cdat1(k)
            csnwmc(k,1) = cdat3(k)
          enddo
        endif   ! end if_iflagliq_block

      endif   ! end if_isubcol_block

!  --- ...  the following are for prognostic cloud scheme (iflagliq>0)

      do ig = 1, ngptlw
        ib = ngb(ig)              ! spectral band index
        ia = ipat(ib)             ! eb_&_c band index for ice cloud coeff

        if ( isubcol > 0 ) then   ! use mcica cloud scheme
          ic = ig
        else                      ! use standard cloud scheme
          ic = 1
        endif

        do k = 1, nlay
          cldliq = cliqmc(k,ic)
          cldice = cicemc(k,ic)
          cldran = cranmc(k,ic)
          cldsnw = csnwmc(k,ic)
          refliq = max(2.5e0, min(60.0e0, reliq(k) ))
          refice = max(5.0e0, reice(k) )
          refran = cdat2(k)
          refsnw = cdat4(k)

          if ( cldfmc(k,ic) >= cldmin ) then

!  --- ...  calculation of absorption coefficients due to ice clouds.
            if ( cldice <= f_zero ) then
              abscoice = f_zero
            else

!  --- ...  ebert and curry approach for all particle sizes though somewhat
!           unjustified for large ice particles

              if ( iflagice == 1 ) then
                refice = min(130.0, max(13.0, real(refice) ))

                abscoice = max( f_zero,                                 &
     &                          absice1(1,ia) + absice1(2,ia)/refice )

!  --- ...  streamer approach for ice effective radius between 5.0 and 131.0 microns
!           and ebert and curry approach for ice eff radius greater than 131.0 microns.
!           no smoothing between the transition of the two methods.

              elseif ( iflagice == 2 ) then

                factor = (refice - 2.0) / 3.0
                index  = max( 1, min( 42, int( factor ) ))
                fint   = factor - float(index)

                abscoice = max( f_zero, absice2(index,ib) + fint        &
     &                   * (absice2(index+1,ib) - absice2(index,ib)) )

!  --- ...  fu's approach for ice effective radius between 4.8 and 135 microns
!           (generalized effective size from 5 to 140 microns)

              elseif ( iflagice == 3 ) then

!               dgeice = max(5.0, 1.5396*reice(k))              ! v4.4 value
                dgeice = max(5.0, 1.0315*reice(k))              ! v4.71 value
                factor = (dgeice - 2.0) / 3.0
                index  = max( 1, min( 45, int( factor ) ))
                fint   = factor - float(index)

                abscoice = max( f_zero, absice3(index,ib) + fint        &
     &                   * (absice3(index+1,ib) - absice3(index,ib)) )

              endif   ! end if_iflagice_block

            endif   ! end if_cldice_block

!  --- ...  calculation of absorption coefficients due to water clouds.

            if ( cldliq <= f_zero ) then
              abscoliq = f_zero
            else
              if ( iflagliq == 1 ) then

                factor = refliq - 1.5
                index  = max( 1, min( 57, int( factor ) ))
                fint   = factor - float(index)

                abscoliq = max( f_zero, absliq1(index,ib) + fint        &
     &                   * (absliq1(index+1,ib) - absliq1(index,ib)) )
              endif   ! end if_iflagliq_block
            endif   ! end if_cldliq_block

            tauliq = cldliq * abscoliq
            tauice = cldice * abscoice
            tauran = cldran * absrain                        ! ncar formula
            tausnw = cldsnw * abssnow0                       ! ncar formula
!           tausnw = cldsnw * abssnow1 / refsnw              ! fu's formula

            taucmc(k,ig) = tauliq + tauice + tauran + tausnw

          endif   ! end if_cldfmc_block
        enddo   ! end do_k_loop

      enddo   ! end do_ig_loop

! ..................................
      end subroutine cldprop
! ----------------------------------


! ----------------------------------
      subroutine mcica_subcol                                           &
! ..................................
!  ---  inputs:
     &    ( cldf, cicep, cliqp, cda1, cda2, cda3,                       &
     &      nlay, nsub, ipseed, iflagcld,                               &
!  ---  outputs:
     &      cldfmc, cicemc, cliqmc, cranmc, csnwmc, taucmc              &
!  ---  optional:
!    &,     ssacmc, asycmc                                              &
     &    )

!  ====================  defination of variables  ====================  !
!                                                                       !
!  input variables:                                                size !
!   cldf    - real, layer cloud fraction                           nlay !
!        - - -  for iflagcld > 0  (prognostic cloud sckeme)  - - -      !
!   cicep   - real, layer in-cloud ice water path (g/m2)           nlay !
!   cliqp   - real, layer in-cloud liquid water path (g/m2)        nlay !
!   cda1    - real, layer rain drop water path (g/m2)              nlay !
!   cda2    - real, not used                                       nlay !
!   cda3    - real, layer snow flake water path (g/m2)             nlay !
!  ** fu's scheme need to be normalized by snow density (g/m**3/1.0e6)  !
!                                                                       !
!        - - -  for iflagcld = 0  (diagnostic cloud sckeme)  - - -      !
!   cicep   - real, not used                                       nlay !
!   cliqp   - real, not used                                       nlay !
!   cda1    - real, layer cloud optical depth                      nlay !
!   cda2    - real, layer cloud single scattering albedo           nlay !
!                   non-delta scaled values                             !
!   cda3    - real, layer cloud asymmetry parameter                nlay !
!                   non-delta scaled values                             !
!                                                                       !
!   nlay    - integer, number of model vertical layers               1  !
!   nsub    - integer, number of sub columns, = number of g-points   1  !
!   ipseed  - integer, permute seed for random num generator         1  !
!    ** note : if the cloud generator is called multiple times, need    !
!              to permute the seed between each call; if between calls  !
!              for lw and sw, use values differ by the number of g-pts. !
!   iflagcld- integer, controflag for cloud optical property scheme  1  !
!               =0: direct input cld optical depth, ssa, and asy        !
!               >0: use input cld liq/ice path to calc cld opt prop     !
!                                                                       !
!  output variables:                                                    !
!   cldfmc  - real, layer cloud fraction [mcica]               nlay*nsub!
!                ---  for  iflagcld > 0  ---                            !
!   cicemc  - real, cloud ice water path [mcica]               nlay*nsub!
!   cliqmc  - real, cloud liquid water path [mcica]            nlay*nsub!
!   cranmc  - real, cloud rain drop water path [mcica]         nlay*nsub!
!   csnwmc  - real, cloud snow flake water path [mcica]        nlay*nsub!
!                ---  for  iflagcld = 0  ---                            !
!   taucmc  - real, cloud optical depth [mcica]                nlay*nsub!
!!optional output variables: (currently not used by lw)                 !
!!  ssacmc  - real, cloud single scattering albedo [mcica]     nlay*nsub!
!!  asycmc  - real, cloud asymmetry parameter [mcica]          nlay*nsub!
!                                                                       !
!                                                                       !
!  other control flags from module variables:                           !
!     iovrlw    : control flag for cloud overlapping method             !
!            (isubcol=1): =0:random; =1:maximum/random: =2:maximum      !
!            (isubcol=0): cloud overlap is managed by subr. rtrn/rtrnmr !
!                                                                       !
!  =====================    end of definitions    ====================  !

      implicit none

!  ---  inputs:
      integer, intent(in) :: nlay, nsub, ipseed, iflagcld

      real (kind=kind_phys), dimension(:),   intent(in) :: cicep,       &
     &       cliqp, cda1, cda2, cda3, cldf

!  ---  outputs:
      real (kind=kind_phys), dimension(:,:), intent(out):: cldfmc,      &
     &       cicemc, cliqmc, cranmc, csnwmc, taucmc

!! ---  optional outputs:
!!    real (kind=kind_phys), dimension(:,:), intent(out):: ssacmc,asycmc

!  ---  locals:
      real (kind=kind_phys) :: cdfunc(nlay,nsub), tem1,                 &
     &                         rand2d(nlay*nsub), rand1d(nsub)

      type (random_stat) :: stat          ! for thread safe random generator

      logical :: lcloudy(nlay,nsub)

      integer :: k, n, kn
!
!===> ...  begin here
!
!  --- ...  advance randum number generator by ipseed values

      call random_setseed                                               &
!  ---  inputs:
     &    ( ipseed,                                                     &
!  ---  outputs:
     &      stat                                                        &
     &    )

!  --- ...  sub-column set up according to overlapping assumption

      select case ( iovrlw )

        case( 0 )        ! random overlap, pick a random value at every level

          call random_number                                            &
!  ---  inputs: ( none )
!  ---  outputs:
     &     ( rand2d, stat )

          kn = 0
          do n = 1, nsub
            do k = 1, nlay
              kn = kn + 1
              cdfunc(k,n) = rand2d(kn)
            enddo
          enddo

        case( 1 )        ! max-ran overlap

          call random_number                                            &
!  ---  inputs: ( none )
!  ---  outputs:
     &     ( rand2d, stat )

          kn = 0
          do n = 1, nsub
            do k = 1, nlay
              kn = kn + 1
              cdfunc(k,n) = rand2d(kn)
            enddo
          enddo

!  ---  first pick a random number for bottom (or top) layer.
!       then walk up the column: (aer's code)
!       if layer below is cloudy, use the same rand num in the layer below
!       if layer below is clear,  use a new random number

!  ---  from bottom up
          do k = 2, nlay
            tem1 = f_one - cldf(k-1)

            do n = 1, nsub
              if ( cdfunc(k-1,n) > tem1 ) then
                cdfunc(k,n) = cdfunc(k-1,n)
              else
                cdfunc(k,n) = cdfunc(k,n) * tem1
              endif
            enddo
          enddo

!  ---  or walk down the column: (if use original author's method)
!       if layer above is cloudy, use the same rand num in the layer above
!       if layer above is clear,  use a new random number

!  ---  from top down
!         do k = nlay-1, 1, -1
!           tem1 = f_one - cldf(k+1)

!           do n = 1, nsub
!             if ( cdfunc(k+1,n) > tem1 ) then
!               cdfunc(k,n) = cdfunc(k+1,n)
!             else
!               cdfunc(k,n) = cdfunc(k,n) * tem1
!             endif
!           enddo
!         enddo

        case( 2 )        ! maximum overlap, pick same random numebr at every level

          call random_number                                            &
!  ---  inputs: ( none )
!  ---  outputs:
     &     ( rand1d, stat )

          do n = 1, nsub
            do k = 1, nlay
              cdfunc(k,n) = rand1d(n)
            enddo
          enddo

      end select

!  --- ...  generate subcolumns for homogeneous clouds

      do k = 1, nlay
        tem1 = f_one - cldf(k)

        do n = 1, nsub
          lcloudy(k,n) = cdfunc(k,n) >= tem1
        enddo
      enddo

!  --- ...  where the subcolumn is cloudy, the subcolumn cloud fraction is 1;
!           where the subcolumn is not cloudy, the subcolumn cloud fraction is 0

      do n = 1, nsub
        do k = 1, nlay
          if ( lcloudy(k,n) ) then
            cldfmc(k,n) = f_one
          else
            cldfmc(k,n) = f_zero
          endif
        enddo
      enddo

!  --- ...  comput sub-column cloud optical properties

      if ( iflagcld == 0 ) then      ! cloud optical properties are ready inputs

        do n = 1, nsub
          do k = 1, nlay
            if ( lcloudy(k,n) ) then
              taucmc(k,n) = cda1(k)
!!            ssacmc(k,n) = cda2(k)
!!            asycmc(k,n) = cda3(k)
            else
              taucmc(k,n) = f_zero
!!            ssacmc(k,n) = f_one
!!            asycmc(k,n) = f_zero
            endif
          enddo
        enddo

      else                           ! cloud liq/ice paths are inputs

!  --- ...  where there is a cloud, set the subcolumn cloud properties.

        do k = 1, nlay
          do n = 1, nsub
            if ( lcloudy(k,n) ) then
              cliqmc(k,n) = cliqp(k)
              cicemc(k,n) = cicep(k)
              cranmc(k,n) = cda1 (k)
              csnwmc(k,n) = cda3 (k)
            else
              cliqmc(k,n) = f_zero
              cicemc(k,n) = f_zero
              cranmc(k,n) = f_zero
              csnwmc(k,n) = f_zero
            endif
          enddo
        enddo

      endif

! ..................................
      end subroutine mcica_subcol
! ----------------------------------


! ----------------------------------
      subroutine rtrn                                                   &
! ..................................
!  ---  inputs:
     &     ( semiss,delp,cldfrc,taucld,secdif,                          &
     &       pklay,pklev,pkbnd,fracs,tautot,                            &
     &       nlay, nlp1,                                                &
!  ---  outputs:
     &       totuflux,totdflux,htr, totuclfl,totdclfl,htrcl, htrb       &
     &     )

!  ===================  program usage description  ===================  !
!                                                                       !
! purpose:  compute the upward/downward radiative fluxes, and heating   !
! rates for both clear or cloudy atmosphere.  clouds are assumed as     !
! randomly overlaping in a vertical colum.                              !
!                                                                       !
! subprograms called:  none                                             !
!                                                                       !
!  ====================  defination of variables  ====================  !
!                                                                       !
!  inputs:                                                     -size-   !
!   semiss  - real, lw surface emissivity                         nbands!
!   delp    - real, layer pressure thickness (mb)                  nlay !
!   cldfrc  - real, layer cloud fraction                         0:nlp1 !
!   taucld  - real, layer cloud opt depth                    nlay*ngptlw!
!   secdif  - real, secant of diffusivity angle                   nbands!
!   pklay   - real, integrated planck func at lay temp       nlay*nbands!
!   pklev   - real, integrated planck func at lev temp     0:nlay*nbands!
!   pkbnd   - real, planck value for each band                    nbands!
!   fracs   - real, planck fractions                         nlay*ngptlw!
!   tautot  - real, total optical depth (gas+aerosols)       nlay*ngptlw!
!   nlay    - integer, number of vertical layers                    1   !
!   nlp1    - integer, number of vertical levels (interfaces)       1   !
!                                                                       !
!  outputs:                                                             !
!   totuflux- real, total sky upward flux (w/m2)                 0:nlay !
!   totdflux- real, total sky downward flux (w/m2)               0:nlay !
!   htr     - real, total sky heating rate (k/sec or k/day)        nlay !
!   totuclfl- real, clear sky upward flux (w/m2)                 0:nlay !
!   totdclfl- real, clear sky downward flux (w/m2)               0:nlay !
!   htrcl   - real, clear sky heating rate (k/sec or k/day)        nlay !
!   htrb    - real, spectral band lw heating rate (k/day)    nlay*nbands!
!                                                                       !
!  module veriables:                                                    !
!   delwave - real, band wavenumber intervals                     nbands!
!   ngb     - integer, band index for each g-value                ngptlw!
!   fluxfac - real, conversion factor for fluxes (pi*2.e4)           1  !
!   heatfac - real, conversion factor for heating rates (g/cp*1e-2)  1  !
!   tblint  - real, conversion factor for look-up tbl (float(ntbl)   1  !
!   bpade   - real, pade approx constant (1/0.278)                   1  !
!   wtdiff  - real, weight for radiance to flux conversion           1  !
!   ntbl    - integer, dimension of look-up tables                   1  !
!   tau_tbl - real, clr-sky opt dep lookup table                 0:ntbl !
!   exp_tbl - real, transmittance lookup table                   0:ntbl !
!   tfn_tbl - real, tau transition function                      0:ntbl !
!                                                                       !
!  local variables:                                                     !
!    itgas  - integer, index for gases contribution look-up table    1  !
!    ittot  - integer, index for gases plus clouds  look-up table    1  !
!    reflct - real, surface reflectance                              1  !
!    atrgas - real, gaseous absorptivity                           nlay !
!    atrtot - real, gaseous and cloud absorptivity                 nlay !
!    odcld  - real, cloud optical depth                      nlay*ngptlw!
!    odepth - real, optical depth of gaseous only                    1  !
!    odtot  - real, optical depth of gas and cloud                   1  !
!    gasfac - real, gas-only pade factor, used for planck function   1  !
!    totfac - real, gas and cloud pade factor, used for planck fn    1  !
!    bbdgas - real, gas-only planck function for downward rt         1  !
!    bbugas - real, gas-only planck function for upward rt         nlay !
!    bbdtot - real, gas and cloud planck function for downward rt    1  !
!    bbutot - real, gas and cloud planck function for upward rt    nlay !
!    gassrc - real, source radiance due to gas only                  1  !
!    totsrc - real, source radiance due to gas and cloud             1  !
!    efclrfr- real, effective clear sky fraction (1-efcldfr) nlay*ngptlw!
!    rtotu  - real, spectrally summed total sky upward radiance      1  !
!    rclru  - real, spectrally summed clear sky upward radiance      1  !
!    toturad- real, total sky upward radiance by layer     0:nlay*nbands!
!    clrurad- real, clear sky upward radiance by layer     0:nlay,nbands!
!    totdrad- real, total sky downward radiance by layer   0:nlay,nbands!
!    clrdrad- real, clear sky downward radiance by layer   0:nlay,nbands!
!    radtotd- real, spectrally summed total sky downward radiance    1  !
!    radclrd- real, spectrally summed clear sky downward radiance    1  !
!    fnet   - real, net longwave flux (w/m2)                     0:nlay !
!    fnetc  - real, clear sky net longwave flux (w/m2)           0:nlay !
!                                                                       !
!                                                                       !
!  *******************************************************************  !
!  original code description                                            !
!                                                                       !
!  original version:   e. j. mlawer, et al. rrtm_v3.0                   !
!  revision for gcms:  michael j. iacono; october, 2002                 !
!  revision for f90:   michael j. iacono; june, 2006                    !
!                                                                       !
!  this program calculates the upward fluxes, downward fluxes, and      !
!  heating rates for an arbitrary clear or cloudy atmosphere. the input !
!  to this program is the atmospheric profile, all Planck function      !
!  information, and the cloud fraction by layer.  a variable diffusivity!
!  angle (secdif) is used for the angle integration. bands 2-3 and 5-9  !
!  use a value for secdif that varies from 1.50 to 1.80 as a function   !
!  of the column water vapor, and other bands use a value of 1.66.  the !
!  gaussian weight appropriate to this angle (wtdiff=0.5) is applied    !
!  here.  note that use of the emissivity angle for the flux integration!
!  can cause errors of 1 to 4 W/m2 within cloudy layers.                !
!  clouds are treated with a random cloud overlap method.               !
!                                                                       !
!  *******************************************************************  !
!  ======================  end of description block  =================  !

!  ---  inputs:
      integer, intent(in) :: nlay, nlp1

      real (kind=kind_phys), dimension(0:),  intent(in) :: cldfrc
      real (kind=kind_phys), dimension(:),   intent(in) :: semiss,      &
     &       delp, secdif, pkbnd

      real (kind=kind_phys), dimension(:,:), intent(in) :: taucld,      &
     &       pklay, fracs, tautot

      real (kind=kind_phys), dimension(0:,:),intent(in) :: pklev

!  ---  outputs:
      real (kind=kind_phys), dimension(:),  intent(out) :: htr, htrcl
      real (kind=kind_phys), dimension(:,:),intent(out) :: htrb

      real (kind=kind_phys), dimension(0:), intent(out) ::              &
     &       totuflux, totdflux, totuclfl, totdclfl

!  ---  locals:
      real (kind=kind_phys), parameter :: rec_6 = 0.166667

      real (kind=kind_phys), dimension(0:nlay,nbands) :: clrurad,       &
     &       clrdrad, toturad, totdrad
      real (kind=kind_phys), dimension(nlay,ngptlw) :: efclrfr, odcld

      real (kind=kind_phys), dimension(0:nlay) :: fnet, fnetc
      real (kind=kind_phys), dimension(nlay)   :: atrtot, atrgas,       &
     &        bbugas, bbutot, trngas

      real (kind=kind_phys) :: totsrc, gassrc, tblind, odepth, odtot,   &
     &        trntot, reflct, totfac, gasfac, flxfac, rtotu, rclru,     &
     &        plfrac, blay, bbdgas, bbdtot, dplnku, dplnkd, rad0,       &
     &        radtotd, radclrd

      integer :: ittot, itgas, ib, ig, k
!
!===> ...  begin here
!
      toturad = f_zero
      totdrad = f_zero
      clrurad = f_zero
      clrdrad = f_zero

      totuflux(0) = f_zero
      totdflux(0) = f_zero
      totuclfl(0) = f_zero
      totdclfl(0) = f_zero

      do k = 1, nlay
        totuflux(k) = f_zero
        totdflux(k) = f_zero
        totuclfl(k) = f_zero
        totdclfl(k) = f_zero
      enddo

      odcld  (:,:) = f_zero
      efclrfr(:,:) = f_one

      do ig = 1, ngptlw
        ib = ngb(ig)

        do k = 1, nlay
          if (cldfrc(k) >= eps) then
            odcld(k,ig) = secdif(ib) * taucld(k,ig)
            efclrfr(k,ig) = f_one-(f_one-exp(-odcld(k,ig)))*cldfrc(k)
          endif
        enddo
      enddo

!  --- ...  loop over all g-points

      do ig = 1, ngptlw
        ib = ngb(ig)

        radtotd = f_zero
        radclrd = f_zero

!  --- ...  downward radiative transfer loop.

        do k = nlay, 1, -1

          plfrac = fracs(k,ig)
          blay = pklay(k,ib)
          dplnku = pklev(k,ib) - blay
          dplnkd = pklev(k-1,ib) - blay
          odepth = max( f_zero, secdif(ib)*tautot(k,ig) )

!  --- ...  clear sky, gases contribution

          if (odepth <= 0.06) then
            atrgas(k) = odepth - 0.5*odepth*odepth
            trngas(k) = f_one - atrgas(k)
            gasfac    = rec_6 * odepth
          else
            tblind = odepth / (bpade + odepth)
            itgas = tblint*tblind + 0.5
            trngas(k) = exp_tbl(itgas)
            atrgas(k) = f_one - trngas(k)
            gasfac    = tfn_tbl(itgas)
          endif

          bbdgas    = plfrac*(blay + dplnkd*gasfac)
          bbugas(k) = plfrac*(blay + dplnku*gasfac)
          gassrc    = bbdgas*atrgas(k)

!  --- ...  total sky, gases+clouds contribution

          if (cldfrc(k) >= eps) then
!  --- ...  it is a cloudy layer

            odtot = odepth + odcld(k,ig)

            if (odtot < 0.06) then
              totfac    = rec_6 * odtot
              atrtot(k) = odtot - 0.5*odtot*odtot
              trntot    = f_one - atrtot(k)
            elseif (odepth <= 0.06) then
              tblind = odtot / (bpade + odtot)
              ittot  = tblint*tblind + 0.5

              totfac    = tfn_tbl(ittot)
              trntot    = exp_tbl(ittot)
              atrtot(k) = f_one - trntot
            else
              odepth = tau_tbl(itgas)
              odtot  = odepth + odcld(k,ig)
              tblind = odtot / (bpade + odtot)
              ittot  = tblint*tblind + 0.5

              totfac    = tfn_tbl(ittot)
              trntot    = exp_tbl(ittot)
              atrtot(k) = f_one - trntot
            endif

            bbdtot    = plfrac*(blay + dplnkd*totfac)
            bbutot(k) = plfrac*(blay + dplnku*totfac)
            totsrc    = bbdtot*atrtot(k)

!  --- ...  total sky radiance
            radtotd = radtotd*trngas(k)*efclrfr(k,ig) + gassrc          &
     &              + cldfrc(k)*(totsrc - gassrc)
            totdrad(k-1,ib) = totdrad(k-1,ib) + radtotd

!  --- ...  clear sky radiance
            radclrd = radclrd*trngas(k) + gassrc
            clrdrad(k-1,ib) = clrdrad(k-1,ib) + radclrd

          else

!  --- ...  it is a clear layer
            radtotd = radtotd*trngas(k) + gassrc
            totdrad(k-1,ib) = totdrad(k-1,ib) + radtotd

            radclrd = radclrd*trngas(k) + gassrc
            clrdrad(k-1,ib) = clrdrad(k-1,ib) + radclrd

          endif

        enddo   ! end do_k_loop

!  --- ...  spectral emissivity & reflectance
!           include the contribution of spectrally varying longwave emissivity
!           and reflection from the surface to the upward radiative transfer.
!     note: spectral and Lambertian reflection are identical for the
!           diffusivity angle flux integration used here.

        rad0 = fracs(1,ig) * pkbnd(ib)

!  --- ...  add in reflection of surface downward radiance.
        reflct = f_one - semiss(ib)
        rtotu = rad0 + reflct*radtotd
        rclru = rad0 + reflct*radclrd

!  --- ...  upward radiative transfer loop.
        toturad(0,ib) = toturad(0,ib) + rtotu
        clrurad(0,ib) = clrurad(0,ib) + rclru

        do k = 1, nlay

          gassrc = bbugas(k)*atrgas(k)
          totsrc = bbutot(k)*atrtot(k)

          if (cldfrc(k) >= eps) then

!  --- ...  it is a cloudy layer
            rtotu = rtotu*trngas(k)*efclrfr(k,ig) + gassrc              &
     &            + cldfrc(k)*(totsrc - gassrc)
            toturad(k,ib) = toturad(k,ib) + rtotu

            rclru = rclru*trngas(k) + gassrc
            clrurad(k,ib) = clrurad(k,ib) + rclru

          else

!  --- ...  it is a clear layer
            rtotu = rtotu*trngas(k) + gassrc
            toturad(k,ib) = toturad(k,ib) + rtotu

            rclru = rclru*trngas(k) + gassrc
            clrurad(k,ib) = clrurad(k,ib) + rclru

          endif

        enddo   ! end do_k_loop

      enddo   ! end do_ig_loop

!  --- ...  process longwave output from band for total and clear streams.
!           calculate upward, downward, and net flux.

      do ib = 1, nbands
        flxfac = wtdiff * fluxfac * delwave(ib)

        do k = 0, nlay
          toturad(k,ib) = toturad(k,ib) * flxfac
          totdrad(k,ib) = totdrad(k,ib) * flxfac
          clrurad(k,ib) = clrurad(k,ib) * flxfac
          clrdrad(k,ib) = clrdrad(k,ib) * flxfac

          totuflux(k) = totuflux(k) + toturad(k,ib)
          totdflux(k) = totdflux(k) + totdrad(k,ib)
          totuclfl(k) = totuclfl(k) + clrurad(k,ib)
          totdclfl(k) = totdclfl(k) + clrdrad(k,ib)
        enddo
      enddo

!  --- ...  calculate net fluxes and heating rates
      fnet(0) = totuflux(0) - totdflux(0)

      do k = 1, nlay
        fnet(k) = totuflux(k) - totdflux(k)
        htr (k) = heatfac*(fnet(k-1) - fnet(k)) / delp(k)
      enddo

!! --- ...  optional clear sky heating rates
      if ( lhlw0 ) then
        fnetc(0) = totuclfl(0) - totdclfl(0)

        do k = 1, nlay
          fnetc(k) = totuclfl(k) - totdclfl(k)
          htrcl(k) = heatfac*(fnetc(k-1)-fnetc(k)) / delp(k)
        enddo
      endif

!! --- ...  optional spectral band heating rates
      if ( lhlwb ) then
        do ib = 1, nbands
          fnet(0) = toturad(0,ib) - totdrad(0,ib)

          do k = 1, nlay
            fnet(k) = toturad(k,ib) - totdrad(k,ib)
            htrb(k,ib) = heatfac*(fnet(k-1)-fnet(k)) / delp(k)
          enddo
        enddo
      endif

! ..................................
      end subroutine rtrn
! ----------------------------------


! ----------------------------------
      subroutine rtrnmr                                                 &
! ..................................
!  ---  inputs:
     &     ( semiss,delp,cldfrc,taucld,secdif,                          &
     &       pklay,pklev,pkbnd,fracs,tautot,                            &
     &       nlay, nlp1,                                                &
!  ---  outputs:
     &       totuflux,totdflux,htr, totuclfl,totdclfl,htrcl, htrb       &
     &     )

!  ===================  program usage description  ===================  !
!                                                                       !
! purpose:  compute the upward/downward radiative fluxes, and heating   !
! rates for both clear or cloudy atmosphere.  clouds are assumed as in  !
! maximum-randomly overlaping in a vertical colum.                      !
!                                                                       !
! subprograms called:  none                                             !
!                                                                       !
!  ====================  defination of variables  ====================  !
!                                                                       !
!  inputs:                                                     -size-   !
!   semiss  - real, lw surface emissivity                         nbands!
!   delp    - real, layer pressure thickness (mb)                  nlay !
!   cldfrc  - real, layer cloud fraction                         0:nlp1 !
!   taucld  - real, layer cloud opt depth                    nlay*ngptlw!
!   secdif  - real, secant of diffusivity angle                   nbands!
!   pklay   - real, integrated planck func at lay temp       nlay*nbands!
!   pklev   - real, integrated planck func at lev temp     0:nlay*nbands!
!   pkbnd   - real, planck value for each band                    nbands!
!   fracs   - real, planck fractions                         nlay*ngptlw!
!   tautot  - real, total optical depth (gas+aerosols)       nlay*ngptlw!
!   nlay    - integer, number of vertical layers                    1   !
!   nlp1    - integer, number of vertical levels (interfaces)       1   !
!                                                                       !
!  outputs:                                                             !
!   totuflux- real, total sky upward flux (w/m2)                 0:nlay !
!   totdflux- real, total sky downward flux (w/m2)               0:nlay !
!   htr     - real, total sky heating rate (k/sec or k/day)        nlay !
!   totuclfl- real, clear sky upward flux (w/m2)                 0:nlay !
!   totdclfl- real, clear sky downward flux (w/m2)               0:nlay !
!   htrcl   - real, clear sky heating rate (k/sec or k/day)        nlay !
!   htrb    - real, spectral band lw heating rate (k/day)    nlay*nbands!
!                                                                       !
!  module veriables:                                                    !
!   delwave - real, band wavenumber intervals                     nbands!
!   ngb     - integer, band index for each g-value                ngptlw!
!   fluxfac - real, conversion factor for fluxes (pi*2.e4)           1  !
!   heatfac - real, conversion factor for heating rates (g/cp*1e-2)  1  !
!   tblint  - real, conversion factor for look-up tbl (float(ntbl)   1  !
!   bpade   - real, pade approx constant (1/0.278)                   1  !
!   wtdiff  - real, weight for radiance to flux conversion           1  !
!   ntbl    - integer, dimension of look-up tables                   1  !
!   tau_tbl - real, clr-sky opt dep lookup table                 0:ntbl !
!   exp_tbl - real, transmittance lookup table                   0:ntbl !
!   tfn_tbl - real, tau transition function                      0:ntbl !
!                                                                       !
!  local variables:                                                     !
!    itgas  - integer, index for gases contribution look-up table    1  !
!    ittot  - integer, index for gases plus clouds  look-up table    1  !
!    reflct - real, surface reflectance                              1  !
!    atrgas - real, gaseous absorptivity                           nlay !
!    atrtot - real, gaseous and cloud absorptivity                 nlay !
!    odcld  - real, cloud optical depth                      nlay*ngptlw!
!    odepth - real, optical depth of gaseous only                    1  !
!    odtot  - real, optical depth of gas and cloud                   1  !
!    gasfac - real, gas-only pade factor, used for planck function   1  !
!    totfac - real, gas and cloud pade factor, used for planck fn    1  !
!    bbdgas - real, gas-only planck function for downward rt         1  !
!    bbugas - real, gas-only planck function for upward rt         nlay !
!    bbdtot - real, gas and cloud planck function for downward rt    1  !
!    bbutot - real, gas and cloud planck function for upward rt    nlay !
!    gassrc - real, source radiance due to gas only                  1  !
!    totsrc - real, source radiance due to gas and cloud             1  !
!    efclrfr- real, effective clear sky fraction (1-efcldfr) nlay*ngptlw!
!    rtotu  - real, spectrally summed total sky upward radiance      1  !
!    rclru  - real, spectrally summed clear sky upward radiance      1  !
!    toturad- real, total sky upward radiance by layer     0:nlay*nbands!
!    clrurad- real, clear sky upward radiance by layer     0:nlay,nbands!
!    totdrad- real, total sky downward radiance by layer   0:nlay,nbands!
!    clrdrad- real, clear sky downward radiance by layer   0:nlay,nbands!
!    radtotd- real, spectrally summed total sky downward radiance    1  !
!    radclrd- real, spectrally summed clear sky downward radiance    1  !
!    fnet   - real, net longwave flux (w/m2)                     0:nlay !
!    fnetc  - real, clear sky net longwave flux (w/m2)           0:nlay !
!                                                                       !
!                                                                       !
!  *******************************************************************  !
!  original code description                                            !
!                                                                       !
!  original version:   e. j. mlawer, et al. rrtm_v3.0                   !
!  revision for gcms:  michael j. iacono; october, 2002                 !
!  revision for f90:   michael j. iacono; june, 2006                    !
!                                                                       !
!  this program calculates the upward fluxes, downward fluxes, and      !
!  heating rates for an arbitrary clear or cloudy atmosphere. the input !
!  to this program is the atmospheric profile, all Planck function      !
!  information, and the cloud fraction by layer.  a variable diffusivity!
!  angle (secdif) is used for the angle integration. bands 2-3 and 5-9  !
!  use a value for secdif that varies from 1.50 to 1.80 as a function   !
!  of the column water vapor, and other bands use a value of 1.66.  the !
!  gaussian weight appropriate to this angle (wtdiff=0.5) is applied    !
!  here.  note that use of the emissivity angle for the flux integration!
!  can cause errors of 1 to 4 W/m2 within cloudy layers.                !
!  clouds are treated with a maximum-random cloud overlap method.       !
!                                                                       !
!  *******************************************************************  !
!  ======================  end of description block  =================  !

!  ---  inputs:
      integer, intent(in) :: nlay, nlp1

      real (kind=kind_phys), dimension(0:),  intent(in) :: cldfrc
      real (kind=kind_phys), dimension(:),   intent(in) :: semiss,      &
     &       delp, secdif, pkbnd

      real (kind=kind_phys), dimension(:,:), intent(in) :: taucld,      &
     &       pklay, fracs, tautot

      real (kind=kind_phys), dimension(0:,:),intent(in) :: pklev

!  ---  outputs:
      real (kind=kind_phys), dimension(:),  intent(out) :: htr, htrcl
      real (kind=kind_phys), dimension(:,:),intent(out) :: htrb

      real (kind=kind_phys), dimension(0:), intent(out) ::              &
     &       totuflux, totdflux, totuclfl, totdclfl

!  ---  locals:
      real (kind=kind_phys), parameter :: rec_6 = 0.166667

      real (kind=kind_phys), dimension(0:nlay,nbands) :: clrurad,       &
     &       clrdrad, toturad, totdrad
      real (kind=kind_phys), dimension(nlay,ngptlw) :: odcld

      real (kind=kind_phys), dimension(0:nlay) :: fnet, fnetc
      real (kind=kind_phys), dimension(nlay)   :: atrtot, atrgas,       &
     &        bbugas, bbutot, trngas

      real (kind=kind_phys) :: totsrc, gassrc, tblind, odepth, odtot,   &
     &        trntot, reflct, totfac, gasfac, flxfac, rtotu, rclru,     &
     &        plfrac, blay, bbdgas, bbdtot, dplnku, dplnkd, rad0,       &
     &        radtotd, radclrd, totradd, clrradd, totradu, clrradu,     &
     &        fmax, fmin, rat1, rat2, rad, radmod

      integer :: ittot, itgas, ib, ig, k

!  dimensions for cloud overlap adjustment
      real (kind=kind_phys), dimension(nlp1) :: faccld1u, faccld2u,     &
     &        facclr1u, facclr2u, faccmb1u, faccmb2u
      real (kind=kind_phys), dimension(0:nlay) :: faccld1d, faccld2d,   &
     &        facclr1d, facclr2d, faccmb1d, faccmb2d

      logical :: lstcldu(nlay), lstcldd(nlay)
!
!===> ...  begin here
!
      do k = 1, nlp1
        faccld1u(k) = f_zero
        faccld2u(k) = f_zero
        facclr1u(k) = f_zero
        facclr2u(k) = f_zero
        faccmb1u(k) = f_zero
        faccmb2u(k) = f_zero
      enddo

      lstcldu(1) = cldfrc(1) > eps
      rat1 = f_zero
      rat2 = f_zero

      do k = 1, nlay-1

        lstcldu(k+1) = cldfrc(k+1)>eps .and. cldfrc(k)<=eps

        if (cldfrc(k) > eps) then
!  --- ...  maximum/random cloud overlap

          if (cldfrc(k+1) >= cldfrc(k)) then
            if (lstcldu(k)) then
              if (cldfrc(k) < f_one) then
                facclr2u(k+1) = (cldfrc(k+1) - cldfrc(k))               &
     &                        / (f_one - cldfrc(k))
              endif
              facclr2u(k) = f_zero
              faccld2u(k) = f_zero
            else
              fmax = max(cldfrc(k), cldfrc(k-1))
              if (cldfrc(k+1) > fmax) then
                facclr1u(k+1) = rat2
                facclr2u(k+1) = (cldfrc(k+1) - fmax)/(f_one - fmax)
              elseif (cldfrc(k+1) < fmax) then
                facclr1u(k+1) = (cldfrc(k+1) - cldfrc(k))               &
     &                        / (cldfrc(k-1) - cldfrc(k))
              else
                facclr1u(k+1) = rat2
              endif
            endif

            if (facclr1u(k+1)>f_zero .or. facclr2u(k+1)>f_zero) then
              rat1 = f_one
              rat2 = f_zero
            else
              rat1 = f_zero
              rat2 = f_zero
            endif
          else
            if (lstcldu(k)) then
              faccld2u(k+1) = (cldfrc(k) - cldfrc(k+1)) / cldfrc(k)
              facclr2u(k) = f_zero
              faccld2u(k) = f_zero
            else
              fmin = min(cldfrc(k), cldfrc(k-1))
              if (cldfrc(k+1) <= fmin) then
                faccld1u(k+1) = rat1
                faccld2u(k+1) = (fmin - cldfrc(k+1)) / fmin
              else
                faccld1u(k+1) = (cldfrc(k) - cldfrc(k+1))               &
     &                        / (cldfrc(k) - fmin)
              endif
            endif

            if (faccld1u(k+1)>f_zero .or. faccld2u(k+1)>f_zero) then
              rat1 = f_zero
              rat2 = f_one
            else
              rat1 = f_zero
              rat2 = f_zero
            endif
          endif

          faccmb1u(k+1) = facclr1u(k+1) * faccld2u(k) * cldfrc(k-1)
          faccmb2u(k+1) = faccld1u(k+1) * facclr2u(k)                   &
     &                  * (f_one - cldfrc(k-1))
        endif

      enddo

      do k = 0, nlay
        faccld1d(k) = f_zero
        faccld2d(k) = f_zero
        facclr1d(k) = f_zero
        facclr2d(k) = f_zero
        faccmb1d(k) = f_zero
        faccmb2d(k) = f_zero
      enddo

      lstcldd(nlay) = cldfrc(nlay) > eps
      rat1 = f_zero
      rat2 = f_zero

      do k = nlay, 2, -1

        lstcldd(k-1) = cldfrc(k-1) > eps .and. cldfrc(k)<=eps

        if (cldfrc(k) > eps) then

          if (cldfrc(k-1) >= cldfrc(k)) then
            if (lstcldd(k)) then
              if (cldfrc(k) < f_one) then
                facclr2d(k-1) = (cldfrc(k-1) - cldfrc(k))               &
     &                        / (f_one - cldfrc(k))
              endif

              facclr2d(k) = f_zero
              faccld2d(k) = f_zero
            else
              fmax = max(cldfrc(k), cldfrc(k+1))

              if (cldfrc(k-1) > fmax) then
                facclr1d(k-1) = rat2
                facclr2d(k-1) = (cldfrc(k-1) - fmax) / (f_one - fmax)
              elseif (cldfrc(k-1) < fmax) then
                facclr1d(k-1) = (cldfrc(k-1) - cldfrc(k))               &
     &                        / (cldfrc(k+1) - cldfrc(k))
              else
                facclr1d(k-1) = rat2
              endif
            endif

            if (facclr1d(k-1)>f_zero .or. facclr2d(k-1)>f_zero) then
              rat1 = f_one
              rat2 = f_zero
            else
              rat1 = f_zero
              rat2 = f_zero
            endif
          else
            if (lstcldd(k)) then
              faccld2d(k-1) = (cldfrc(k) - cldfrc(k-1)) / cldfrc(k)
              facclr2d(k) = f_zero
              faccld2d(k) = f_zero
            else
              fmin = min(cldfrc(k), cldfrc(k+1))

              if (cldfrc(k-1) <= fmin) then
                faccld1d(k-1) = rat1
                faccld2d(k-1) = (fmin - cldfrc(k-1)) / fmin
              else
                faccld1d(k-1) = (cldfrc(k) - cldfrc(k-1))               &
     &                        / (cldfrc(k) - fmin)
              endif
            endif

            if (faccld1d(k-1)>f_zero .or. faccld2d(k-1)>f_zero) then
              rat1 = f_zero
              rat2 = f_one
            else
              rat1 = f_zero
              rat2 = f_zero
            endif
          endif

          faccmb1d(k-1) = facclr1d(k-1) * faccld2d(k) * cldfrc(k+1)
          faccmb2d(k-1) = faccld1d(k-1) * facclr2d(k)                   &
     &                  * (f_one - cldfrc(k+1))
        endif

      enddo

      toturad = f_zero
      totdrad = f_zero
      clrurad = f_zero
      clrdrad = f_zero

      totuflux(0) = f_zero
      totdflux(0) = f_zero
      totuclfl(0) = f_zero
      totdclfl(0) = f_zero

      do k = 1, nlay
        totuflux(k) = f_zero
        totdflux(k) = f_zero
        totuclfl(k) = f_zero
        totdclfl(k) = f_zero
      enddo

      odcld(:,:) = f_zero
      do ig = 1, ngptlw
        ib = ngb(ig)

        do k = 1, nlay
          if (cldfrc(k) >= eps) then
            odcld(k,ig) = secdif(ib) * taucld(k,ig)
          endif
        enddo
      enddo

!  --- ...  loop over all g-points

      do ig = 1, ngptlw
        ib = ngb(ig)

        radtotd = f_zero
        radclrd = f_zero

!  --- ...  downward radiative transfer loop.

        do k = nlay, 1, -1

          plfrac = fracs(k,ig)
          blay = pklay(k,ib)
          dplnku = pklev(k,ib) - blay
          dplnkd = pklev(k-1,ib) - blay
          odepth = max( f_zero, secdif(ib)*tautot(k,ig) )

!  --- ...  clear sky, gases contribution

          if (odepth <= 0.06) then
            atrgas(k) = odepth - 0.5*odepth*odepth
            trngas(k) = f_one - atrgas(k)
            gasfac    = rec_6 * odepth
          else
            tblind = odepth / (bpade + odepth)
            itgas = tblint*tblind + 0.5
            trngas(k) = exp_tbl(itgas)
            atrgas(k) = f_one - trngas(k)
            gasfac    = tfn_tbl(itgas)
          endif

          bbdgas    = plfrac*(blay + dplnkd*gasfac)
          bbugas(k) = plfrac*(blay + dplnku*gasfac)
          gassrc    = bbdgas*atrgas(k)

!  --- ...  total sky, gases+clouds contribution

          if (lstcldd(k)) then
            totradd = cldfrc(k) * radtotd
            clrradd = radtotd - totradd
            rad = f_zero
          endif

          if (cldfrc(k) >= eps) then
!  --- ...  it is a cloudy layer

            odtot = odepth + odcld(k,ig)

            if (odtot < 0.06) then
              totfac    = rec_6 * odtot
              atrtot(k) = odtot - 0.5*odtot*odtot
              trntot    = f_one - atrtot(k)
            elseif (odepth <= 0.06) then
              tblind = odtot / (bpade + odtot)
              ittot  = tblint*tblind + 0.5

              totfac    = tfn_tbl(ittot)
              trntot    = exp_tbl(ittot)
              atrtot(k) = f_one - trntot
            else
              odepth = tau_tbl(itgas)
              odtot  = odepth + odcld(k,ig)
              tblind = odtot / (bpade + odtot)
              ittot  = tblint*tblind + 0.5

              totfac    = tfn_tbl(ittot)
              trntot    = exp_tbl(ittot)
              atrtot(k) = f_one - trntot
            endif

            bbdtot    = plfrac*(blay + dplnkd*totfac)
            bbutot(k) = plfrac*(blay + dplnku*totfac)
            totsrc    = bbdtot*atrtot(k)

            totradd = totradd*trntot + cldfrc(k)*totsrc
            clrradd = clrradd*trngas(k) + (f_one - cldfrc(k))*gassrc

!  --- ...  total sky radiance
            radtotd = totradd + clrradd
            totdrad(k-1,ib) = totdrad(k-1,ib) + radtotd

!  --- ...  clear sky radiance
            radclrd = radclrd*trngas(k) + gassrc
            clrdrad(k-1,ib) = clrdrad(k-1,ib) + radclrd

            radmod = rad*(facclr1d(k-1)*trngas(k)+faccld1d(k-1)*trntot) &
     &             - faccmb1d(k-1)*gassrc + faccmb2d(k-1)*totsrc

            rad = -radmod + facclr2d(k-1)*(clrradd + radmod)            &
     &                    - faccld2d(k-1)*(totradd - radmod)
            totradd = totradd + rad
            clrradd = clrradd - rad

          else

!  --- ...  it is a clear layer
            radtotd = radtotd*trngas(k) + gassrc
            totdrad(k-1,ib) = totdrad(k-1,ib) + radtotd

            radclrd = radclrd*trngas(k) + gassrc
            clrdrad(k-1,ib) = clrdrad(k-1,ib) + radclrd

          endif

        enddo   ! end do_k_loop

!  --- ...  spectral emissivity & reflectance
!           include the contribution of spectrally varying longwave emissivity
!           and reflection from the surface to the upward radiative transfer.
!     note: spectral and Lambertian reflection are identical for the
!           diffusivity angle flux integration used here.

        rad0 = fracs(1,ig) * pkbnd(ib)

!  --- ...  add in reflection of surface downward radiance.
        reflct = 1.0 - semiss(ib)
        rtotu = rad0 + reflct*radtotd
        rclru = rad0 + reflct*radclrd

!  --- ...  upward radiative transfer loop.
        toturad(0,ib) = toturad(0,ib) + rtotu
        clrurad(0,ib) = clrurad(0,ib) + rclru

        do k = 1, nlay

          gassrc = bbugas(k)*atrgas(k)
          totsrc = bbutot(k)*atrtot(k)

          if (lstcldu(k)) then
            totradu = cldfrc(k) * rtotu
            clrradu = rtotu - totradu
            rad = f_zero
          endif

          if (cldfrc(k) >= eps) then

!  --- ...  it is a cloudy layer
            trntot = f_one - atrtot(k)
            totradu = totradu*trntot + cldfrc(k)*totsrc
            clrradu = clrradu*trngas(k) + (f_one - cldfrc(k))*gassrc

!  --- ...  total sky radiance
            rtotu = totradu + clrradu
            toturad(k,ib) = toturad(k,ib) + rtotu

!  --- ...  clear sky radiance
            rclru = rclru*trngas(k) + gassrc
            clrurad(k,ib) = clrurad(k,ib) + rclru

            radmod = rad*(facclr1u(k+1)*trngas(k)+faccld1u(k+1)*trntot) &
     &             - faccmb1u(k+1)*gassrc + faccmb2u(k+1)*totsrc
            rad = -radmod + facclr2u(k+1)*(clrradu + radmod)            &
     &                    - faccld2u(k+1)*(totradu - radmod)
            totradu = totradu + rad
            clrradu = clrradu - rad

          else

!  --- ...  it is a clear layer
            rtotu = rtotu*trngas(k) + gassrc
            toturad(k,ib) = toturad(k,ib) + rtotu

            rclru = rclru*trngas(k) + gassrc
            clrurad(k,ib) = clrurad(k,ib) + rclru

          endif

        enddo   ! end do_k_loop

      enddo   ! end do_ig_loop

!  --- ...  process longwave output from band for total and clear streams.
!           calculate upward, downward, and net flux.

      do ib = 1, nbands
        flxfac = wtdiff * fluxfac * delwave(ib)

        do k = 0, nlay
          toturad(k,ib) = toturad(k,ib) * flxfac
          totdrad(k,ib) = totdrad(k,ib) * flxfac
          clrurad(k,ib) = clrurad(k,ib) * flxfac
          clrdrad(k,ib) = clrdrad(k,ib) * flxfac

          totuflux(k) = totuflux(k) + toturad(k,ib)
          totdflux(k) = totdflux(k) + totdrad(k,ib)
          totuclfl(k) = totuclfl(k) + clrurad(k,ib)
          totdclfl(k) = totdclfl(k) + clrdrad(k,ib)
        enddo
      enddo

!  --- ...  calculate net fluxes and heating rates
      fnet(0) = totuflux(0) - totdflux(0)

      do k = 1, nlay
        fnet(k) = totuflux(k) - totdflux(k)
        htr (k) = heatfac*(fnet(k-1) - fnet(k)) / delp(k)
      enddo

!! --- ...  optional clear sky heating rates
      if ( lhlw0 ) then
        fnetc(0) = totuclfl(0) - totdclfl(0)

        do k = 1, nlay
          fnetc(k) = totuclfl(k) - totdclfl(k)
          htrcl(k) = heatfac*(fnetc(k-1)-fnetc(k)) / delp(k)
        enddo
      endif

!! --- ...  optional spectral band heating rates
      if ( lhlwb ) then
        do ib = 1, nbands
          fnet(0) = toturad(0,ib) - totdrad(0,ib)

          do k = 1, nlay
            fnet(k) = toturad(k,ib) - totdrad(k,ib)
            htrb(k,ib) = heatfac*(fnet(k-1)-fnet(k)) / delp(k)
          enddo
        enddo
      endif

! .................................
      end subroutine rtrnmr
! ---------------------------------


! ---------------------------------
      subroutine rtrnmc                                                 &
! .................................
!  ---  inputs:
     &     ( semiss,delp,cldfmc,taucmc,secdif,                          &
     &       pklay,pklev,pkbnd,fracs,tautot,                            &
     &       nlay, nlp1,                                                &
!  ---  outputs:
     &       totuflux,totdflux,htr, totuclfl,totdclfl,htrcl, htrb       &
     &     )

!  ===================  program usage description  ===================  !
!                                                                       !
! purpose:  compute the upward/downward radiative fluxes, and heating   !
! rates for both clear or cloudy atmosphere.  clouds are treated with   !
! the mcica stochastic approach.                                        !
!                                                                       !
! subprograms called:  none                                             !
!                                                                       !
!  ====================  defination of variables  ====================  !
!                                                                       !
!  inputs:                                                     -size-   !
!   semiss  - real, lw surface emissivity                         nbands!
!   delp    - real, layer pressure thickness (mb)                  nlay !
!   cldfmc  - real, layer cloud fraction                     nlay*ngptlw!
!   taucmc  - real, layer cloud opt depth                    nlay*ngptlw!
!   secdif  - real, secant of diffusivity angle                   nbands!
!   pklay   - real, integrated planck func at lay temp       nlay*nbands!
!   pklev   - real, integrated planck func at lev temp     0:nlay*nbands!
!   pkbnd   - real, planck value for each band                    nbands!
!   fracs   - real, planck fractions                         nlay*ngptlw!
!   tautot  - real, total optical depth (gas+aerosols)       nlay*ngptlw!
!   nlay    - integer, number of vertical layers                    1   !
!   nlp1    - integer, number of vertical levels (interfaces)       1   !
!                                                                       !
!  outputs:                                                             !
!   totuflux- real, total sky upward flux (w/m2)                 0:nlay !
!   totdflux- real, total sky downward flux (w/m2)               0:nlay !
!   htr     - real, total sky heating rate (k/sec or k/day)        nlay !
!   totuclfl- real, clear sky upward flux (w/m2)                 0:nlay !
!   totdclfl- real, clear sky downward flux (w/m2)               0:nlay !
!   htrcl   - real, clear sky heating rate (k/sec or k/day)        nlay !
!   htrb    - real, spectral band lw heating rate (k/day)    nlay*nbands!
!                                                                       !
!  module veriables:                                                    !
!   delwave - real, band wavenumber intervals                     nbands!
!   ngb     - integer, band index for each g-value                ngptlw!
!   fluxfac - real, conversion factor for fluxes (pi*2.e4)           1  !
!   heatfac - real, conversion factor for heating rates (g/cp*1e-2)  1  !
!   tblint  - real, conversion factor for look-up tbl (float(ntbl)   1  !
!   bpade   - real, pade approx constant (1/0.278)                   1  !
!   wtdiff  - real, weight for radiance to flux conversion           1  !
!   ntbl    - integer, dimension of look-up tables                   1  !
!   tau_tbl - real, clr-sky opt dep lookup table                 0:ntbl !
!   exp_tbl - real, transmittance lookup table                   0:ntbl !
!   tfn_tbl - real, tau transition function                      0:ntbl !
!                                                                       !
!  local variables:                                                     !
!    itgas  - integer, index for gases contribution look-up table    1  !
!    ittot  - integer, index for gases plus clouds  look-up table    1  !
!    reflct - real, surface reflectance                              1  !
!    atrgas - real, gaseous absorptivity                           nlay !
!    atrtot - real, gaseous and cloud absorptivity                 nlay !
!    odcld  - real, cloud optical depth                      nlay*ngptlw!
!    odepth - real, optical depth of gaseous only                    1  !
!    odtot  - real, optical depth of gas and cloud                   1  !
!    gasfac - real, gas-only pade factor, used for planck function   1  !
!    totfac - real, gas and cloud pade factor, used for planck fn    1  !
!    bbdgas - real, gas-only planck function for downward rt         1  !
!    bbugas - real, gas-only planck function for upward rt         nlay !
!    bbdtot - real, gas and cloud planck function for downward rt    1  !
!    bbutot - real, gas and cloud planck function for upward rt    nlay !
!    gassrc - real, source radiance due to gas only                  1  !
!    totsrc - real, source radiance due to gas and cloud             1  !
!    efclrfr- real, effective clear sky fraction (1-efcldfr) nlay*ngptlw!
!    rtotu  - real, spectrally summed total sky upward radiance      1  !
!    rclru  - real, spectrally summed clear sky upward radiance      1  !
!    toturad- real, total sky upward radiance by layer     0:nlay*nbands!
!    clrurad- real, clear sky upward radiance by layer     0:nlay,nbands!
!    totdrad- real, total sky downward radiance by layer   0:nlay,nbands!
!    clrdrad- real, clear sky downward radiance by layer   0:nlay,nbands!
!    radtotd- real, spectrally summed total sky downward radiance    1  !
!    radclrd- real, spectrally summed clear sky downward radiance    1  !
!    fnet   - real, net longwave flux (w/m2)                     0:nlay !
!    fnetc  - real, clear sky net longwave flux (w/m2)           0:nlay !
!                                                                       !
!                                                                       !
!  *******************************************************************  !
!  original code description                                            !
!                                                                       !
!  original version:   e. j. mlawer, et al. rrtm_v3.0                   !
!  revision for gcms:  michael j. iacono; october, 2002                 !
!  revision for f90:   michael j. iacono; june, 2006                    !
!                                                                       !
!  this program calculates the upward fluxes, downward fluxes, and      !
!  heating rates for an arbitrary clear or cloudy atmosphere. the input !
!  to this program is the atmospheric profile, all Planck function      !
!  information, and the cloud fraction by layer.  a variable diffusivity!
!  angle (secdif) is used for the angle integration. bands 2-3 and 5-9  !
!  use a value for secdif that varies from 1.50 to 1.80 as a function   !
!  of the column water vapor, and other bands use a value of 1.66.  the !
!  gaussian weight appropriate to this angle (wtdiff=0.5) is applied    !
!  here.  note that use of the emissivity angle for the flux integration!
!  can cause errors of 1 to 4 W/m2 within cloudy layers.                !
!  clouds are treated with the mcica stochastic approach and            !
!  maximum-random cloud overlap.                                        !
!                                                                       !
!  *******************************************************************  !
!  ======================  end of description block  =================  !

!  ---  inputs:
      integer, intent(in) :: nlay, nlp1

      real (kind=kind_phys), dimension(:),   intent(in) :: semiss,      &
     &       delp, secdif, pkbnd

      real (kind=kind_phys), dimension(:,:), intent(in) :: taucmc,      &
     &       cldfmc, pklay, fracs, tautot

      real (kind=kind_phys), dimension(0:,:),intent(in) :: pklev

!  ---  outputs:
      real (kind=kind_phys), dimension(:),  intent(out) :: htr, htrcl
      real (kind=kind_phys), dimension(:,:),intent(out) :: htrb

      real (kind=kind_phys), dimension(0:), intent(out) ::              &
     &       totuflux, totdflux, totuclfl, totdclfl

!  ---  locals:
      real (kind=kind_phys), parameter :: rec_6 = 0.166667

      real (kind=kind_phys), dimension(0:nlay,nbands) :: clrurad,       &
     &       clrdrad, toturad, totdrad
      real (kind=kind_phys), dimension(nlay,ngptlw) :: efclrfr, odcld

      real (kind=kind_phys), dimension(0:nlay) :: fnet, fnetc
      real (kind=kind_phys), dimension(nlay)   :: atrtot, atrgas,       &
     &        bbugas, bbutot, trngas

      real (kind=kind_phys) :: totsrc, gassrc, tblind, odepth, odtot,   &
     &        trntot, reflct, totfac, gasfac, flxfac, rtotu, rclru,     &
     &        plfrac, blay, bbdgas, bbdtot, dplnku, dplnkd, rad0,       &
     &        radtotd, radclrd

      integer :: ittot, itgas, ib, ig, k
!
!===> ...  begin here
!
      toturad = f_zero
      totdrad = f_zero
      clrurad = f_zero
      clrdrad = f_zero

      totuflux(0) = f_zero
      totdflux(0) = f_zero
      totuclfl(0) = f_zero
      totdclfl(0) = f_zero

      do k = 1, nlay
        totuflux(k) = f_zero
        totdflux(k) = f_zero
        totuclfl(k) = f_zero
        totdclfl(k) = f_zero
      enddo

      do ig = 1, ngptlw
        ib = ngb(ig)

        do k = 1, nlay
          if (cldfmc(k,ig) >= eps) then
            odcld(k,ig) = secdif(ib) * taucmc(k,ig)
            efclrfr(k,ig) = f_one-(f_one-exp(-odcld(k,ig)))*cldfmc(k,ig)
          else
            odcld(k,ig) = f_zero
            efclrfr(k,ig) = f_one
          endif
        enddo
      enddo

!  --- ...  loop over all g-points

      do ig = 1, ngptlw
        ib = ngb(ig)

        radtotd = f_zero
        radclrd = f_zero

!  --- ...  downward radiative transfer loop.

        do k = nlay, 1, -1

          plfrac = fracs(k,ig)
          blay = pklay(k,ib)
          dplnku = pklev(k,ib) - blay
          dplnkd = pklev(k-1,ib) - blay
          odepth = max( f_zero, secdif(ib)*tautot(k,ig) )

!  --- ...  clear sky, gases contribution

          if (odepth <= 0.06) then
            atrgas(k) = odepth - 0.5*odepth*odepth
            trngas(k) = f_one - atrgas(k)
            gasfac    = rec_6 * odepth
          else
            tblind = odepth / (bpade + odepth)
            itgas = tblint*tblind + 0.5
            trngas(k) = exp_tbl(itgas)
            atrgas(k) = f_one - trngas(k)
            gasfac    = tfn_tbl(itgas)
          endif

          bbdgas    = plfrac*(blay + dplnkd*gasfac)
          bbugas(k) = plfrac*(blay + dplnku*gasfac)
          gassrc    = bbdgas*atrgas(k)

!  --- ...  total sky, gases+clouds contribution

          if (cldfmc(k,ig) >= eps) then
!  --- ...  it is a cloudy layer

            odtot = odepth + odcld(k,ig)

            if (odtot < 0.06) then
              totfac    = rec_6 * odtot
              atrtot(k) = odtot - 0.5*odtot*odtot
              trntot    = f_one - atrtot(k)
            elseif (odepth <= 0.06) then
              tblind = odtot / (bpade + odtot)
              ittot  = tblint*tblind + 0.5

              totfac    = tfn_tbl(ittot)
              trntot    = exp_tbl(ittot)
              atrtot(k) = f_one - trntot
            else
              odepth = tau_tbl(itgas)
              odtot  = odepth + odcld(k,ig)
              tblind = odtot / (bpade + odtot)
              ittot  = tblint*tblind + 0.5

              totfac    = tfn_tbl(ittot)
              trntot    = exp_tbl(ittot)
              atrtot(k) = f_one - trntot
            endif

            bbdtot    = plfrac*(blay + dplnkd*totfac)
            bbutot(k) = plfrac*(blay + dplnku*totfac)
            totsrc    = bbdtot*atrtot(k)

!  --- ...  total sky radiance
            radtotd = radtotd*trngas(k)*efclrfr(k,ig) + gassrc          &
     &              + cldfmc(k,ig)*(totsrc - gassrc)
            totdrad(k-1,ib) = totdrad(k-1,ib) + radtotd

!  --- ...  clear sky radiance
            radclrd = radclrd*trngas(k) + gassrc
            clrdrad(k-1,ib) = clrdrad(k-1,ib) + radclrd

          else

!  --- ...  it is a clear layer
            radtotd = radtotd*trngas(k) + gassrc
            totdrad(k-1,ib) = totdrad(k-1,ib) + radtotd

            radclrd = radclrd*trngas(k) + gassrc
            clrdrad(k-1,ib) = clrdrad(k-1,ib) + radclrd

          endif

        enddo   ! end do_k_loop

!  --- ...  spectral emissivity & reflectance
!           include the contribution of spectrally varying longwave emissivity
!           and reflection from the surface to the upward radiative transfer.
!     note: spectral and Lambertian reflection are identical for the
!           diffusivity angle flux integration used here.

        rad0 = fracs(1,ig) * pkbnd(ib)

!  --- ...  add in reflection of surface downward radiance.
        reflct = f_one - semiss(ib)
        rtotu = rad0 + reflct*radtotd
        rclru = rad0 + reflct*radclrd

!  --- ...  upward radiative transfer loop.
        toturad(0,ib) = toturad(0,ib) + rtotu
        clrurad(0,ib) = clrurad(0,ib) + rclru

        do k = 1, nlay

          gassrc = bbugas(k)*atrgas(k)
          totsrc = bbutot(k)*atrtot(k)

          if (cldfmc(k,ig) > eps) then

!  --- ...  it is a cloudy layer
            rtotu = rtotu*trngas(k)*efclrfr(k,ig) + gassrc              &
     &            + cldfmc(k,ig)*(totsrc - gassrc)
            toturad(k,ib) = toturad(k,ib) + rtotu

            rclru = rclru*trngas(k) + gassrc
            clrurad(k,ib) = clrurad(k,ib) + rclru

          else

!  --- ...  it is a clear layer
            rtotu = rtotu*trngas(k) + gassrc
            toturad(k,ib) = toturad(k,ib) + rtotu

            rclru = rclru*trngas(k) + gassrc
            clrurad(k,ib) = clrurad(k,ib) + rclru

          endif

        enddo   ! end do_k_loop

      enddo   ! end do_ig_loop

!  --- ...  process longwave output from band for total and clear streams.
!           calculate upward, downward, and net flux.

      do ib = 1, nbands
        flxfac = wtdiff * fluxfac * delwave(ib)

        do k = 0, nlay
          toturad(k,ib) = toturad(k,ib) * flxfac
          totdrad(k,ib) = totdrad(k,ib) * flxfac
          clrurad(k,ib) = clrurad(k,ib) * flxfac
          clrdrad(k,ib) = clrdrad(k,ib) * flxfac

          totuflux(k) = totuflux(k) + toturad(k,ib)
          totdflux(k) = totdflux(k) + totdrad(k,ib)
          totuclfl(k) = totuclfl(k) + clrurad(k,ib)
          totdclfl(k) = totdclfl(k) + clrdrad(k,ib)
        enddo
      enddo

!  --- ...  calculate net fluxes and heating rates
      fnet(0) = totuflux(0) - totdflux(0)

      do k = 1, nlay
        fnet(k) = totuflux(k) - totdflux(k)
        htr (k) = heatfac*(fnet(k-1) - fnet(k)) / delp(k)
      enddo

!! --- ...  optional clear sky heating rates
      if ( lhlw0 ) then
        fnetc(0) = totuclfl(0) - totdclfl(0)

        do k = 1, nlay
          fnetc(k) = totuclfl(k) - totdclfl(k)
          htrcl(k) = heatfac*(fnetc(k-1)-fnetc(k)) / delp(k)
        enddo
      endif

!! --- ...  optional spectral band heating rates
      if ( lhlwb ) then
        do ib = 1, nbands
          fnet(0) = toturad(0,ib) - totdrad(0,ib)

          do k = 1, nlay
            fnet(k) = toturad(k,ib) - totdrad(k,ib)
            htrb(k,ib) = heatfac*(fnet(k-1)-fnet(k)) / delp(k)
          enddo
        enddo
      endif

! ..................................
      end subroutine rtrnmc
! ----------------------------------


! ----------------------------------
      subroutine taumol                                                 &
! ..................................
!  ---  inputs:
     &     ( laytrop,pavel,coldry,colamt,colbrd,wx,tauaer,              &
     &       rfrate,fac00,fac01,fac10,fac11,jp,jt,jt1,                  &
     &       selffac,selffrac,indself,forfac,forfrac,indfor,            &
     &       minorfrac,scaleminor,scaleminorn2,indminor,                &
     &       nlay,                                                      &
!  ---  outputs:
     &       fracs, tautot                                              &
     &     )

!  ************    original subprogram description    ***************   !
!                                                                       !
!                  optical depths developed for the                     !
!                                                                       !
!                rapid radiative transfer model (rrtm)                  !
!                                                                       !
!            atmospheric and environmental research, inc.               !
!                        131 hartwell avenue                            !
!                        lexington, ma 02421                            !
!                                                                       !
!                           eli j. mlawer                               !
!                         jennifer delamere                             !
!                         steven j. taubman                             !
!                         shepard a. clough                             !
!                                                                       !
!                       email:  mlawer@aer.com                          !
!                       email:  jdelamer@aer.com                        !
!                                                                       !
!        the authors wish to acknowledge the contributions of the       !
!        following people:  karen cady-pereira, patrick d. brown,       !
!        michael j. iacono, ronald e. farren, luke chen,                !
!        robert bergstrom.                                              !
!                                                                       !
!  revision for g-point reduction: michael j. iacono; aer, inc.         !
!                                                                       !
!     taumol                                                            !
!                                                                       !
!     this file contains the subroutines taugbn (where n goes from      !
!     1 to 16).  taugbn calculates the optical depths and planck        !
!     fractions per g-value and layer for band n.                       !
!                                                                       !
!  *******************************************************************  !
!  ==================   program usage description   ==================  !
!                                                                       !
!    call  taumol                                                       !
!       inputs:                                                         !
!          ( laytrop,pavel,coldry,colamt,colbrd,wx,tauaer,              !
!            rfrate,fac00,fac01,fac10,fac11,jp,jt,jt1,                  !
!            selffac,selffrac,indself,forfac,forfrac,indfor,            !
!            minorfrac,scaleminor,scaleminorn2,indminor,                !
!            nlay,                                                      !
!       outputs:                                                        !
!            fracs, tautot )                                            !
!                                                                       !
!  subprograms called:  taugb## (## = 01 -16)                           !
!                                                                       !
!                                                                       !
!  ====================  defination of variables  ====================  !
!                                                                       !
!  inputs:                                                        size  !
!     laytrop   - integer, tropopause layer index (unitless)        1   !
!                   layer at which switch is made for key species       !
!     pavel     - real, layer pressures (mb)                       nlay !
!     coldry    - real, column amount for dry air (mol/cm2)        nlay !
!     colamt    - real, column amounts of h2o, co2, o3, n2o, ch4,       !
!                   o2, co (mol/cm**2)                       nlay*maxgas!
!     colbrd    - real, column amount of broadening gases          nlay !
!     wx        - real, cross-section amounts(mol/cm2)      nlay*maxxsec!
!     tauaer    - real, aerosol optical depth               nlay*nbands !
!     rfrate    - real, reference ratios of binary species parameter    !
!     (:,m,:)m=1-h2o/co2,2-h2o/o3,3-h2o/n2o,4-h2o/ch4,5-n2o/co2,6-o3/co2!
!     (:,:,n)n=1,2: the rates of ref press at the 2 sides of the layer  !
!                                                          nlay*nrates*2!
!     facij     - real, factors multiply the reference ks, i,j of 0/1   !
!                   for lower/higher of the 2 appropriate temperatures  !
!                   and altitudes                                  nlay !
!     jp        - real, index of lower reference pressure          nlay !
!     jt, jt1   - real, indices of lower reference temperatures    nlay !
!                   for pressure levels jp and jp+1, respectively       !
!     selffac   - real, scale factor for water vapor self-continuum     !
!                   equals (water vapor density)/(atmospheric density   !
!                   at 296k and 1013 mb)                           nlay !
!     selffrac  - real, factor for temperature interpolation of         !
!                   reference water vapor self-continuum data      nlay !
!     indself   - integer, index of lower reference temperature for     !
!                   the self-continuum interpolation               nlay !
!     forfac    - real, scale factor for w. v. foreign-continuum   nlay !
!     forfrac   - real, factor for temperature interpolation of         !
!                   reference w.v. foreign-continuum data          nlay !
!     indfor    - integer, index of lower reference temperature for     !
!                   the foreign-continuum interpolation            nlay !
!     minorfrac - real, factor for minor gases                     nlay !
!     scaleminor,scaleminorn2                                           !
!               - real, scale factors for minor gases              nlay !
!     indminor  - integer, index of lower reference temperature for     !
!                   minor gases                                    nlay !
!     nlay      - integer, total number of layers                   1   !
!                                                                       !
!  outputs:                                                             !
!     fracs     - real, planck fractions                     nlay*ngptlw!
!     tautot    - real, total optical depth (gas+aerosols)   nlay*ngptlw!
!                                                                       !
!  internal variables:                                                  !
!     ng##      - integer, number of g-values in band ## (##=01-16) 1   !
!     nspa      - integer, for lower atmosphere, the number of ref      !
!                   atmos, each has different relative amounts of the   !
!                   key species for the band                      nbands!
!     nspb      - integer, same but for upper atmosphere          nbands!
!     absa      - real, k-values for lower ref atmospheres (no w.v.     !
!                   self-continuum) (cm**2/molecule)  nspa(##)*5*13*ng##!
!     absb      - real, k-values for high ref atmospheres (all sources) !
!                   (cm**2/molecule)               nspb(##)*5*13:59*ng##!
!     ka_m'mgas'- real, k-values for low ref atmospheres minor species  !
!                   (cm**2/molecule)                          mmn##*ng##!
!     kb_m'mgas'- real, k-values for high ref atmospheres minor species !
!                   (cm**2/molecule)                          mmn##*ng##!
!     selfref   - real, k-values for w.v. self-continuum for ref atmos  !
!                   used below laytrop (cm**2/mol)               10*ng##!
!     forref    - real, k-values for w.v. foreign-continuum for ref atmos
!                   used below/above laytrop (cm**2/mol)          4*ng##!
!                                                                       !
!  ******************************************************************   !

!  ---  inputs:
      integer, intent(in) :: nlay, laytrop

      integer, dimension(:), intent(in) ::   jp, jt, jt1, indself,      &
     &       indfor, indminor

      real (kind=kind_phys), dimension(:), intent(in) :: pavel, coldry, &
     &       colbrd, fac00, fac01, fac10, fac11, selffac, selffrac,     &
     &       forfac, forfrac, minorfrac, scaleminor, scaleminorn2

      real (kind=kind_phys), dimension(:,:), intent(in) :: colamt, wx,  &
     &       tauaer

      real (kind=kind_phys), dimension(:,:,:), intent(in) :: rfrate

!  ---  outputs:
      real (kind=kind_phys), dimension(:,:),intent(out) :: fracs,tautot

!  ---  locals
      real (kind=kind_phys), dimension(nlay,ngptlw) :: taug

      integer :: ib, ig, k
!
!===> ...  begin here
!
      call taugb01
      call taugb02
      call taugb03
      call taugb04
      call taugb05
      call taugb06
      call taugb07
      call taugb08
      call taugb09
      call taugb10
      call taugb11
      call taugb12
      call taugb13
      call taugb14
      call taugb15
      call taugb16

!  ---  combine gaseous and aerosol optical depths

      do ig = 1, ngptlw
        ib = ngb(ig)

        do k = 1, nlay
          tautot(k,ig) = taug(k,ig) + tauaer(k,ib)
        enddo
      enddo

! =================
      contains
! =================

! ----------------------------------
      subroutine taugb01
! ..................................

!  ------------------------------------------------------------------  !
!  written by eli j. mlawer, atmospheric & environmental research.     !
!  revised by michael j. iacono, atmospheric & environmental research. !
!                                                                      !
!     band 1:  10-350 cm-1 (low key - h2o; low minor - n2)             !
!                          (high key - h2o; high minor - n2)           !
!                                                                      !
!  compute the optical depth by interpolating in ln(pressure) and      !
!  temperature.  below laytrop, the water vapor self-continuum and     !
!  foreign continuum is interpolated (in temperature) separately.      !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb01

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig
      real (kind=kind_phys) :: pp, corradj, scalen2, tauself, taufor,   &
     &       taun2
!
!===> ...  begin here
!
!  ---  minor gas mapping levels:
!     lower - n2, p = 142.5490 mbar, t = 215.70 k
!     upper - n2, p = 142.5490 mbar, t = 215.70 k

!  --- ...  lower atmosphere loop

      do k = 1, laytrop

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(1) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(1) + 1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)
        pp = pavel(k)
        corradj =  f_one
        if (pp < 250.0) then
          corradj = f_one - 0.15 * (250.0-pp) / 154.4
        endif
        scalen2 = colbrd(k) * scaleminorn2(k)

        do ig = 1, ng01
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) -  forref(indf,ig))) 
          taun2   = scalen2*(ka_mn2(indm,ig) + minorfrac(k)             &
     &            * (ka_mn2(indm+1,ig) - ka_mn2(indm,ig)))

          taug(k,ig) = corradj * (colamt(k,1)                           &
     &      * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)        &
     &      +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))       &
     &      + tauself + taufor + taun2)

          fracs(k,ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(1) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(1) + 1
        indf = indfor(k)
        indm = indminor(k)
        pp = pavel(k)
        corradj =  f_one - 0.15 * (pp / 95.6)

        scalen2 = colbrd(k) * scaleminorn2(k)
        do ig = 1, ng01
          taufor = forfac(k) * (forref(indf,ig) + forfrac(k)            &
     &           * (forref(indf+1,ig) - forref(indf,ig))) 
          taun2  = scalen2*(kb_mn2(indm,ig) + minorfrac(k)              &
     &           * (kb_mn2(indm+1,ig) - kb_mn2(indm,ig)))

          taug(k,ig) = corradj * (colamt(k,1)                           &
     &      * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)        &
     &      +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))       &
     &      + taufor + taun2)

          fracs(k,ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb01
! ----------------------------------

! ----------------------------------
      subroutine taugb02
! ..................................

!  ------------------------------------------------------------------  !
!     band 2:  350-500 cm-1 (low key - h2o; high key - h2o)            !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb02

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, ig

      real (kind=kind_phys) :: pp, corradj, tauself, taufor
!
!===> ...  begin here
!
!  --- ...  lower atmosphere loop

      do k = 1, laytrop

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(2) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(2) + 1
        inds = indself(k)
        indf = indfor(k)
        pp = pavel(k)
        corradj = f_one - 0.05 * (pp - 100.0) / 900.0

        do ig = 1, ng02
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig))) 

          taug(k,ns02+ig) = corradj * (colamt(k,1)                      &
     &      * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)        &
     &      +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))       &
     &      + tauself + taufor)

          fracs(k,ns02+ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(2) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(2) + 1
        indf = indfor(k)

        do ig = 1, ng02
          taufor = forfac(k) * (forref(indf,ig) + forfrac(k)            &
     &           * (forref(indf+1,ig) - forref(indf,ig))) 

          taug(k,ns02+ig) = colamt(k,1)                                 &
     &      * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)        &
     &      +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))       &
     &      + taufor

          fracs(k,ns02+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb02
! ----------------------------------

! ----------------------------------
      subroutine taugb03
! ..................................

!  ------------------------------------------------------------------  !
!     band 3:  500-630 cm-1 (low key - h2o,co2; low minor - n2o)       !
!                           (high key - h2o,co2; high minor - n2o)     !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb03

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig, js,js1, jmn2o, jpl

      real (kind=kind_phys) :: fmn2omf, ratn2o, adjfac, adjcoln2o,      &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_mn2o,  specparm_mn2o,  specmult_mn2o,  fmn2o,      &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      refrat_planck_a, refrat_planck_b, refrat_m_a, refrat_m_b,   &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      tauself, taufor, n2om1, n2om2, absn2o, p, p4, fk0, fk1,     &
     &      fk2, temp, tau_major, tau_major1
!
!===> ...  begin here
!
!  --- ...  minor gas mapping levels:
!     lower - n2o, p = 706.272 mbar, t = 278.94 k
!     upper - n2o, p = 95.58 mbar, t = 215.7 k

      refrat_planck_a = chi_mls(1,9)/chi_mls(2,9)    ! P = 212.725 mb
      refrat_planck_b = chi_mls(1,13)/chi_mls(2,13)  ! P = 95.58   mb
      refrat_m_a      = chi_mls(1,3)/chi_mls(2,3)    ! P = 706.270 mb
      refrat_m_b      = chi_mls(1,13)/chi_mls(2,13)  ! P = 95.58   mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop

        speccomb = colamt(k,1) + rfrate(k,1,1)*colamt(k,2)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)        

        speccomb1 = colamt(k,1) + rfrate(k,1,2)*colamt(k,2)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_mn2o = colamt(k,1) + refrat_m_a*colamt(k,2)
        specparm_mn2o = colamt(k,1) / speccomb_mn2o
        if (specparm_mn2o >= oneminus) specparm_mn2o = oneminus
        specmult_mn2o = 8.0 * specparm_mn2o
        jmn2o = 1 + int(specmult_mn2o)
        fmn2o = mod(specmult_mn2o, f_one)
        fmn2omf = minorfrac(k) * fmn2o

!  --- ...  in atmospheres where the amount of n2O is too great to be considered
!           a minor species, adjust the column amount of n2O by an empirical factor
!           to obtain the proper contribution.

        temp = coldry(k) * chi_mls(4,jp(k)+1)
        ratn2o = colamt(k,4) / temp
        if (ratn2o > 1.5) then
          adjfac = 0.5 + (ratn2o - 0.5)**0.65
          adjcoln2o = adjfac * temp
        else
          adjcoln2o = colamt(k,4)
        endif

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,2)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl = 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(3) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(3) + js1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        if (specparm < 0.125) then
          p = fs - 1.0
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)
        else if (specparm > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = 1.0 - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)
        endif

        if (specparm1 < 0.125) then
          p = fs1 - 1.0
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)
        elseif (specparm1 > 0.875) then
          p = -fs1
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)
        else
          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)
        endif

        do ig = 1, ng03
          tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)         &
     &        * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &        * (forref(indf+1,ig) - forref(indf,ig)))
          n2om1   = ka_mn2o(jmn2o,indm,ig) + fmn2o                      &
     &        * (ka_mn2o(jmn2o+1,indm,ig) - ka_mn2o(jmn2o,indm,ig))
          n2om2   = ka_mn2o(jmn2o,indm+1,ig) + fmn2o                    &
     &        * (ka_mn2o(jmn2o+1,indm+1,ig) - ka_mn2o(jmn2o,indm+1,ig))
          absn2o  = n2om1 + minorfrac(k) * (n2om2 - n2om1)

          if (specparm < 0.125) then
            tau_major = speccomb                                        &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig)) 
          elseif (specparm > 0.875) then
            tau_major = speccomb                                        &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))
          else
            tau_major = speccomb                                        &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))
          endif

          if (specparm1 < 0.125) then
            tau_major1 = speccomb1                                      &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))
          elseif (specparm1 > 0.875) then
            tau_major1 = speccomb1                                      &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))
          else
            tau_major1 = speccomb1                                      &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))
          endif

          taug(k,ns03+ig) = tau_major + tau_major1                      &
     &                    + tauself + taufor + adjcoln2o*absn2o

          fracs(k,NS03+ig) = fracrefa(ig,jpl)                           &
     &                   + fpl*(fracrefa(ig,jpl+1) - fracrefa(ig,jpl))
        enddo   ! end do_ig_loop

      enddo     ! end do_k_loop

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay

        speccomb = colamt(k,1) + rfrate(k,1,1)*colamt(k,2)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 4.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,1,2)*colamt(k,2)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 4.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        fac000 = (f_one - fs) * fac00(k)
        fac010 = (f_one - fs) * fac10(k)
        fac100 = fs * fac00(k)
        fac110 = fs * fac10(k)
        fac001 = (f_one - fs1) * fac01(k)
        fac011 = (f_one - fs1) * fac11(k)
        fac101 = fs1 * fac01(k)
        fac111 = fs1 * fac11(k)

        speccomb_mn2o = colamt(k,1) + refrat_m_b*colamt(k,2)
        specparm_mn2o = colamt(k,1) / speccomb_mn2o
        if (specparm_mn2o >= oneminus) specparm_mn2o = oneminus
        specmult_mn2o = 4.0 * specparm_mn2o
        jmn2o = 1 + int(specmult_mn2o)
        fmn2o = mod(specmult_mn2o, f_one)
        fmn2omf = minorfrac(k) * fmn2o

!  --- ...  in atmospheres where the amount of n2o is too great to be considered
!           a minor species, adjust the column amount of N2O by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(4,jp(k)+1)
        ratn2o = colamt(k,4) / temp
        if (ratn2o > 1.5) then
          adjfac = 0.5 + (ratn2o - 0.5)**0.65
          adjcoln2o = adjfac * temp
        else
          adjcoln2o = colamt(k,4)
        endif

        speccomb_planck = colamt(k,1) + refrat_planck_b*colamt(k,2)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 4.0 * specparm_planck
        jpl = 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(3) + js
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(3) + js1
        indf = indfor(k)
        indm = indminor(k)

        do ig = 1, ng03
          taufor = forfac(k) * (forref(indf,ig) + forfrac(k)            &
     &           * (forref(indf+1,ig) - forref(indf,ig))) 
          n2om1 = kb_mn2o(jmn2o,indm,ig) + fmn2o                        &
     &       * (kb_mn2o(jmn2o+1,indm,ig) - kb_mn2o(jmn2o,indm,ig))
          n2om2 = kb_mn2o(jmn2o,indm+1,ig) + fmn2o                      &
     &       * (kb_mn2o(jmn2o+1,indm+1,ig) - kb_mn2o(jmn2o,indm+1,ig))
          absn2o = n2om1 + minorfrac(k) * (n2om2 - n2om1)

          taug(k,ns03+ig) = speccomb                                    &
     &       * (fac000*absb(ind0  ,ig) + fac100*absb(ind0+1,ig)         &
     &       +  fac010*absb(ind0+5,ig) + fac110*absb(ind0+6,ig))        &
     &       + speccomb1                                                &
     &       * (fac001*absb(ind1  ,ig) + fac101*absb(ind1+1,ig)         &
     &       +  fac011*absb(ind1+5,ig) + fac111*absb(ind1+6,ig))        &
     &       + taufor + adjcoln2o*absn2o            

          fracs(k,ns03+ig) = fracrefb(ig,jpl) + fpl                     &
     &       * (fracrefb(ig,jpl+1)-fracrefb(ig,jpl))
        enddo

      enddo

! ..................................
      end subroutine taugb03
! ----------------------------------

! ----------------------------------
      subroutine taugb04
! ..................................

!  ------------------------------------------------------------------  !
!     band 4:  630-700 cm-1 (low key - h2o,co2; high key - o3,co2)     !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb04

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, ig, js, js1, jpl

      real (kind=kind_phys) :: tauself, taufor, p, p4, fk0, fk1, fk2,   &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      refrat_planck_a, refrat_planck_b, tau_major, tau_major1
!
!===> ...  begin here
!
      refrat_planck_a = chi_mls(1,11)/chi_mls(2,11)     ! P = 142.5940 mb
      refrat_planck_b = chi_mls(3,13)/chi_mls(2,13)     ! P = 95.58350 mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop

        speccomb = colamt(k,1) + rfrate(k,1,1)*colamt(k,2)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,1,2)*colamt(k,2)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,2)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl = 1 + int(specmult_planck)
        fpl = mod(specmult_planck, 1.0)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(4) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(4) + js1
        inds = indself(k)
        indf = indfor(k)

        if (specparm < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)
        elseif (specparm > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)
        endif

        if (specparm1 < 0.125) then
          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)
        elseif (specparm1 > 0.875) then
          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)
        else
          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)
        endif

        do ig = 1, ng04
          tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)         &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig))) 

          if (specparm < 0.125) then
            tau_major = speccomb                                        &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))
          elseif (specparm > 0.875) then
            tau_major = speccomb                                        &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))
          else
            tau_major = speccomb                                        &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))
          endif

          if (specparm1 < 0.125) then
            tau_major1 = speccomb1                                      &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))
          elseif (specparm1 > 0.875) then
            tau_major1 = speccomb1                                      &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))
          else
            tau_major1 = speccomb1                                      &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))
          endif

          taug(k,ns04+ig) = tau_major + tau_major1 + tauself + taufor

          fracs(k,ns04+ig) = fracrefa(ig,jpl)                           &
     &                + fpl*(fracrefa(ig,jpl+1) - fracrefa(ig,jpl))
        enddo   ! end do_ig_loop

      enddo     ! end do_k_loop

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay

        speccomb = colamt(k,3) + rfrate(k,6,1)*colamt(k,2)
        specparm = colamt(k,3) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 4.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,3) + rfrate(k,6,2)*colamt(k,2)
        specparm1 = colamt(k,3) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 4.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        fac000 = (f_one - fs) * fac00(k)
        fac010 = (f_one - fs) * fac10(k)
        fac100 = fs * fac00(k)
        fac110 = fs * fac10(k)
        fac001 = (f_one - fs1) * fac01(k)
        fac011 = (f_one - fs1) * fac11(k)
        fac101 = fs1 * fac01(k)
        fac111 = fs1 * fac11(k)

        speccomb_planck = colamt(k,3) + refrat_planck_b*colamt(k,2)
        specparm_planck = colamt(k,3) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 4.0 * specparm_planck
        jpl = 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(4) + js
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(4) + js1

        do ig = 1, ng04
          taug(k,ns04+ig) =  speccomb                                   &
     &       * (fac000*absb(ind0  ,ig) + fac100*absb(ind0+1,ig)         &
     &       +  fac010*absb(ind0+5,ig) + fac110*absb(ind0+6,ig))        &
     &       + speccomb1                                                &
     &       * (fac001*absb(ind1  ,ig) + fac101*absb(ind1+1,ig)         &
     &       +  fac011*absb(ind1+5,ig) + fac111*absb(ind1+6,ig)) 

          fracs(k,ns04+ig) = fracrefb(ig,jpl) + fpl                     &
     &       * (fracrefb(ig,jpl+1) - fracrefb(ig,jpl))
        enddo

!  --- ...  empirical modification to code to improve stratospheric cooling rates
!           for co2. revised to apply weighting for g-point reduction in this band.

        taug(k,ns04+ 8) = taug(k,ns04+ 8) * 0.92
        taug(k,ns04+ 9) = taug(k,ns04+ 9) * 0.88
        taug(k,ns04+10) = taug(k,ns04+10) * 1.07
        taug(k,ns04+11) = taug(k,ns04+11) * 1.1
        taug(k,ns04+12) = taug(k,ns04+12) * 0.99
        taug(k,ns04+13) = taug(k,ns04+13) * 0.88
        taug(k,ns04+14) = taug(k,ns04+14) * 0.943

      enddo   ! end do_k_loop

! ..................................
      end subroutine taugb04
! ----------------------------------

! ----------------------------------
      subroutine taugb05
! ..................................

!  ------------------------------------------------------------------  !
!     band 5:  700-820 cm-1 (low key - h2o,co2; low minor - o3, ccl4)  !
!                           (high key - o3,co2)                        !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb05

!  ---  locals: 
      integer :: k, ind0, ind1, inds, indf, indm, ig, js, js1, jmo3, jpl

      real (kind=kind_phys)  :: tauself, taufor, o3m1, o3m2, abso3,     &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_mo3,   specparm_mo3,   specmult_mo3,   fmo3,       &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      refrat_planck_a, refrat_planck_b, refrat_m_a,               &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level :
!     lower - o3, p = 317.34 mbar, t = 240.77 k
!     lower - ccl4

!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower/upper atmosphere.

      refrat_planck_a = chi_mls(1,5)/chi_mls(2,5)      ! P = 473.420 mb
      refrat_planck_b = chi_mls(3,43)/chi_mls(2,43)    ! P = 0.2369  mb
      refrat_m_a = chi_mls(1,7)/chi_mls(2,7)           ! P = 317.348 mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,1) + rfrate(k,1,1)*colamt(k,2)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,1,2)*colamt(k,2)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_mo3 = colamt(k,1) + refrat_m_a*colamt(k,2)
        specparm_mo3 = colamt(k,1) / speccomb_mo3
        if (specparm_mo3 >= oneminus) specparm_mo3 = oneminus
        specmult_mo3 = 8.0 * specparm_mo3
        jmo3 = 1 + int(specmult_mo3)
        fmo3 = mod(specmult_mo3, f_one)

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,2)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(5) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(5) + js1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - 1.0
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng05
            tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)      &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            o3m1 = ka_mo3(jmo3,indm,ig) + fmo3                          &
     &           * (ka_mo3(jmo3+1,indm,ig) - ka_mo3(jmo3,indm,ig))
            o3m2 = ka_mo3(jmo3,indm+1,ig) + fmo3                        &
     &           * (ka_mo3(jmo3+1,indm+1,ig) - ka_mo3(jmo3,indm+1,ig))
            abso3 = o3m1 + minorfrac(k)*(o3m2-o3m1)

            taug(k,ns05+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor + abso3*colamt(k,3)                   &
     &         + wx(k,1)*ccl4(ig)

            fracs(k,ns05+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1) - fracrefa(ig,jpl))
          enddo
        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng05
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            o3m1 = ka_mo3(jmo3,indm,ig) + fmo3                          &
     &           * (ka_mo3(jmo3+1,indm,ig) - ka_mo3(jmo3,indm,ig))
            o3m2 = ka_mo3(jmo3,indm+1,ig) + fmo3                        &
     &           * (ka_mo3(jmo3+1,indm+1,ig) - ka_mo3(jmo3,indm+1,ig))
            abso3 = o3m1 + minorfrac(k)*(o3m2-o3m1)

            taug(k,ns05+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor + abso3*colamt(k,3)                   &
     &         + wx(k,1)*ccl4(ig)

            fracs(k,ns05+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng05
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            o3m1 = ka_mo3(jmo3,indm,ig) + fmo3                          &
     &           * (ka_mo3(jmo3+1,indm,ig)-ka_mo3(jmo3,indm,ig))
            o3m2 = ka_mo3(jmo3,indm+1,ig) + fmo3                        &
     &           * (ka_mo3(jmo3+1,indm+1,ig)-ka_mo3(jmo3,indm+1,ig))
            abso3 = o3m1 + minorfrac(k)*(o3m2-o3m1)

            taug(k,ns05+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor + abso3*colamt(k,3)                   &
     &         + wx(k,1)*ccl4(ig)

            fracs(k,ns05+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        speccomb = colamt(k,3) + rfrate(k,6,1)*colamt(k,2)
        specparm = colamt(k,3) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 4.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,3) + rfrate(k,6,2)*colamt(k,2)
        specparm1 = colamt(k,3) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 4.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        fac000 = (1.0 - fs) * fac00(k)
        fac010 = (1.0 - fs) * fac10(k)
        fac100 = fs * fac00(k)
        fac110 = fs * fac10(k)
        fac001 = (1.0 - fs1) * fac01(k)
        fac011 = (1.0 - fs1) * fac11(k)
        fac101 = fs1 * fac01(k)
        fac111 = fs1 * fac11(k)

        speccomb_planck = colamt(k,3) + refrat_planck_b*colamt(k,2)
        specparm_planck = colamt(k,3) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 4.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(5) + js
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(5) + js1
         
        do ig = 1, ng05
          taug(k,ns05+ig) = speccomb                                    &
     &       * (fac000*absb(ind0  ,ig) + fac100*absb(ind0+1,ig)         &
     &       +  fac010*absb(ind0+5,ig) + fac110*absb(ind0+6,ig))        &
     &       + speccomb1                                                &
     &       * (fac001*absb(ind1  ,ig) + fac101*absb(ind1+1,ig)         &
     &       +  fac011*absb(ind1+5,ig) + fac111*absb(ind1+6,ig))        &
     &       + wx(k,1) * ccl4(ig)

          fracs(k,ns05+ig) = fracrefb(ig,jpl) + fpl                     &
     &       * (fracrefb(ig,jpl+1)-fracrefb(ig,jpl))
        enddo
      enddo

! ..................................
      end subroutine taugb05
! ----------------------------------

! ----------------------------------
      subroutine taugb06
! ..................................

!  ------------------------------------------------------------------  !
!     band 6:  820-980 cm-1 (low key - h2o; low minor - co2)           !
!                           (high key - none; high minor - cfc11, cfc12)
!  ------------------------------------------------------------------  !

      use module_radlw_kgb06

!  ---  locals: 
      integer :: k, ind0, ind1, inds, indf, indm, ig

      real (kind=kind_phys) :: ratco2, adjfac, adjcolco2, tauself,      &
     &      taufor, absco2, temp
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level:
!     lower - co2, p = 706.2720 mb, t = 294.2 k
!     upper - cfc11, cfc12

!  --- ...  lower atmosphere loop

      do k = 1, laytrop

!  --- ...  in atmospheres where the amount of co2 is too great to be considered
!           a minor species, adjust the column amount of co2 by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(2,jp(k)+1)
        ratco2 = colamt(k,2) / temp
        if (ratco2 > 3.0) then
          adjfac = 2.0 + (ratco2-2.0)**0.77
          adjcolco2 = adjfac * temp
        else
          adjcolco2 = colamt(k,2)
        endif

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(6) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(6) + 1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        do ig = 1, ng06
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig)))
          absco2 = (ka_mco2(indm,ig) + minorfrac(k)                     &
     &           * (ka_mco2(indm+1,ig) - ka_mco2(indm,ig)))

          taug(k,ns06+ig) = colamt(k,1)                                 &
     &       * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)       &
     &       +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))      &
     &       + tauself + taufor + adjcolco2*absco2                      &
     &       + wx(k,2)*cfc11adj(ig) + wx(k,3)*cfc12(ig)

          fracs(k,ns06+ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop
!           nothing important goes on above laytrop in this band.

      do k = laytrop+1, nlay
        do ig = 1, ng06
          taug(k,ns06+ig) = wx(k,2)*cfc11adj(ig) + wx(k,3)*cfc12(ig)

          fracs(k,ns06+ig) = fracrefa(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb06
! ----------------------------------

! ----------------------------------
      subroutine taugb07
! ..................................

!  ------------------------------------------------------------------  !
!     band 7:  980-1080 cm-1 (low key - h2o,o3; low minor - co2)       !
!                            (high key - o3; high minor - co2)         !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb07

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig, js,js1, jmco2, jpl

      real (kind=kind_phys) :: tauself, taufor, co2m1, co2m2, absco2,   &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_mco2,  specparm_mco2,  specmult_mco2,  fmco2,      &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      refrat_planck_a, refrat_m_a, ratco2, adjfac, adjcolco2,     &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2, temp
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level :
!     lower - co2, p = 706.2620 mbar, t= 278.94 k
!     upper - co2, p = 12.9350 mbar, t = 234.01 k

!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower atmosphere.

      refrat_planck_a = chi_mls(1,3)/chi_mls(3,3)     ! P = 706.2620 mb
      refrat_m_a = chi_mls(1,3)/chi_mls(3,3)          ! P = 706.2720 mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,1) + rfrate(k,2,1)*colamt(k,3)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,2,2)*colamt(k,3)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_mco2 = colamt(k,1) + refrat_m_a*colamt(k,3)
        specparm_mco2 = colamt(k,1) / speccomb_mco2
        if (specparm_mco2 >= oneminus) specparm_mco2 = oneminus
        specmult_mco2 = 8.0 * specparm_mco2
        jmco2 = 1 + int(specmult_mco2)
        fmco2 = mod(specmult_mco2, f_one)

!  --- ...  in atmospheres where the amount of CO2 is too great to be considered
!           a minor species, adjust the column amount of CO2 by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(2,jp(k)+1)
        ratco2 = colamt(k,2) / temp
        if (ratco2 > 3.0) then
          adjfac = 3.0 + (ratco2-3.0)**0.79
          adjcolco2 = adjfac * temp
        else
          adjcolco2 = colamt(k,2)
        endif

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,3)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(7) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(7) + js1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng07
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            co2m1 = ka_mco2(jmco2,indm,ig) + fmco2                      &
     &         * (ka_mco2(jmco2+1,indm,ig) - ka_mco2(jmco2,indm,ig))
            co2m2 = ka_mco2(jmco2,indm+1,ig) + fmco2                    &
     &         * (ka_mco2(jmco2+1,indm+1,ig) - ka_mco2(jmco2,indm+1,ig))
            absco2 = co2m1 + minorfrac(k) * (co2m2 - co2m1)

            taug(k,ns07+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor + adjcolco2*absco2

            fracs(k,ns07+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng07
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            co2m1 = ka_mco2(jmco2,indm,ig) + fmco2                      &
     &         * (ka_mco2(jmco2+1,indm,ig) - ka_mco2(jmco2,indm,ig))
            co2m2 = ka_mco2(jmco2,indm+1,ig) + fmco2                    &
     &         * (ka_mco2(jmco2+1,indm+1,ig) - ka_mco2(jmco2,indm+1,ig))
            absco2 = co2m1 + minorfrac(k) * (co2m2 - co2m1)

            taug(k,ns07+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor + adjcolco2*absco2

            fracs(k,ns07+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng07
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            co2m1 = ka_mco2(jmco2,indm,ig) + fmco2                      &
     &         * (ka_mco2(jmco2+1,indm,ig) - ka_mco2(jmco2,indm,ig))
            co2m2 = ka_mco2(jmco2,indm+1,ig) + fmco2                    &
     &         * (ka_mco2(jmco2+1,indm+1,ig) - ka_mco2(jmco2,indm+1,ig))
            absco2 = co2m1 + minorfrac(k) * (co2m2 - co2m1)

            taug(k,ns07+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor + adjcolco2*absco2

            fracs(k,ns07+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay

!  --- ...  in atmospheres where the amount of co2 is too great to be considered
!           a minor species, adjust the column amount of co2 by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(2,jp(k)+1)
        ratco2 = colamt(k,2) / temp
        if (ratco2 > 3.0) then
          adjfac = 2.0 + (ratco2-2.0)**0.79
          adjcolco2 = adjfac * temp
        else
          adjcolco2 = colamt(k,2)
        endif

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(7) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(7) + 1
        indm = indminor(k)

        do ig = 1, ng07
          absco2 = kb_mco2(indm,ig) + minorfrac(k)                      &
     &           * (kb_mco2(indm+1,ig) - kb_mco2(indm,ig))

          taug(k,ns07+ig) = colamt(k,3)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))      &
     &       + adjcolco2 * absco2

          fracs(k,ns07+ig) = fracrefb(ig)
        enddo

!  --- ...  empirical modification to code to improve stratospheric cooling rates
!           for o3.  revised to apply weighting for g-point reduction in this band.

        taug(k,ns07+ 6) = taug(k,ns07+ 6) * 0.92
        taug(k,ns07+ 7) = taug(k,ns07+ 7) * 0.88
        taug(k,ns07+ 8) = taug(k,ns07+ 8) * 1.07
        taug(k,ns07+ 9) = taug(k,ns07+ 9) * 1.1
        taug(k,ns07+10) = taug(k,ns07+10) * 0.99
        taug(k,ns07+11) = taug(k,ns07+11) * 0.855
      enddo

! ..................................
      end subroutine taugb07
! ----------------------------------

! ----------------------------------
      subroutine taugb08
! ..................................

!  ------------------------------------------------------------------  !
!     band 8:  1080-1180 cm-1 (low key - h2o; low minor - co2,o3,n2o)  !
!                             (high key - o3; high minor - co2, n2o)   !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb08

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig

      real (kind=kind_phys) :: tauself, taufor, absco2, abso3, absn2o,  &
     &      ratco2, adjfac, adjcolco2, temp
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level:
!     lower - co2, p = 1053.63 mb, t = 294.2 k
!     lower - o3,  p = 317.348 mb, t = 240.77 k
!     lower - n2o, p = 706.2720 mb, t= 278.94 k
!     lower - cfc12,cfc11
!     upper - co2, p = 35.1632 mb, t = 223.28 k
!     upper - n2o, p = 8.716e-2 mb, t = 226.03 k

!  --- ...  lower atmosphere loop

      do k = 1, laytrop

!  --- ...  in atmospheres where the amount of co2 is too great to be considered
!           a minor species, adjust the column amount of co2 by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(2,jp(k)+1)
        ratco2 = colamt(k,2) / temp
        if (ratco2 > 3.0) then
          adjfac = 2.0 + (ratco2-2.0)**0.65
          adjcolco2 = adjfac * temp
        else
          adjcolco2 = colamt(k,2)
        endif

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(8) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(8) + 1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        do ig = 1, ng08
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig)))
          absco2 = (ka_mco2(indm,ig) + minorfrac(k)                     &
     &           * (ka_mco2(indm+1,ig) - ka_mco2(indm,ig)))
          abso3  = (ka_mo3(indm,ig) + minorfrac(k)                      &
     &           * (ka_mo3(indm+1,ig) - ka_mo3(indm,ig)))
          absn2o = (ka_mn2o(indm,ig) + minorfrac(k)                     &
     &           * (ka_mn2o(indm+1,ig) - ka_mn2o(indm,ig)))

          taug(k,ns08+ig) = colamt(k,1)                                 &
     &       * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)       &
     &       +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))      &
     &       + tauself + taufor + adjcolco2*absco2 +colamt(k,3)*abso3   &
     &       + colamt(k,4)*absn2o + wx(k,3)*cfc12(ig)                   &
     &       + wx(k,4)*cfc22adj(ig)

          fracs(k,ns08+ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay

!  --- ...  in atmospheres where the amount of co2 is too great to be considered
!           a minor species, adjust the column amount of co2 by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(2,jp(k)+1)
        ratco2 = colamt(k,2) / temp
        if (ratco2 > 3.0) then
          adjfac = 2.0 + (ratco2-2.0)**0.65
          adjcolco2 = adjfac * temp
        else
          adjcolco2 = colamt(k,2)
        endif

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(8) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(8) + 1
        indm = indminor(k)

        do ig = 1, ng08
          absco2 = (kb_mco2(indm,ig) + minorfrac(k)                     &
     &           * (kb_mco2(indm+1,ig) - kb_mco2(indm,ig)))
          absn2o = (kb_mn2o(indm,ig) + minorfrac(k)                     &
     &           * (kb_mn2o(indm+1,ig) - kb_mn2o(indm,ig)))

          taug(k,ns08+ig) = colamt(k,3)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))      &
     &       + adjcolco2*absco2 + colamt(k,4)*absn2o                    &
     &       + wx(k,3)*cfc12(ig) + wx(k,4)*cfc22adj(ig)

          fracs(k,ns08+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb08
! ----------------------------------

! ----------------------------------
      subroutine taugb09
! ..................................

!  ------------------------------------------------------------------  !
!     band 9:  1180-1390 cm-1 (low key - h2o,ch4; low minor - n2o)     !
!                             (high key - ch4; high minor - n2o)       !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb09

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig, js,js1, jmn2o, jpl

      real (kind=kind_phys) :: tauself, taufor, n2om1, n2om2, absn2o,   &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_mn2o,  specparm_mn2o,  specmult_mn2o,  fmn2o,      &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      refrat_planck_a, refrat_m_a, ratn2o, adjfac, adjcoln2o,     &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2, temp
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level :
!     lower - n2o, p = 706.272 mbar, t = 278.94 k
!     upper - n2o, p = 95.58 mbar, t = 215.7 k

!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower/upper atmosphere.

      refrat_planck_a = chi_mls(1,9)/chi_mls(6,9)       ! P = 212 mb
      refrat_m_a = chi_mls(1,3)/chi_mls(6,3)            ! P = 706.272 mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,1) + rfrate(k,4,1)*colamt(k,5)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,4,2)*colamt(k,5)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_mn2o = colamt(k,1) + refrat_m_a*colamt(k,5)
        specparm_mn2o = colamt(k,1) / speccomb_mn2o
        if (specparm_mn2o >= oneminus) specparm_mn2o = oneminus
        specmult_mn2o = 8.0 * specparm_mn2o
        jmn2o = 1 + int(specmult_mn2o)
        fmn2o = mod(specmult_mn2o, f_one)

!  --- ...  in atmospheres where the amount of n2o is too great to be considered
!           a minor species, adjust the column amount of n2o by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(4,jp(k)+1)
        ratn2o = colamt(k,4) / temp
        if (ratn2o > 1.5) then
          adjfac = 0.5 + (ratn2o-0.5)**0.65
          adjcoln2o = adjfac * temp
        else
          adjcoln2o = colamt(k,4)
        endif

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,5)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(9) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(9) + js1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng09
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            n2om1 = ka_mn2o(jmn2o,indm,ig) + fmn2o                      &
     &         * (ka_mn2o(jmn2o+1,indm,ig) - ka_mn2o(jmn2o,indm,ig))
            n2om2 = ka_mn2o(jmn2o,indm+1,ig) + fmn2o                    &
     &         * (ka_mn2o(jmn2o+1,indm+1,ig) - ka_mn2o(jmn2o,indm+1,ig))
            absn2o = n2om1 + minorfrac(k) * (n2om2 - n2om1)

            taug(k,ns09+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor + adjcoln2o*absn2o            

            fracs(k,ns09+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng09
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            n2om1 = ka_mn2o(jmn2o,indm,ig) + fmn2o                      &
     &         * (ka_mn2o(jmn2o+1,indm,ig) - ka_mn2o(jmn2o,indm,ig))
            n2om2 = ka_mn2o(jmn2o,indm+1,ig) + fmn2o                    &
     &         * (ka_mn2o(jmn2o+1,indm+1,ig) - ka_mn2o(jmn2o,indm+1,ig))
            absn2o = n2om1 + minorfrac(k) * (n2om2 - n2om1)

            taug(k,ns09+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor + adjcoln2o*absn2o            

            fracs(k,ns09+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1) - fracrefa(ig,jpl))
          enddo
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng09
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            n2om1 = ka_mn2o(jmn2o,indm,ig) + fmn2o                      &
     &         * (ka_mn2o(jmn2o+1,indm,ig) - ka_mn2o(jmn2o,indm,ig))
            n2om2 = ka_mn2o(jmn2o,indm+1,ig) + fmn2o                    &
     &         * (ka_mn2o(jmn2o+1,indm+1,ig) - ka_mn2o(jmn2o,indm+1,ig))
            absn2o = n2om1 + minorfrac(k) * (n2om2 - n2om1)

            taug(k,ns09+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor + adjcoln2o*absn2o            

            fracs(k,ns09+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay

!  --- ...  in atmospheres where the amount of n2o is too great to be considered
!           a minor species, adjust the column amount of n2o by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * chi_mls(4,jp(k)+1)
        ratn2o = colamt(k,4) / temp
        if (ratn2o > 1.5) then
          adjfac = 0.5 + (ratn2o - 0.5)**0.65
          adjcoln2o = adjfac * temp
        else
          adjcoln2o = colamt(k,4)
        endif

        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(9) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(9) + 1
        indm = indminor(k)

        do ig = 1, ng09
          absn2o = kb_mn2o(indm,ig) + minorfrac(k)                      &
     &           * (kb_mn2o(indm+1,ig) - kb_mn2o(indm,ig))

          taug(k,ns09+ig) = colamt(k,5)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))      &
     &       + adjcoln2o*absn2o

          fracs(k,ns09+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb09
! ----------------------------------

! ----------------------------------
      subroutine taugb10
! ..................................

!  ------------------------------------------------------------------  !
!     band 10:  1390-1480 cm-1 (low key - h2o; high key - h2o)         !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb10

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, ig

      real (kind=kind_phys) :: tauself, taufor
!
!===> ...  begin here
!
!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(10) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(10) + 1
        inds = indself(k)
        indf = indfor(k)

        do ig = 1, ng10
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig))) 

          taug(k,ns10+ig) = colamt(k,1)                                 &
     &       * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)       &
     &       +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))      &
     &       + tauself + taufor

          fracs(k,ns10+ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(10) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(10) + 1
        indf = indfor(k)

        do ig = 1, ng10
          taufor = forfac(k) * (forref(indf,ig) + forfrac(k)            &
     &           * (forref(indf+1,ig) - forref(indf,ig))) 

          taug(k,ns10+ig) = colamt(k,1)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))      &
     &       + taufor

          fracs(k,ns10+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb10
! ----------------------------------

! ----------------------------------
      subroutine taugb11
! ..................................

!  ------------------------------------------------------------------  !
!     band 11:  1480-1800 cm-1 (low - h2o; low minor - o2)             !
!                              (high key - h2o; high minor - o2)       !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb11

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig

      real (kind=kind_phys) :: scaleo2, tauself, taufor, tauo2
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level :
!     lower - o2, p = 706.2720 mbar, t = 278.94 k
!     upper - o2, p = 4.758820 mbarm t = 250.85 k

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(11) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(11) + 1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)
        scaleo2 = colamt(k,6) * scaleminor(k)

        do ig = 1, ng11
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig)))
          tauo2 = scaleo2 * (ka_mo2(indm,ig) + minorfrac(k)             &
     &          * (ka_mo2(indm+1,ig) - ka_mo2(indm,ig)))

          taug(k,ns11+ig) = colamt(k,1)                                 &
     &       * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)       &
     &       +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))      &
     &       + tauself + taufor + tauo2

          fracs(k,ns11+ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(11) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(11) + 1
        indf = indfor(k)
        indm = indminor(k)
        scaleo2 = colamt(k,6) * scaleminor(k)

        do ig = 1, ng11
          taufor = forfac(k) * (forref(indf,ig) + forfrac(k)            &
     &           * (forref(indf+1,ig) - forref(indf,ig))) 
          tauo2  = scaleo2 * (kb_mo2(indm,ig) + minorfrac(k)            &
     &           * (kb_mo2(indm+1,ig) - kb_mo2(indm,ig)))

          taug(k,ns11+ig) = colamt(k,1)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))      &
     &       + taufor + tauo2

          fracs(k,ns11+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb11
! ----------------------------------

! ----------------------------------
      subroutine taugb12
! ..................................

!  ------------------------------------------------------------------  !
!     band 12:  1800-2080 cm-1 (low - h2o,co2; high - nothing)         !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb12

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, ig, js, js1, jpl

      real (kind=kind_phys) :: tauself, taufor, refrat_planck_a,        &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2
!
!===> ...  begin here
!
!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower/upper atmosphere.

      refrat_planck_a = chi_mls(1,10)/chi_mls(2,10)      ! P =   174.164 mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,1) + rfrate(k,1,1)*colamt(k,2)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,1,2)*colamt(k,2)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,2)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(12) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(12) + js1
        inds = indself(k)
        indf = indfor(k)

        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng12
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 

            taug(k,ns12+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor

            fracs(k,ns12+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng12
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 

            taug(k,ns12+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor

            fracs(k,ns12+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng12
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 

            taug(k,ns12+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor

            fracs(k,ns12+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        do ig = 1, ng12
          taug(k,ns12+ig) = f_zero
          fracs(k,ns12+ig) = f_zero
        enddo
      enddo

! ..................................
      end subroutine taugb12
! ----------------------------------

! ----------------------------------
      subroutine taugb13
! ..................................

!  ------------------------------------------------------------------  !
!     band 13:  2080-2250 cm-1 (low key-h2o,n2o; high minor-o3 minor)  !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb13

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig, js, js1, jmco2,   &
     &           jmco, jpl

      real (kind=kind_phys) :: tauself, taufor, co2m1, co2m2, absco2,   &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_mco2,  specparm_mco2,  specmult_mco2,  fmco2,      &
     &      speccomb_mco,   specparm_mco,   specmult_mco,   fmco,       &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      refrat_planck_a, refrat_m_a, refrat_m_a3, ratco2,           &
     &      adjfac, adjcolco2, com1, com2, absco, abso3,                &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2, temp
!
!===> ...  begin here
!
!  --- ...  minor gas mapping levels :
!     lower - co2, p = 1053.63 mb, t = 294.2 k
!     lower - co, p = 706 mb, t = 278.94 k
!     upper - o3, p = 95.5835 mb, t = 215.7 k

!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower/upper atmosphere.

      refrat_planck_a = chi_mls(1,5)/chi_mls(4,5)        ! P = 473.420 mb (Level 5)
      refrat_m_a = chi_mls(1,1)/chi_mls(4,1)             ! P = 1053. (Level 1)
      refrat_m_a3 = chi_mls(1,3)/chi_mls(4,3)            ! P = 706. (Level 3)

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,1) + rfrate(k,3,1)*colamt(k,4)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,3,2)*colamt(k,4)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_mco2 = colamt(k,1) + refrat_m_a*colamt(k,4)
        specparm_mco2 = colamt(k,1) / speccomb_mco2
        if (specparm_mco2 >= oneminus) specparm_mco2 = oneminus
        specmult_mco2 = 8.0 * specparm_mco2
        jmco2 = 1 + int(specmult_mco2)
        fmco2 = mod(specmult_mco2, f_one)

!  --- ...  in atmospheres where the amount of co2 is too great to be considered
!           a minor species, adjust the column amount of co2 by an empirical factor
!           to obtain the proper contribution.

        temp   = coldry(k) * 3.55e-4
        ratco2 = colamt(k,2) / temp
        if (ratco2 > 3.0) then
          adjfac = 2.0 + (ratco2-2.0)**0.68
          adjcolco2 = adjfac * temp
        else
          adjcolco2 = colamt(k,2)
        endif

        speccomb_mco = colamt(k,1) + refrat_m_a3*colamt(k,4)
        specparm_mco = colamt(k,1) / speccomb_mco
        if (specparm_mco >= oneminus) specparm_mco = oneminus
        specmult_mco = 8.0 * specparm_mco
        jmco = 1 + int(specmult_mco)
        fmco = mod(specmult_mco, f_one)

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,4)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(13) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(13) + js1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)

        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng13
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            co2m1 = ka_mco2(jmco2,indm,ig) + fmco2                      &
     &         * (ka_mco2(jmco2+1,indm,ig) - ka_mco2(jmco2,indm,ig))
            co2m2 = ka_mco2(jmco2,indm+1,ig) + fmco2                    &
     &         * (ka_mco2(jmco2+1,indm+1,ig) - ka_mco2(jmco2,indm+1,ig))
            absco2 = co2m1 + minorfrac(k) * (co2m2 - co2m1)
            com1 = ka_mco(jmco,indm,ig) + fmco                          &
     &           * (ka_mco(jmco+1,indm,ig) - ka_mco(jmco,indm,ig))
            com2 = ka_mco(jmco,indm+1,ig) + fmco                        &
     &           * (ka_mco(jmco+1,indm+1,ig) - ka_mco(jmco,indm+1,ig))
            absco = com1 + minorfrac(k) * (com2 - com1)

            taug(k,ns13+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor + adjcolco2*absco2                    &
     &         + colamt(k,7)*absco

            fracs(k,ns13+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng13
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            co2m1 = ka_mco2(jmco2,indm,ig) + fmco2                      &
     &         * (ka_mco2(jmco2+1,indm,ig) - ka_mco2(jmco2,indm,ig))
            co2m2 = ka_mco2(jmco2,indm+1,ig) + fmco2                    &
     &         * (ka_mco2(jmco2+1,indm+1,ig) - ka_mco2(jmco2,indm+1,ig))
            absco2 = co2m1 + minorfrac(k) * (co2m2 - co2m1)
            com1 = ka_mco(jmco,indm,ig) + fmco                          &
     &           * (ka_mco(jmco+1,indm,ig) - ka_mco(jmco,indm,ig))
            com2 = ka_mco(jmco,indm+1,ig) + fmco                        &
     &           * (ka_mco(jmco+1,indm+1,ig) - ka_mco(jmco,indm+1,ig))
            absco = com1 + minorfrac(k) * (com2 - com1)

            taug(k,ns13+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor + adjcolco2*absco2                    &
     &         + colamt(k,7)*absco

            fracs(k,ns13+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng13
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            co2m1 = ka_mco2(jmco2,indm,ig) + fmco2                      &
     &         * (ka_mco2(jmco2+1,indm,ig) - ka_mco2(jmco2,indm,ig))
            co2m2 = ka_mco2(jmco2,indm+1,ig) + fmco2                    &
     &         * (ka_mco2(jmco2+1,indm+1,ig) - ka_mco2(jmco2,indm+1,ig))
            absco2 = co2m1 + minorfrac(k) * (co2m2 - co2m1)
            com1 = ka_mco(jmco,indm,ig) + fmco                          &
     &           * (ka_mco(jmco+1,indm,ig) - ka_mco(jmco,indm,ig))
            com2 = ka_mco(jmco,indm+1,ig) + fmco                        &
     &           * (ka_mco(jmco+1,indm+1,ig) - ka_mco(jmco,indm+1,ig))
            absco = com1 + minorfrac(k) * (com2 - com1)

            taug(k,ns13+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor + adjcolco2*absco2                    &
     &         + colamt(k,7)*absco

            fracs(k,ns13+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        indm = indminor(k)
        do ig = 1, ng13
          abso3 = kb_mo3(indm,ig) + minorfrac(k)                        &
     &          * (kb_mo3(indm+1,ig) - kb_mo3(indm,ig))

          taug(k,ns13+ig) = colamt(k,3)*abso3

          fracs(k,ns13+ig) =  fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb13
! ----------------------------------

! ----------------------------------
      subroutine taugb14
! ..................................

!  ------------------------------------------------------------------  !
!     band 14:  2250-2380 cm-1 (low - co2; high - co2)                 !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb14

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, ig

      real (kind=kind_phys) :: tauself, taufor
!
!===> ...  begin here
!
!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(14) + 1
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(14) + 1
        inds = indself(k)
        indf = indfor(k)

        do ig = 1, ng14
          tauself = selffac(k) * (selfref(inds,ig) + selffrac(k)        &
     &            * (selfref(inds+1,ig) - selfref(inds,ig)))
          taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)           &
     &            * (forref(indf+1,ig) - forref(indf,ig))) 

          taug(k,ns14+ig) = colamt(k,2)                                 &
     &       * (fac00(k)*absa(ind0,ig) + fac10(k)*absa(ind0+1,ig)       &
     &       +  fac01(k)*absa(ind1,ig) + fac11(k)*absa(ind1+1,ig))      &
     &       + tauself + taufor

          fracs(k,ns14+ig) = fracrefa(ig)
        enddo
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(14) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(14) + 1

        do ig = 1, ng14
          taug(k,ns14+ig) = colamt(k,2)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))

          fracs(k,ns14+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb14
! ----------------------------------

! ----------------------------------
      subroutine taugb15
! ..................................

!  ------------------------------------------------------------------  !
!     band 15:  2380-2600 cm-1 (low - n2o,co2; low minor - n2)         !
!                              (high - nothing)                        !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb15

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, indm, ig, js, js1, jmn2, jpl

      real (kind=kind_phys) :: scalen2, tauself, taufor,                &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_mn2,   specparm_mn2,   specmult_mn2,   fmn2,       &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      refrat_planck_a, refrat_m_a, n2m1, n2m2, taun2,             &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2
!
!===> ...  begin here
!
!  --- ...  minor gas mapping level :
!     lower - nitrogen continuum, P = 1053., T = 294.

!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower atmosphere.

      refrat_planck_a = chi_mls(4,1)/chi_mls(2,1)      ! P = 1053. mb (Level 1)
      refrat_m_a = chi_mls(4,1)/chi_mls(2,1)           ! P = 1053. mb

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,4) + rfrate(k,5,1)*colamt(k,2)
        specparm = colamt(k,4) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,4) + rfrate(k,5,2)*colamt(k,2)
        specparm1 = colamt(k,4) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_mn2 = colamt(k,4) + refrat_m_a*colamt(k,2)
        specparm_mn2 = colamt(k,4) / speccomb_mn2
        if (specparm_mn2 >= oneminus) specparm_mn2 = oneminus
        specmult_mn2 = 8.0 * specparm_mn2
        jmn2 = 1 + int(specmult_mn2)
        fmn2 = mod(specmult_mn2, f_one)

        speccomb_planck = colamt(k,4) + refrat_planck_a*colamt(k,2)
        specparm_planck = colamt(k,4) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(15) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(15) + js1
        inds = indself(k)
        indf = indfor(k)
        indm = indminor(k)
         
        scalen2 = colbrd(k) * scaleminor(k)
        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng15
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            n2m1 = ka_mn2(jmn2,indm,ig) + fmn2                          &
     &           * (ka_mn2(jmn2+1,indm,ig) - ka_mn2(jmn2,indm,ig))
            n2m2 = ka_mn2(jmn2,indm+1,ig) + fmn2                        &
     &           * (ka_mn2(jmn2+1,indm+1,ig) - ka_mn2(jmn2,indm+1,ig))
            taun2 = scalen2 * (n2m1 + minorfrac(k) * (n2m2 - n2m1))

            taug(k,ns15+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor + taun2

            fracs(k,ns15+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo

        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng15
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            n2m1 = ka_mn2(jmn2,indm,ig) + fmn2                          &
     &           * (ka_mn2(jmn2+1,indm,ig) - ka_mn2(jmn2,indm,ig))
            n2m2 = ka_mn2(jmn2,indm+1,ig) + fmn2                        &
     &           * (ka_mn2(jmn2+1,indm+1,ig) - ka_mn2(jmn2,indm+1,ig))
            taun2 = scalen2 * (n2m1 + minorfrac(k) * (n2m2 - n2m1))

            taug(k,ns15+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor + taun2

            fracs(k,ns15+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo

        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng15
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 
            n2m1 = ka_mn2(jmn2,indm,ig) + fmn2                          &
     &           * (ka_mn2(jmn2+1,indm,ig) - ka_mn2(jmn2,indm,ig))
            n2m2 = ka_mn2(jmn2,indm+1,ig) + fmn2                        &
     &           * (ka_mn2(jmn2+1,indm+1,ig) - ka_mn2(jmn2,indm+1,ig))
            taun2 = scalen2 * (n2m1 + minorfrac(k) * (n2m2 - n2m1))

            taug(k,ns15+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor + taun2

            fracs(k,ns15+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif
      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        do ig = 1, ng15
          taug(k,ns15+ig) = f_zero

          fracs(k,ns15+ig) = f_zero
        enddo
      enddo

! ..................................
      end subroutine taugb15
! ----------------------------------

! ----------------------------------
      subroutine taugb16
! ..................................

!  ------------------------------------------------------------------  !
!     band 16:  2600-3250 cm-1 (low key- h2o,ch4; high key - ch4)      !
!  ------------------------------------------------------------------  !

      use module_radlw_kgb16

!  ---  locals:
      integer :: k, ind0, ind1, inds, indf, ig, js, js1, jpl

      real (kind=kind_phys) :: tauself, taufor, refrat_planck_a,        &
     &      speccomb,       specparm,       specmult,       fs,         &
     &      speccomb1,      specparm1,      specmult1,      fs1,        &
     &      speccomb_planck,specparm_planck,specmult_planck,fpl,        &
     &      fac000, fac100, fac200, fac010, fac110, fac210,             &
     &      fac001, fac101, fac201, fac011, fac111, fac211,             &
     &      p, p4, fk0, fk1, fk2
!
!===> ...  begin here
!
!  --- ...  calculate reference ratio to be used in calculation of Planck
!           fraction in lower atmosphere.

      refrat_planck_a = chi_mls(1,6)/chi_mls(6,6)        ! P = 387. mb (Level 6)

!  --- ...  lower atmosphere loop

      do k = 1, laytrop
        speccomb = colamt(k,1) + rfrate(k,4,1)*colamt(k,5)
        specparm = colamt(k,1) / speccomb
        if (specparm >= oneminus) specparm = oneminus
        specmult = 8.0 * specparm
        js = 1 + int(specmult)
        fs = mod(specmult, f_one)

        speccomb1 = colamt(k,1) + rfrate(k,4,2)*colamt(k,5)
        specparm1 = colamt(k,1) / speccomb1
        if (specparm1 >= oneminus) specparm1 = oneminus
        specmult1 = 8.0 * specparm1
        js1 = 1 + int(specmult1)
        fs1 = mod(specmult1, f_one)

        speccomb_planck = colamt(k,1) + refrat_planck_a*colamt(k,5)
        specparm_planck = colamt(k,1) / speccomb_planck
        if (specparm_planck >= oneminus) specparm_planck=oneminus
        specmult_planck = 8.0 * specparm_planck
        jpl= 1 + int(specmult_planck)
        fpl = mod(specmult_planck, f_one)

        ind0 = ((jp(k)-1)*5 + (jt (k)-1)) * nspa(16) + js
        ind1 = ( jp(k)   *5 + (jt1(k)-1)) * nspa(16) + js1
        inds = indself(k)
        indf = indfor(k)

        if (specparm < 0.125 .and. specparm1 < 0.125) then
          p = fs - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = fs1 - f_one
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng16
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 

            taug(k,ns16+ig) = speccomb                                  &
     &         * (fac000*absa(ind0   ,ig) + fac100*absa(ind0+ 1,ig)     &
     &         +  fac200*absa(ind0+ 2,ig) + fac010*absa(ind0+ 9,ig)     &
     &         +  fac110*absa(ind0+10,ig) + fac210*absa(ind0+11,ig))    &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1   ,ig) + fac101*absa(ind1+ 1,ig)     &
     &         +  fac201*absa(ind1+ 2,ig) + fac011*absa(ind1+ 9,ig)     &
     &         +  fac111*absa(ind1+10,ig) + fac211*absa(ind1+11,ig))    &
     &         + tauself + taufor

            fracs(k,ns16+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1) - fracrefa(ig,jpl))
          enddo
        elseif (specparm > 0.875 .and. specparm1 > 0.875) then
          p = -fs 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac000 = fk0*fac00(k)
          fac100 = fk1*fac00(k)
          fac200 = fk2*fac00(k)
          fac010 = fk0*fac10(k)
          fac110 = fk1*fac10(k)
          fac210 = fk2*fac10(k)

          p = -fs1 
          p4 = p**4
          fk0 = p4
          fk1 = f_one - p - 2.0*p4
          fk2 = p + p4
          fac001 = fk0*fac01(k)
          fac101 = fk1*fac01(k)
          fac201 = fk2*fac01(k)
          fac011 = fk0*fac11(k)
          fac111 = fk1*fac11(k)
          fac211 = fk2*fac11(k)

          do ig = 1, ng16
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 

            taug(k,ns16+ig) = speccomb                                  &
     &         * (fac200*absa(ind0-1,ig) + fac100*absa(ind0   ,ig)      &
     &         +  fac000*absa(ind0+1,ig) + fac210*absa(ind0+ 8,ig)      &
     &         +  fac110*absa(ind0+9,ig) + fac010*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac201*absa(ind1-1,ig) + fac101*absa(ind1   ,ig)      &
     &         +  fac001*absa(ind1+1,ig) + fac211*absa(ind1+ 8,ig)      &
     &         +  fac111*absa(ind1+9,ig) + fac011*absa(ind1+10,ig))     &
     &         + tauself + taufor

            fracs(k,ns16+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        else
          fac000 = (f_one - fs) * fac00(k)
          fac010 = (f_one - fs) * fac10(k)
          fac100 = fs * fac00(k)
          fac110 = fs * fac10(k)

          fac001 = (f_one - fs1) * fac01(k)
          fac011 = (f_one - fs1) * fac11(k)
          fac101 = fs1 * fac01(k)
          fac111 = fs1 * fac11(k)

          do ig = 1, ng16
            tauself = selffac(k)* (selfref(inds,ig) + selffrac(k)       &
     &              * (selfref(inds+1,ig) - selfref(inds,ig)))
            taufor  = forfac(k) * (forref(indf,ig) + forfrac(k)         &
     &              * (forref(indf+1,ig) - forref(indf,ig))) 

            taug(k,ns16+ig) = speccomb                                  &
     &         * (fac000*absa(ind0  ,ig) + fac100*absa(ind0+ 1,ig)      &
     &         +  fac010*absa(ind0+9,ig) + fac110*absa(ind0+10,ig))     &
     &         + speccomb1                                              &
     &         * (fac001*absa(ind1  ,ig) + fac101*absa(ind1+ 1,ig)      &
     &         +  fac011*absa(ind1+9,ig) + fac111*absa(ind1+10,ig))     &
     &         + tauself + taufor

            fracs(k,ns16+ig) = fracrefa(ig,jpl) + fpl                   &
     &         * (fracrefa(ig,jpl+1)-fracrefa(ig,jpl))
          enddo
        endif

      enddo

!  --- ...  upper atmosphere loop

      do k = laytrop+1, nlay
        ind0 = ((jp(k)-13)*5 + (jt (k)-1)) * nspb(16) + 1
        ind1 = ((jp(k)-12)*5 + (jt1(k)-1)) * nspb(16) + 1

        do ig = 1, ng16
          taug(k,ns16+ig) = colamt(k,5)                                 &
     &       * (fac00(k)*absb(ind0,ig) + fac10(k)*absb(ind0+1,ig)       &
     &       +  fac01(k)*absb(ind1,ig) + fac11(k)*absb(ind1+1,ig))

          fracs(k,ns16+ig) = fracrefb(ig)
        enddo
      enddo

! ..................................
      end subroutine taugb16
! ----------------------------------

! ..................................
      end subroutine taumol
!-----------------------------------





!
!........................................!
      end module module_radlw_main       !
!========================================!