LCOV - code coverage report
Current view: top level - atmos_phys/schemes/utilities - geopotential_temp.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 57 63 90.5 %
Date: 2025-01-13 21:54:50 Functions: 1 1 100.0 %

          Line data    Source code
       1             : module geopotential_temp
       2             : 
       3             :    !---------------------------------------------------------------------------
       4             :    ! Compute geopotential from temperature
       5             :    !
       6             :    ! The hydrostatic matrix elements must be consistent with the dynamics
       7             :    !      algorithm.
       8             :    ! The diagonal element is the itegration weight from interface kint minus
       9             :    !      lyr_step to midpoint kint.
      10             :    ! The offdiagonal element is the weight between interfaces.
      11             :    !
      12             :    ! Author: B.Boville, Feb 2001 from earlier code by Boville and S.J. Lin
      13             :    !---------------------------------------------------------------------------
      14             : 
      15             :    use ccpp_kinds,                only: kind_phys
      16             :    use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t
      17             : 
      18             :    implicit none
      19             :    private
      20             :    save
      21             : 
      22             :    public geopotential_temp_run
      23             : 
      24             : CONTAINS
      25             :    !===========================================================================
      26             : 
      27             :    !> \section arg_table_geopotential_temp_run  Argument Table
      28             :    !! \htmlinclude geopotential_temp_run.html
      29    23907312 :    subroutine geopotential_temp_run(pver, lagrang, layer_surf, layer_toa,        &
      30    23907312 :         interface_surf, interface_toa, ncnst, piln, pint, pmid, pdel, rpdel,  &
      31    47814624 :         temp, qv, carr, cprops, rair, gravit, zvir, zi, zm, ncol,             &
      32           0 :         errflg, errmsg)
      33             : 
      34             :       !-----------------------------------------------------------------------
      35             :       !
      36             :       ! Purpose:
      37             :       ! Compute the geopotential height (above the surface) at the midpoints and
      38             :       ! interfaces using the input temperatures and pressures.
      39             :       !
      40             :       !-----------------------------------------------------------------------
      41             : 
      42             :       !------------------------------Arguments--------------------------------
      43             :       !
      44             :       ! Input arguments
      45             :       !
      46             :       integer,         intent(in)  :: pver
      47             :       logical,         intent(in)  :: lagrang     ! lagrangian vertical coordinate?
      48             :       integer,         intent(in)  :: layer_surf
      49             :       integer,         intent(in)  :: layer_toa
      50             :       integer,         intent(in)  :: interface_surf
      51             :       integer,         intent(in)  :: interface_toa
      52             :       integer,         intent(in)  :: ncnst       ! Number of constituents
      53             :       integer,         intent(in)  :: ncol        ! Number of columns
      54             : 
      55             :       ! piln: Log interface pressures
      56             :       real(kind_phys), intent(in)                   :: piln(:,:)   ! (ncol,pverp)
      57             :       ! pint: Interface pressures
      58             :       real(kind_phys), intent(in)                   :: pint(:,:)   ! (ncol,pverp)
      59             :       ! pmid: Midpoint pressures
      60             :       real(kind_phys), intent(in)                   :: pmid(:,:)   ! (ncol,pver)
      61             :       ! pdel: layer thickness
      62             :       real(kind_phys), intent(in)                   :: pdel(:,:)   ! (ncol,pver)
      63             :       ! rpdel: inverse of layer thickness
      64             :       real(kind_phys), intent(in)                   :: rpdel(:,:)  ! (ncol,pver)
      65             :       ! temp: temperature
      66             :       real(kind_phys), intent(in)                   :: temp(:,:)   ! (ncol,pver)
      67             :       ! qv: specific humidity
      68             :       real(kind_phys), intent(in)                   :: qv(:,:)     ! (ncol,pver)
      69             :       ! carr: ccpp constituents
      70             :       real(kind_phys), intent(in)                   :: carr(:,:,:) ! (ncol, pver, num_const)
      71             :       ! cprops: ccpp constituent properties
      72             :       type(ccpp_constituent_prop_ptr_t), intent(in) :: cprops(:) ! (num_const)
      73             :       ! rair: Gas constant for dry air
      74             :       real(kind_phys), intent(in)                   :: rair(:,:)   ! (ncol,pver)
      75             :       ! gravit: Acceleration of gravity
      76             :       real(kind_phys), intent(in)                   :: gravit
      77             :       ! zvir: rh2o/rair - 1
      78             :       real(kind_phys), intent(in)                   :: zvir(:,:)  ! (ncol,pver)
      79             : 
      80             :       ! Output arguments
      81             : 
      82             :       ! zi: Height above surface at interfaces
      83             :       real(kind_phys), intent(out)    :: zi(:,:)    ! (ncol,pverp)
      84             :       ! zm: Geopotential height at mid level
      85             :       real(kind_phys), intent(out)    :: zm(:,:)    ! (ncol,pver)
      86             :       integer,            intent(out) :: errflg
      87             :       character(len=512), intent(out) :: errmsg
      88             :       !
      89             :       !---------------------------Local variables-----------------------------
      90             :       !
      91             :       logical                      :: active_flag     ! Flag for whether consitutent is thermodynamically active
      92             :       logical                      :: water_flag      ! Flag for whether constituent is a water species
      93             :       integer                      :: icol            ! Horizontal index
      94             :       integer                      :: klyr            ! Vertical layer index
      95             :       integer                      :: kint            ! Vertical interface index
      96             :       integer                      :: cidx            ! CCPP constituent index
      97             :       integer                      :: lyr_step        ! increment to move up a level
      98             :       integer                      :: int_step        ! increment to move up a level
      99    47814624 :       real(kind_phys)              :: hkk(ncol)       ! diagonal element of hydrostatic matrix
     100    47814624 :       real(kind_phys)              :: hkl(ncol)       ! off-diagonal element
     101    47814624 :       real(kind_phys)              :: rog(ncol,pver)  ! Rair / gravit
     102             :       real(kind_phys)              :: tv              ! virtual temperature
     103             :       real(kind_phys)              :: tvfac           ! Tv / T
     104    47814624 :       real(kind_phys)              :: qfac(ncol,pver) ! factor to convert from wet to dry mixing ratio
     105    23907312 :       real(kind_phys)              :: sum_dry_mixing_ratio(ncol,pver) ! sum of dry water mixing ratios
     106             :       !
     107             :       !-----------------------------------------------------------------------
     108             :       !
     109             : 
     110    23907312 :       errmsg = ''
     111    23907312 :       errflg = 0
     112             : 
     113 10403016624 :       rog(:ncol,:) = rair(:ncol,:) / gravit
     114             : 
     115             :       ! Determine order of vertical dimension loop
     116    23907312 :       if (layer_surf > layer_toa) then
     117             :          lyr_step = -1
     118             :       else
     119           0 :          lyr_step = 1
     120             :       end if
     121    23907312 :       if (interface_surf > interface_toa) then
     122             :          int_step = -1
     123             :       else
     124           0 :          int_step = 1
     125             :       end if
     126             : 
     127             :       ! The surface height is zero by definition.
     128   399196512 :       zi(:ncol, interface_surf) = 0.0_kind_phys
     129             : 
     130             :       ! For the computation of generalized virtual temperature (equation 16
     131             :       ! in Lauritzen et al. (2018);  https://doi.org/10.1029/2017MS001257)
     132             :       !
     133             :       ! Compute factor for converting wet to dry mixing ratio (eq.7)
     134             :       !
     135 10403016624 :       qfac        = 1._kind_phys
     136    23907312 :       active_flag = .false.
     137    23907312 :       water_flag  = .false.
     138    95629248 :       do cidx = 1,ncnst
     139             :          ! Check if constituent is thermodynamically active:
     140    71721936 :          call cprops(cidx)%is_thermo_active(active_flag)
     141    95629248 :          if (active_flag) then
     142             :             ! Check if consitutent is also a water species:
     143    71721936 :             call cprops(cidx)%is_water_species(water_flag)
     144    71721936 :             if (water_flag) then
     145  1936492272 :                do klyr = layer_surf, layer_toa, lyr_step
     146 31209049872 :                   do icol = 1, ncol
     147             :                      ! Add thermodynamically active water species
     148             :                      ! to mixing ratio factor:
     149 58545115200 :                      qfac(icol, klyr) = qfac(icol, klyr) -                    &
     150 89682443136 :                                         carr(icol, klyr, cidx)
     151             :                   end do
     152             :                end do
     153             :             end if
     154             :          end if
     155             :       end do
     156 10403016624 :       qfac = 1._kind_phys/qfac
     157             : 
     158             :       ! Compute sum of thermodynamically active water
     159             :       ! constituent mixing ratios with respect to dry air:
     160 10403016624 :       sum_dry_mixing_ratio = 1._kind_phys
     161    23907312 :       active_flag          = .false.
     162    23907312 :       water_flag           = .false.
     163    95629248 :       do cidx = 1,ncnst
     164             :          !Check if constituent is thermodynamically active:
     165    71721936 :          call cprops(cidx)%is_thermo_active(active_flag)
     166    95629248 :          if (active_flag) then
     167             :             !Check if consitutent is also a water species:
     168    71721936 :             call cprops(cidx)%is_water_species(water_flag)
     169    71721936 :             if (water_flag) then
     170  1936492272 :                do klyr = layer_surf, layer_toa, lyr_step
     171 31209049872 :                   do icol = 1, ncol
     172 58545115200 :                      sum_dry_mixing_ratio(icol, klyr) =                       &
     173             :                         sum_dry_mixing_ratio(icol, klyr) +                    &
     174 89682443136 :                         carr(icol, klyr, cidx) * qfac(icol,klyr)
     175             :                   end do
     176             :                end do
     177             :             end if
     178             :          end if
     179             :       end do
     180 10403016624 :       sum_dry_mixing_ratio(:,:) = 1._kind_phys/sum_dry_mixing_ratio(:,:)
     181             : 
     182             :       ! Compute zi, zm from bottom up.
     183             :       ! Note, zi(i,k) is the interface above zm(i,k) when ordered top to bot
     184             : 
     185    23907312 :       klyr = layer_surf
     186    23907312 :       do kint = interface_surf + int_step, interface_toa, int_step
     187             : 
     188             :          ! First set hydrostatic elements consistent with dynamics
     189   621590112 :          if (lagrang) then
     190           0 :             do icol = 1, ncol
     191           0 :                hkl(icol) = piln(icol, kint-int_step) - piln(icol,kint)
     192             :                hkk(icol) = 1._kind_phys -                                     &
     193           0 :                     (pint(icol,kint) * hkl(icol) * rpdel(icol,klyr))
     194             :             end do
     195             :          else
     196 10379109312 :             do icol = 1,ncol
     197  9757519200 :                hkl(icol) = pdel(icol,klyr) / pmid(icol,klyr)
     198 10379109312 :                hkk(icol) = 0.5_kind_phys * hkl(icol)
     199             :             end do
     200             :          end if
     201             : 
     202             :          ! Now compute tv, zm, zi
     203             : 
     204 10379109312 :          do icol = 1, ncol
     205 19515038400 :             tvfac   = (1._kind_phys + (zvir(icol,klyr) + 1._kind_phys) *      &
     206  9757519200 :                       qv(icol,klyr)*qfac(icol,klyr)) *                        &
     207 19515038400 :                       sum_dry_mixing_ratio(icol,klyr)
     208  9757519200 :             tv      = temp(icol,klyr) * tvfac
     209             : 
     210 19515038400 :             zm(icol,klyr) = zi(icol,kint-int_step) +                          &
     211  9757519200 :                  (rog(icol,klyr) * tv * hkk(icol))
     212  9757519200 :             zi(icol,kint) = zi(icol,kint-int_step) +                          &
     213 20136628512 :                  (rog(icol,klyr) * tv * hkl(icol))
     214             :          end do
     215   621590112 :          klyr = klyr + lyr_step
     216             :       end do
     217             : 
     218    23907312 :    end subroutine geopotential_temp_run
     219             : 
     220             : end module geopotential_temp

Generated by: LCOV version 1.14