⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfilt_massfix.f90

📁 CCSM Research Tools: Community Atmosphere Model (CAM)
💻 F90
字号:
#include <misc.h>#include <params.h>subroutine tfilt_massfix (ztodt,         lat,    u3m1,   u3,     &                          v3m1,   v3,    t3m1,   t3,     q3m1,   &                          q3,     psm1,  ps,             alpha,  &                          etamid, qfcst, vort,   div,    vortm2, &                          divm2,         qminus, psm2,   um2,    &                          vm2,    tm2,   qm2,    vortm1, divm1,  &                          omga,   dpsl,  dpsm,   nlon)!----------------------------------------------------------------------- ! ! Purpose: ! Time filter (second half of filter for vorticity and divergence only)! ! Method: ! ! Author: ! !-----------------------------------------------------------------------   use precision   use history, only: outfld   use pmgrid   use pspect   use commap   use constituents, only: pcnst, pnats, qmin   use tracers, only: tottnam, tendnam   use time_manager, only: get_nstep   implicit none#include <comctl.h>#include <comlun.h>#include <comqfl.h>#include <comtfc.h>!! Input arguments!   real(r8), intent(in) :: ztodt                  ! two delta t (unless nstep<2)   real(r8), intent(in) :: qfcst(plond,plev,pcnst)! slt moisture forecast   real(r8), intent(in) :: vort(plond,plev)   real(r8), intent(in) :: div(plond,plev)   real(r8), intent(inout) :: vortm2(plond,plev)   real(r8), intent(inout) :: divm2(plond,plev)   real(r8), intent(in) :: qminus(plond,plev,pcnst)   real(r8), intent(inout) :: psm2(plond)   real(r8), intent(inout) :: um2(plond,plev)   real(r8), intent(inout) :: vm2(plond,plev)   real(r8), intent(inout) :: tm2(plond,plev)   real(r8), intent(inout) :: qm2(plond,plev,pcnst+pnats)   real(r8), intent(inout) :: omga(plond,plev)   real(r8), intent(in) :: dpsl(plond)   real(r8), intent(in) :: dpsm(plond)   real(r8), intent(in) :: alpha(pcnst)   real(r8), intent(in) :: etamid(plev)           ! vertical coords at midpoints    real(r8), intent(in) :: u3(plond,plev)   real(r8), intent(in) :: v3(plond,plev)   real(r8), intent(in) :: t3(plond,plev)   integer, intent(in) :: lat   integer, intent(in) :: nlon! Input/Output arguments   real(r8), intent(inout) :: q3(plond,plev,pcnst+pnats)   real(r8), intent(inout) :: ps(plond)   real(r8), intent(inout) :: vortm1(plond,plev)   real(r8), intent(inout) :: psm1(plond)   real(r8), intent(inout) :: u3m1(plond,plev)   real(r8), intent(inout) :: v3m1(plond,plev)   real(r8), intent(inout) :: t3m1(plond,plev)   real(r8), intent(inout) :: divm1(plond,plev)   real(r8), intent(inout) :: q3m1(plond,plev,pcnst+pnats)!! Local workspace!   integer ifcnt                   ! Counter   integer :: nstep                ! current timestep number   real(r8) rpmid(plond,plev)      ! 1./pmid   real(r8) pdel(plond,plev)       ! pdel(k)   = pint  (k+1)-pint  (k)   real(r8) pint(plond,plevp)      ! pressure at model interfaces (n  )   real(r8) pmid(plond,plev)       ! pressure at model levels (time n)   real(r8) utend(plond,plev)      ! du/dt   real(r8) vtend(plond,plev)      ! dv/dt   real(r8) ttend(plond,plev)      ! dT/dt   real(r8) qtend(plond,plev,pcnst)! dq/dt   real(r8) pstend(plond)          ! d(ps)/dt   real(r8) pintm1(plond,plevp)    ! pressure at model interfaces (n-1)   real(r8) pmidm1(plond,plev)     ! pressure at model levels (time n-1)   real(r8) pdelm1(plond,plev)     ! pdelm1(k) = pintm1(k+1)-pintm1(k)   real(r8) om2eps   real(r8) corm   real(r8) wm   real(r8) absf   real(r8) worst   logical lfixlim               ! flag to turn on fixer limiter   real(r8) ta(plond,plev,pcnst)   ! total advection of constituents   real(r8) dqfx3(plond,plev,pcnst)! q tendency due to mass adjustment   real(r8) coslat                 ! cosine(latitude)   real(r8) rcoslat(plond)         ! 1./cosine(latitude)!   real(r8) engt                   ! Thermal   energy integral!   real(r8) engk                   ! Kinetic   energy integral!   real(r8) engp                   ! Potential energy integral   integer i, k, m!-----------------------------------------------------------------------   nstep = get_nstep()   coslat = cos(clat(lat))   do i=1,nlon     rcoslat(i) = 1./coslat   enddo   lfixlim = .true.   corm    = 0.1!! Set average dry mass to specified constant preserving horizontal! gradients of ln(ps). Proportionality factor was calculated in STEPON! for nstep=0 or SCAN2 otherwise from integrals calculated in INIDAT! and SCAN2 respectively.! Set p*.!   do i=1,nlon      ps(i) = ps(i)*fixmas   end do!! Set current time pressure arrays for model levels etc.!   call plevs0(nlon    ,plond   ,plev    ,ps      ,pint    ,pmid    ,pdel)!   rpmid(:nlon,:plev) = 1./pmid(:nlon,:plev)!! Compute q tendency due to mass adjustment! If LFIXLIM = .T., then:! Check to see if fixer is exceeding a desired fractional limit of the! constituent mixing ratio ("corm").  If so, then limit the fixer to! that specified limit.!   do m=1,pcnst      do k=1,plev         do i=1,nlon            dqfx3(i,k,m) = alpha(m)*etamid(k)*abs(qfcst(i,k,m) - qminus(i,k,m))         end do         if (lfixlim) then            ifcnt = 0            worst = 0.            wm    = 0.            do i = 1,nlon               absf = abs(dqfx3(i,k,m))               if (absf.gt.corm) then                  ifcnt = ifcnt + 1                  worst = max(absf,worst)                  wm = wm + absf                  dqfx3(i,k,m) = sign(corm,dqfx3(i,k,m))               endif            end do            if (ifcnt.gt.0) then               wm = wm/float(ifcnt)#ifndef HADVTEST               write (6,1000) m,corm,ifcnt,k,lat,wm,worst#endif            endif         endif         do i=1,nlon            dqfx3(i,k,m) = qfcst(i,k,m)*dqfx3(i,k,m)/ztodt#ifdef HADVTEST            q3(i,k,m) = qfcst(i,k,m)#else            q3(i,k,m) = qfcst(i,k,m) + ztodt*dqfx3(i,k,m)#endif            ta(i,k,m) = (q3(i,k,m) - qminus(i,k,m))/ztodt         end do      end do   end do!! Check for and correct invalid constituents!   call qneg3 ('TFILT_MASSFIX',lat   ,nlon    ,plond   ,plev    , &               pcnst+pnats,qmin ,q3(1,1,1))!! Send slt tendencies to the history tape!   do m=1,pcnst      call outfld(tottnam(m),ta(1,1,m),plond   ,lat     )   end do!! Calculate vertical motion field!   call omcalc (rcoslat ,div     ,u3      ,v3      ,dpsl    ,  &                dpsm    ,pmid    ,pdel    ,rpmid   ,pint(1,plevp), &                omga    ,nlon    )!   write(6,*)'tfilt: lat=',lat!   write(6,*)'omga=',omga!! Time filter (second half of filter for vorticity and divergence only)!!   if(lat.eq.2) then!      write(6,*)'tfilt: ps=',psm2(13),psm1(13),ps(13)!      write(6,*)'tfilt: u=',um2(13,18),u3m1(13,18),u3(13,18)!      write(6,*)'tfilt: t=',tm2(13,18),t3m1(13,18),t3(13,18)!      write(6,*)'tfilt: water=',qm2(13,18,1),q3m1(13,18,1),q3(13,18,1)!      write(6,*)'tfilt: cwat=',qm2(13,18,2),q3m1(13,18,2),q3(13,18,2)!      write(6,*)'tfilt: vort=',vortm2(13,18),vortm1(13,18),vort(13,18)!      write(6,*)'tfilt: div=',divm2(13,18),divm1(13,18),div(13,18)!   end if   om2eps = 1. - 2.*eps   if (nstep.ge.2) then      do k=1,plev         do i=1,nlon            u3m1(i,k) = om2eps*u3m1(i,k) + eps*um2(i,k) + eps*u3(i,k)            v3m1(i,k) = om2eps*v3m1(i,k) + eps*vm2(i,k) + eps*v3(i,k)            t3m1(i,k) = om2eps*t3m1(i,k) + eps*tm2(i,k) + eps*t3(i,k)            q3m1(i,k,1) = om2eps*q3m1(i,k,1) + eps*qm2(i,k,1) + eps*q3(i,k,1)            vortm1(i,k) = om2eps*vortm1(i,k) + eps*vortm2(i,k) + eps*vort(i,k)            divm1(i,k) = om2eps*divm1(i,k) + eps*divm2(i,k) + eps*div(i,k)         end do         do m=2,pcnst+pnats            do i=1,nlon               q3m1(i,k,m) = om2eps*q3m1(i,k,m) + eps*qm2(i,k,m) + eps*q3(i,k,m)            end do         end do      end do      do i=1,nlon         psm1(i) = om2eps*psm1(i) + eps*psm2(i) + eps*ps(i)      end do   end if   call plevs0 (nlon    ,plond   ,plev    ,psm1    ,pintm1  ,pmidm1  ,pdelm1)!! Compute time tendencies:comment out since currently not on h-t!   do k=1,plev      do i=1,nlon         ttend(i,k) = (t3(i,k)-tm2(i,k))/ztodt         utend(i,k) = (u3(i,k)-um2(i,k))/ztodt         vtend(i,k) = (v3(i,k)-vm2(i,k))/ztodt      end do   end do   do m=1,pcnst      do k=1,plev         do i=1,nlon            qtend(i,k,m) = (q3(i,k,m) - qm2(i,k,m))/ztodt         end do      end do   end do   do i=1,nlon      pstend(i) = (ps(i) - psm2(i))/ztodt   end do!   do m=1,pcnst      call outfld (tendnam(m),qtend(1,1,m),plond,lat)   end do   call outfld ('UTEND   ',utend,plond,lat)   call outfld ('VTEND   ',vtend,plond,lat)   call outfld ('TTEND   ',ttend,plond,lat)   call outfld ('LPSTEN  ',pstend,plond,lat)   return1000 format(' TIMEFILTER: WARNING: fixer for tracer ',i3,' exceeded ', &      f8.5,' for ',i5,' points at k,lat = ',2i4, &      ' Avg/Worst = ',1p2e10.2)end subroutine  tfilt_massfix

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -