LCOV - code coverage report
Current view: top level - physics/carma/base - versol.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 44 50 88.0 %
Date: 2025-03-14 01:30:37 Functions: 1 1 100.0 %

          Line data    Source code
       1             : ! Include shortname defintions, so that the F77 code does not have to be modified to
       2             : ! reference the CARMA structure.
       3             : #include "carma_globaer.h"
       4             : 
       5             : !!  This routine solves the vertical transport equation.
       6             : !!  <cvert> is temporary storage for concentrations (particles,
       7             : !!  gas, potential temperature) being transported.
       8             : !!  New values of <cvert> are calculated.
       9             : !!
      10             : !! @author Eric Jensen
      11             : !! @version Dec-1996
      12   231137280 : subroutine versol(carma, cstate, cvert, itbnd, ibbnd, ftop, fbot, cvert_tbnd, cvert_bbnd, &
      13   231137280 :   vertadvu, vertadvd, vertdifu, vertdifd, rc)
      14             : 
      15             :   ! types
      16             :   use carma_precision_mod
      17             :   use carma_enums_mod
      18             :   use carma_constants_mod
      19             :   use carma_types_mod
      20             :   use carmastate_mod
      21             :   use carma_mod
      22             : 
      23             :   implicit none
      24             : 
      25             :   type(carma_type), intent(in)         :: carma           !! the carma object
      26             :   type(carmastate_type), intent(inout) :: cstate          !! the carma state object
      27             :   real(kind=f), intent(inout)          :: cvert(NZ)       !! quantity being transported
      28             :   integer, intent(in)                  :: itbnd           !! top boundary condition
      29             :   integer, intent(in)                  :: ibbnd           !! bottom boundary condition
      30             :   real(kind=f), intent(in)             :: ftop            !! flux at top boundary
      31             :   real(kind=f), intent(in)             :: fbot            !! flux at bottom boundary
      32             :   real(kind=f), intent(in)             :: cvert_tbnd      !! quantity at top boundary
      33             :   real(kind=f), intent(in)             :: cvert_bbnd      !! quantity at bottom boundary
      34             :   real(kind=f), intent(in)             :: vertadvu(NZP1)  !! upward vertical transport rate into level k from level k-1 [cm/s]
      35             :   real(kind=f), intent(in)             :: vertadvd(NZP1)  !! downward vertical transport rate into level k from level k-1 [cm/s]
      36             :   real(kind=f), intent(in)             :: vertdifu(NZP1)  !! upward vertical diffusion rate into level k from level k-1 [cm/s]
      37             :   real(kind=f), intent(in)             :: vertdifd(NZP1)  !! downward vertical diffusion rate into level k from level k-1 [cm/s]
      38             :   integer, intent(inout)               :: rc              !! return code, negative indicates failure
      39             : 
      40             : !  Declare local variables
      41             : !
      42             :   integer                        :: k
      43   462274560 :   real(kind=f)                   :: al(NZ)
      44   462274560 :   real(kind=f)                   :: bl(NZ)
      45   462274560 :   real(kind=f)                   :: dl(NZ)
      46   462274560 :   real(kind=f)                   :: el(NZ)
      47   462274560 :   real(kind=f)                   :: fl(NZ)
      48   462274560 :   real(kind=f)                   :: ul(NZ)
      49   462274560 :   real(kind=f)                   :: ctempl(NZ)
      50   462274560 :   real(kind=f)                   :: ctempu(NZ)
      51   231137280 :   real(kind=f)                   :: divcor(NZ)
      52             :   real(kind=f)                   :: uc
      53             :   real(kind=f)                   :: cour
      54             :   real(kind=f)                   :: denom
      55             :      
      56             :   ! Divergence adjustments are not being generated.
      57  7627530240 :   divcor(:) = 0._f
      58             : 
      59             :   ! Determine whether transport should be solved explicitly (uc=0)
      60             :   ! or implicitly (uc=1).
      61   231137280 :   uc = 0._f
      62  7627530240 :   do k = 1,NZ
      63           0 :     cour = dz(k)/dtime - &
      64  7396392960 :     ( vertdifu(k+1) + vertdifd(k) + vertadvu(k+1) + vertadvd(k) )
      65             : 
      66  7627530240 :     if( cour .lt. 0._f .and. uc .ne. 1._f )then
      67    11166406 :       uc = 1.0_f
      68             : 
      69             :       ! NOTE: This can happen a lot and clutters up the log. Should we print it out or not?     
      70             : !      write(LUNOPRT,'(a,i3,7(1x,1pe8.1))') &
      71             : !         'in versol: k dz/dt vdifd vdifu vadvd vadvu cour uc = ', &
      72             : !          k, dz(k)/dtime, vertdifd(k), vertdifu(k+1), &
      73             : !          vertadvd(k), vertadvu(k+1), cour, uc
      74             :     endif
      75             :   enddo
      76             : 
      77             :   ! Store concentrations in local variables (shifted up and down
      78             :   ! a vertical level).
      79  7396392960 :   do k = 2,NZ
      80  7165255680 :     ctempl(k) = cvert(k-1)
      81  7396392960 :     ctempu(k-1) = cvert(k)
      82             :   enddo
      83             : 
      84   231137280 :   if( ibbnd .eq. I_FIXED_CONC ) then
      85   231137280 :     ctempl(1) = cvert_bbnd
      86             :   else
      87           0 :     ctempl(1) = 0._f
      88             :   endif
      89             : 
      90   231137280 :   if( itbnd .eq. I_FIXED_CONC ) then
      91   231137280 :     ctempu(NZ) = cvert_tbnd
      92             :   else
      93           0 :     ctempu(NZ) = 0._f
      94             :   endif
      95             :   
      96             :   ! Calculate coefficients of the transport equation:
      97             :   !   al(k)c(k+1) + bl(k)c(k) + ul(k)c(k-1) = dl(k)
      98             : 
      99  7627530240 :   do k = 1,NZ
     100  7396392960 :     al(k) = uc * ( vertdifd(k+1) + vertadvd(k+1) )
     101  7396392960 :     bl(k) = -( uc*(vertdifd(k)+vertdifu(k+1)+ &
     102             :                    vertadvd(k)+vertadvu(k+1)) &
     103  7396392960 :                + dz(k)/dtime )
     104  7396392960 :     ul(k) = uc * ( vertdifu(k) + vertadvu(k) )
     105             :     dl(k) = cvert(k) * &
     106             :       ( (1._f - uc)*(vertdifd(k)+vertdifu(k+1)+ &
     107             :                  vertadvd(k)+vertadvu(k+1)) &
     108           0 :       - dz(k)/dtime ) - &
     109             :       (1._f - uc) * ( (vertdifu(k)+vertadvu(k))*ctempl(k) + &
     110             :       (vertdifd(k+1)+vertadvd(k+1))*ctempu(k) ) - &
     111  7627530240 :       divcor(k) * dz(k)
     112             :   enddo
     113             : 
     114             :   ! Boundary fluxes: <ftop> is the downward flux across the
     115             :   ! upper boundary; <fbot> is the upward flux across the
     116             :   ! lower boundary.
     117   231137280 :   if(( igridv .eq. I_SIG ) .or. ( igridv .eq. I_HYBRID )) then
     118   231137280 :     if( itbnd .eq. I_FLUX_SPEC ) dl(1) = dl(1) - ftop
     119   231137280 :     if( ibbnd .eq. I_FLUX_SPEC ) dl(NZ) = dl(NZ) - fbot
     120             :   else
     121           0 :     if( itbnd .eq. I_FLUX_SPEC ) dl(NZ) = dl(NZ) - ftop
     122           0 :     if( ibbnd .eq. I_FLUX_SPEC ) dl(1) = dl(1) - fbot
     123             :   endif
     124             : 
     125             :   ! Calculate recursion relations.
     126   231137280 :   el(1) = dl(1)/bl(1)
     127   231137280 :   fl(1) = al(1)/bl(1)
     128  7396392960 :   do k = 2,NZ
     129  7165255680 :     denom = bl(k) - ul(k) * fl(k-1)
     130  7165255680 :     el(k) = ( dl(k) - ul(k)*el(k-1) ) / denom
     131  7396392960 :     fl(k) = al(k) / denom
     132             :   enddo
     133             : 
     134             :   ! Calculate new concentrations.
     135             : 
     136   231137280 :   cvert(NZ) = el(NZ)
     137  7396392960 :   do k = NZ-1,1,-1
     138  7396392960 :     cvert(k) = el(k) - fl(k)*cvert(k+1)
     139             :   enddo
     140             : 
     141             :   ! Return to caller with new concentrations.
     142   231137280 :   return
     143   231137280 : end

Generated by: LCOV version 1.14