LCOV - code coverage report
Current view: top level - dynamics/fv - dryairm.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 68 73 93.2 %
Date: 2025-03-14 01:23:43 Functions: 1 1 100.0 %

          Line data    Source code
       1             : !-----------------------------------------------------------------------
       2             : !BOP
       3             : ! !ROUTINE: dryairm --- Check dry air mass; set to a predefined value if
       4             : !                       nlres is false (initialization run)
       5             : !
       6             : ! !INTERFACE:
       7             : 
       8        2304 : subroutine dryairm( grid,  moun,  ps,   tracer,  delp,                   &
       9        2304 :                     pe,    nlres_loc )
      10             : 
      11             : ! !USES:
      12             :   use shr_kind_mod,       only: r8 => shr_kind_r8
      13             :   use dynamics_vars,      only: T_FVDYCORE_GRID
      14             : #if defined( SPMD )
      15             : #define CPP_PRT_PREFIX  if( grid%iam == 0 )
      16             : #else
      17             : #define CPP_PRT_PREFIX
      18             : #endif
      19             : 
      20             : !fvitt
      21             :  use constituents,        only: cnst_type
      22             :  use mean_module,         only: gmeanxy
      23             : 
      24             :  use pio,                 only: file_desc_t
      25             :  use cam_initfiles,       only: topo_file_get_id, scale_dry_air_mass
      26             :  use cam_logfile,         only: iulog
      27             :  implicit   none
      28             : 
      29             :  type (T_FVDYCORE_GRID), intent(in) :: grid
      30             :  logical, intent(in):: nlres_loc
      31             :  logical, intent(in):: moun
      32             : 
      33             :  real(r8), intent(inout) :: tracer(grid%ifirstxy:grid%ilastxy,                      &
      34             :                                grid%jfirstxy:grid%jlastxy,grid%km,grid%ntotq) ! Tracers
      35             :  real(r8), intent(inout) :: ps(grid%ifirstxy:grid%ilastxy,                          &
      36             :                                grid%jfirstxy:grid%jlastxy)   ! surface pressure
      37             :  real(r8), intent(inout) :: delp(grid%ifirstxy:grid%ilastxy,                        &
      38             :                                  grid%jfirstxy:grid%jlastxy,grid%km) ! press. thickness
      39             :  real(r8), intent(inout) :: pe(grid%ifirstxy:grid%ilastxy,grid%km+1,                &
      40             :                                grid%jfirstxy:grid%jlastxy)   ! edge pressure
      41             : 
      42             : ! !DESCRIPTION:
      43             : !  Perform adjustment of the total dry-air-mass while preserving total
      44             : !  tracer mass
      45             : !  Developer: S.-J. Lin, Aug 2000
      46             : !
      47             : ! !REVISION HISTORY:
      48             : !   AAM   01.06.27       Assure agreement thru roundoff for 2D decomp.
      49             : !   WS    05.07.06       Simplified interface with grid argument
      50             : !   WS    05.08.26       Modified for XY decomposition
      51             : !   WS    06.02.21       OMP bug fix (2nd to last DO), removed YZ ver.
      52             : !   WS    06.07.01       Transitioned tracers q to T_TRACERS
      53             : !
      54             : !EOP
      55             : !---------------------------------------------------------------------
      56             : !BOC
      57             : 
      58             : ! Use work arrays psdk/psdkg to assure identical answers through roundoff
      59             : !    for different z decompositions
      60             : 
      61        2304 :       real(r8), allocatable :: psdk(:,:,:)     ! local work array
      62        2304 :       real(r8), allocatable :: psdkg(:,:,:)    ! global work array
      63             : ! dry surface pressure
      64        4608 :       real(r8)    psd(grid%ifirstxy:grid%ilastxy,grid%jfirstxy:grid%jlastxy)
      65             : 
      66             :       integer :: im, jm, km                            ! Dimensions
      67             :       integer :: ifirstxy, ilastxy, jfirstxy, jlastxy  ! XY slice
      68             :       integer :: nq                            ! Number of advective tracers         
      69             :       real(r8):: ptop
      70             : 
      71             :       type(file_desc_t), pointer :: fh_topo
      72             : 
      73             :       integer  i, j, k, ic
      74             :       real(r8) psm0, psm1
      75             :       real(r8) psdry
      76             :       real(r8) dpd
      77             : 
      78        2304 :     fh_topo => topo_file_get_id()
      79             : 
      80        2304 :     im       = grid%im
      81        2304 :     jm       = grid%jm
      82        2304 :     km       = grid%km
      83             : 
      84        2304 :     ifirstxy   = grid%ifirstxy
      85        2304 :     ilastxy    = grid%ilastxy
      86        2304 :     jfirstxy   = grid%jfirstxy
      87        2304 :     jlastxy    = grid%jlastxy
      88        2304 :     nq         = grid%nq
      89        2304 :     ptop       = grid%ptop
      90             :     
      91        2304 :     if (scale_dry_air_mass <= 0.0_r8) return
      92             : 
      93             : ! Check global maximum/minimum
      94             : 
      95        2304 :     call gmeanxy( grid, ps, psm0 )
      96             : 
      97       11520 :     allocate (psdk(ifirstxy:ilastxy,jfirstxy:jlastxy,km))
      98        9216 :     allocate (psdkg(ifirstxy:ilastxy,jfirstxy:jlastxy,km))
      99             : 
     100             : !$omp  parallel do private(i,j,k)
     101      163584 :     do k=1,km
     102      647424 :        do j=jfirstxy,jlastxy
     103    12257280 :           do i=ifirstxy,ilastxy
     104    12096000 :              psdk(i,j,k) = 0._r8
     105             :           enddo
     106             :        enddo
     107             :     enddo
     108             : 
     109             : !$omp  parallel do private(i,j,k)
     110      163584 :     do k=1,km
     111      647424 :        do j=jfirstxy,jlastxy
     112    12257280 :           do i=ifirstxy,ilastxy
     113    12096000 :              psdkg(i,j,k) = 0._r8
     114             :           enddo
     115             :        enddo
     116             :     enddo
     117             : 
     118             : !$omp  parallel do private(i,j)
     119        9216 :        do j=jfirstxy,jlastxy
     120      175104 :           do i=ifirstxy,ilastxy
     121      172800 :              psdk(i,j,1) = ptop
     122             :           enddo
     123             :        enddo
     124             : 
     125        2304 :     if( nq .ne. 0 ) then
     126             : !$omp  parallel do private(i,j,k)
     127      163584 :        do k=1,km
     128      647424 :           do j=jfirstxy,jlastxy
     129    12257280 :              do i=ifirstxy,ilastxy
     130    34836480 :                 psdk(i,j,k) = psdk(i,j,k) +    &
     131    46932480 :                 (1._r8-tracer(i,j,k,1))*(pe(i,k+1,j)-pe(i,k,j))
     132             :              enddo
     133             :           enddo
     134             :        enddo
     135             :     else
     136             : 
     137             : !$omp  parallel do private(i,j,k)
     138           0 :        do k=1,km
     139           0 :           do j=jfirstxy,jlastxy
     140           0 :              do i=ifirstxy,ilastxy
     141           0 :                 psdk(i,j,k) = psdk(i,j,k) +  pe(i,k+1,j) - pe(i,k,j)
     142             :              enddo
     143             :           enddo
     144             :        enddo
     145             : 
     146             :     endif
     147             : 
     148             : !$omp  parallel do private(i,j,k)
     149      163584 :     do k=1,km
     150      647424 :        do j=jfirstxy,jlastxy
     151    12257280 :           do i=ifirstxy,ilastxy
     152    12096000 :              psdkg(i,j,k) = psdk(i,j,k)
     153             :           enddo
     154             :        enddo
     155             :     enddo
     156             : 
     157             : !$omp  parallel do private(i,j)
     158        9216 :     do j=jfirstxy,jlastxy
     159      175104 :        do i=ifirstxy,ilastxy
     160      172800 :           psd(i,j) = 0._r8
     161             :        enddo
     162             :     enddo
     163             : 
     164             :  !$omp  parallel do private(i,j,k)
     165        9216 :     do j=jfirstxy,jlastxy
     166      493056 :        do k=1,km
     167    12102912 :           do i=ifirstxy,ilastxy
     168    12096000 :              psd(i,j) = psd(i,j) + psdkg(i,j,k)
     169             :           enddo
     170             :        enddo
     171             :     enddo
     172             : 
     173        2304 :     call gmeanxy( grid, psd, psdry )
     174             :  
     175        2304 :  CPP_PRT_PREFIX write(iulog,*) 'Total Mass=', 0.01_r8*psm0, '(mb), Dry Mass=', 0.01_r8*psdry, '(mb)'
     176        2304 :  CPP_PRT_PREFIX write(iulog,*) 'Total Precipitable Water =', (psm0-psdry)/9.80616_r8, '(kg/m**2)'
     177             : 
     178        2304 :     deallocate (psdk)
     179        2304 :     deallocate (psdkg)
     180             : 
     181        2304 :     if( nlres_loc ) return
     182             : 
     183         768 :     if(moun) then
     184         768 :        dpd = scale_dry_air_mass - psdry
     185             :     else
     186           0 :        dpd = 1000._r8*100._r8 - psdry
     187             :     endif
     188         768 :  CPP_PRT_PREFIX write(iulog,*) 'dry mass to be added =', 0.01_r8*dpd
     189             : 
     190             : !$omp  parallel do private(i, j, ic)
     191             : 
     192        3072 :        do j=jfirstxy,jlastxy
     193             : 
     194      467712 :           do ic=1,nq
     195    11637504 :              do i=ifirstxy,ilastxy
     196             :                 ! fvitt
     197             :                 ! don't want to change the initial dry mixing ratios of tracers
     198    12496896 :                 if (cnst_type(ic).ne.'dry') tracer(i,j,km,ic) =        &
     199     2456064 :                    tracer(i,j,km,ic)*delp(i,j,km)/(delp(i,j,km)+dpd)
     200             :              enddo
     201             :           enddo
     202             : 
     203             : ! Adjust the lowest Lagrangian layer
     204       58368 :           do i=ifirstxy,ilastxy
     205       55296 :              delp(i,j,km) = delp(i,j,km) + dpd
     206       55296 :              pe(i,km+1,j) = pe(i,km,j) + delp(i,j,km)
     207       57600 :              ps(i,j) = pe(i,km+1,j)
     208             :           enddo
     209             :        enddo
     210             : 
     211         768 :     call gmeanxy( grid, ps, psm1 )
     212             : 
     213         768 :  CPP_PRT_PREFIX write(iulog,*) 'Total moist surface pressure after adjustment (mb) = ',0.01_r8*psm1 
     214             : 
     215             :  return
     216             : 
     217             : !EOC
     218        2304 : end subroutine dryairm
     219             : !---------------------------------------------------------------------

Generated by: LCOV version 1.14