zm_conv.f90

来自「CCSM Research Tools: Community Atmospher」· F90 代码 · 共 1,872 行 · 第 1/5 页

F90
1,872
字号
!------------------------------------------------------------------------------!   do i = 1,il2g      ftemp(i) = 0.      expnum(i) = 0.      expdif(i) = 0.   end do!!jr Change from msg+1 to 1 to prevent blowup!   do k = 1,pver      do i = 1,il2g         dz(i,k) = zf(i,k) - zf(i,k+1)      end do   end do!! initialize many output and work variables to zero!   pflx(:il2g,1) = 0   do k = msg + 1,pver      do i = 1,il2g         k1(i,k) = 0.         i2(i,k) = 0.         i3(i,k) = 0.         i4(i,k) = 0.         mu(i,k) = 0.         f(i,k) = 0.         eps(i,k) = 0.         eu(i,k) = 0.         du(i,k) = 0.         ql(i,k) = 0.         cu(i,k) = 0.         evp(i,k) = 0.         cmeg(i,k) = 0.         qds(i,k) = q(i,k)         md(i,k) = 0.         ed(i,k) = 0.         sd(i,k) = s(i,k)         qd(i,k) = q(i,k)         mc(i,k) = 0.         qu(i,k) = q(i,k)         su(i,k) = s(i,k)!        est(i)=exp(a-b/t(i,k))         est(i) = c1*exp((c2* (t(i,k)-tfreez))/((t(i,k)-tfreez)+c3))!++bee         if ( p(i,k)-est(i) > 0. ) then            qst(i,k) = eps1*est(i)/ (p(i,k)-est(i))         else            qst(i,k) = 1.0         end if!--bee         gamma(i,k) = qst(i,k)*(1. + qst(i,k)/eps1)*eps1*rl/(rd*t(i,k)**2)*rl/cp         hmn(i,k) = cp*t(i,k) + grav*z(i,k) + rl*q(i,k)         hsat(i,k) = cp*t(i,k) + grav*z(i,k) + rl*qst(i,k)         hu(i,k) = hmn(i,k)         hd(i,k) = hmn(i,k)         mu2(i,k) = 0.         eu2(i,k) = 0.         du2(i,k) = 0.         md2(i,k) = 0.         ed2(i,k) = 0.         pflx(i,k) = 0.         cmfdqr(i,k) = 0.      end do   end do!!jr Set to zero things which make this routine blow up!   do k=1,msg      do i=1,il2g         cmfdqr(i,k) = 0.         mu2(i,k) = 0.         eu2(i,k) = 0.         du2(i,k) = 0.         md2(i,k) = 0.         ed2(i,k) = 0.      end do   end do!! interpolate the layer values of qst, hsat and gamma to! layer interfaces!   do i = 1,il2g      hsthat(i,msg+1) = hsat(i,msg+1)      qsthat(i,msg+1) = qst(i,msg+1)      gamhat(i,msg+1) = gamma(i,msg+1)      totpcp(i) = 0.      totevp(i) = 0.   end do   do k = msg + 2,pver      do i = 1,il2g         if (abs(qst(i,k-1)-qst(i,k)) > 1.E-6) then            qsthat(i,k) = log(qst(i,k-1)/qst(i,k))*qst(i,k-1)*qst(i,k)/ (qst(i,k-1)-qst(i,k))         else            qsthat(i,k) = qst(i,k)         end if         hsthat(i,k) = cp*shat(i,k) + rl*qsthat(i,k)         if (abs(gamma(i,k-1)-gamma(i,k)) > 1.E-6) then            gamhat(i,k) = log(gamma(i,k-1)/gamma(i,k))*gamma(i,k-1)*gamma(i,k)/ &                                (gamma(i,k-1)-gamma(i,k))         else            gamhat(i,k) = gamma(i,k)         end if      end do   end do!! initialize cloud top to highest plume top.!jr changed hard-wired 4 to limcnv+1 (not to exceed pver)!   do i = 1,il2g      jt(i) = max(lel(i),limcnv+1)      jt(i) = min(jt(i),pver)      jd(i) = pver      jlcl(i) = lel(i)      hmin(i) = 1.E6   end do!! find the level of minimum hsat, where detrainment starts!   do k = msg + 1,pver      do i = 1,il2g         if (hsat(i,k) <= hmin(i) .and. k >= jt(i) .and. k <= jb(i)) then            hmin(i) = hsat(i,k)            j0(i) = k         end if      end do   end do   do i = 1,il2g      j0(i) = min(j0(i),jb(i)-2)      j0(i) = max(j0(i),jt(i)+2)!! Fix from Guang Zhang to address out of bounds array reference!      j0(i) = min(j0(i),pver)   end do!! Initialize certain arrays inside cloud!   do k = msg + 1,pver      do i = 1,il2g         if (k >= jt(i) .and. k <= jb(i)) then            hu(i,k) = hmn(i,mx(i)) + cp*0.5            su(i,k) = s(i,mx(i)) + 0.5         end if      end do   end do!! *********************************************************! compute taylor series for approximate eps(z) below! *********************************************************!   do k = pver - 1,msg + 1,-1      do i = 1,il2g         if (k < jb(i) .and. k >= jt(i)) then            k1(i,k) = k1(i,k+1) + (hmn(i,mx(i))-hmn(i,k))*dz(i,k)            ihat(i,k) = 0.5* (k1(i,k+1)+k1(i,k))            i2(i,k) = i2(i,k+1) + ihat(i,k)*dz(i,k)            idag(i,k) = 0.5* (i2(i,k+1)+i2(i,k))            i3(i,k) = i3(i,k+1) + idag(i,k)*dz(i,k)            iprm(i,k) = 0.5* (i3(i,k+1)+i3(i,k))            i4(i,k) = i4(i,k+1) + iprm(i,k)*dz(i,k)         end if      end do   end do!! re-initialize hmin array for ensuing calculation.!   do i = 1,il2g      hmin(i) = 1.E6   end do   do k = msg + 1,pver      do i = 1,il2g         if (k >= j0(i) .and. k <= jb(i) .and. hmn(i,k) <= hmin(i)) then            hmin(i) = hmn(i,k)            expdif(i) = hmn(i,mx(i)) - hmin(i)         end if      end do   end do!! *********************************************************! compute approximate eps(z) using above taylor series! *********************************************************!   do k = msg + 2,pver      do i = 1,il2g         expnum(i) = 0.         ftemp(i) = 0.         if (k < jt(i) .or. k >= jb(i)) then            k1(i,k) = 0.            expnum(i) = 0.         else            expnum(i) = hmn(i,mx(i)) - (hsat(i,k-1)*(zf(i,k)-z(i,k)) + &                        hsat(i,k)* (z(i,k-1)-zf(i,k)))/(z(i,k-1)-z(i,k))         end if         if ((expdif(i) > 100. .and. expnum(i) > 0.) .and. &	     k1(i,k) > expnum(i)*dz(i,k)) then            ftemp(i) = expnum(i)/k1(i,k)            f(i,k) = ftemp(i) + i2(i,k)/k1(i,k)*ftemp(i)**2 + &                     (2.*i2(i,k)**2-k1(i,k)*i3(i,k))/k1(i,k)**2* &                     ftemp(i)**3 + (-5.*k1(i,k)*i2(i,k)*i3(i,k)+ &                     5.*i2(i,k)**3+k1(i,k)**2*i4(i,k))/ &                     k1(i,k)**3*ftemp(i)**4            f(i,k) = max(f(i,k),0._r8)            f(i,k) = min(f(i,k),0.0002_r8)         end if      end do   end do   do i = 1,il2g      if (j0(i) < jb(i)) then         if (f(i,j0(i)) < 1.E-6 .and. f(i,j0(i)+1) > f(i,j0(i))) j0(i) = j0(i) + 1      end if   end do   do k = msg + 2,pver      do i = 1,il2g         if (k >= jt(i) .and. k <= j0(i)) then            f(i,k) = max(f(i,k),f(i,k-1))         end if      end do   end do   do i = 1,il2g      eps0(i) = f(i,j0(i))      eps(i,jb(i)) = eps0(i)   end do!! This is set to match the Rasch and Kristjansson paper!   do k = pver,msg + 1,-1      do i = 1,il2g         if (k >= j0(i) .and. k <= jb(i)) then            eps(i,k) = f(i,j0(i))         end if      end do   end do   do k = pver,msg + 1,-1      do i = 1,il2g         if (k < j0(i) .and. k >= jt(i)) eps(i,k) = f(i,k)      end do   end do!! specify the updraft mass flux mu, entrainment eu, detrainment du! and moist static energy hu.! here and below mu, eu,du, md and ed are all normalized by mb!   do i = 1,il2g      if (eps0(i) > 0.) then!          mu(i,jb(i)) = 1.!          eu(i,jb(i)) = eps0(i)/2.!**pjr NOTE TO CORE GROUP mu and mu2 (and eu and eu2 should have the same vals now)         mu2(i,jb(i)) = 1.         eu2(i,jb(i)) = mu2(i,jb(i))/dz(i,jb(i))         mu(i,jb(i)) = mu2(i,jb(i))         eu(i,jb(i)) = eu2(i,jb(i))      end if   end do   do k = pver,msg + 1,-1      do i = 1,il2g         if (eps0(i) > 0. .and. (k >= jt(i) .and. k < jb(i))) then            zuef(i) = zf(i,k) - zf(i,jb(i))            rmue(i) = (1./eps0(i))* (exp(eps(i,k+1)*zuef(i))-1.)/zuef(i)            mu(i,k) = (1./eps0(i))* (exp(eps(i,k)*zuef(i))-1.)/zuef(i)            eu(i,k) = (rmue(i)-mu(i,k+1))/dz(i,k)            du(i,k) = (rmue(i)-mu(i,k))/dz(i,k)            mu2(i,k) = mu(i,k)            eu2(i,k) = eu(i,k)            du2(i,k) = du(i,k)         end if      end do   end do!   khighest = pverp   klowest = 1   do i=1,il2g      khighest = min(khighest,lel(i))      klowest = max(klowest,jb(i))   end do   do k = klowest-1,khighest,-1!cdir$ ivdep      do i = 1,il2g         if (k <= jb(i)-1 .and. k >= lel(i) .and. eps0(i) > 0.) then            if (mu(i,k) < 0.01) then               hu(i,k) = hu(i,jb(i))               mu(i,k) = 0.               mu2(i,k) = mu(i,k)               eu2(i,k) = 0.               du2(i,k) = mu2(i,k+1)/dz(i,k)               eu(i,k) = eu2(i,k)               du(i,k) = du2(i,k)            else               hu(i,k) = mu(i,k+1)/mu(i,k)*hu(i,k+1) + &                         dz(i,k)/mu(i,k)* (eu(i,k)*hmn(i,k)- du(i,k)*hsat(i,k))            end if         end if      end do   end do!! reset cloud top index beginning from two layers above the! cloud base (i.e. if cloud is only one layer thick, top is not reset!   do i=1,il2g      doit(i) = .true.   end do   do k=klowest-2,khighest-1,-1      do i=1,il2g         if (doit(i) .and. k <= jb(i)-2 .and. k >= lel(i)-1) then  	   if (hu(i,k) <= hsthat(i,k) .and. hu(i,k+1) > hsthat(i,k+1) &	       .and. mu(i,k) >= 0.02) then               if (hu(i,k)-hsthat(i,k) < -2000.) then                  jt(i) = k + 1                  doit(i) = .false.               else                  jt(i) = k                  if (eps0(i) <= 0.) doit(i) = .false.               end if            else if (hu(i,k) > hu(i,jb(i)) .or. mu(i,k) < 0.01) then               jt(i) = k + 1               doit(i) = .false.            end if         end if      end do   end do   do k = pver,msg + 1,-1!cdir$ ivdep      do i = 1,il2g         if (k >= lel(i) .and. k <= jt(i) .and. eps0(i) > 0.) then            mu(i,k) = 0.            eu(i,k) = 0.            du(i,k) = 0.            mu2(i,k) = 0.            eu2(i,k) = 0.            du2(i,k) = 0.            hu(i,k) = hu(i,jb(i))         end if         if (k == jt(i) .and. eps0(i) > 0.) then            du(i,k) = mu(i,k+1)/dz(i,k)            du2(i,k) = mu2(i,k+1)/dz(i,k)            eu2(i,k) = 0.            mu2(i,k) = 0.            eu(i,k) = 0.            mu(i,k) = 0.         end if      end do   end do!! specify downdraft properties (no downdrafts if jd.ge.jb).! scale down downward mass flux profile so that net flux! (up-down) at cloud base in not negative.!   do i = 1,il2g!! in normal downdraft strength run alfa=0.2.  In test4 alfa=0.1!      alfa(i) = 0.1      jt(i) = min(jt(i),jb(i)-1)      jd(i) = max(j0(i),jt(i)+1)      jd(i) = min(jd(i),jb(i))      hd(i,jd(i)) = hmn(i,jd(i)-1)      if (jd(i) < jb(i) .and. eps0(i) > 0.) then         epsm(i) = eps0(i)!          alfa(i)=2.*epsm(i)*( zf(i,jd(i))-zf(i,jb(i)) )/!     1         (  exp(2.*epsm(i)*( zf(i,jd(i))-!               zf(i,jb(i)) ))-1.  )         md(i,jd(i)) = -alfa(i)*epsm(i)/eps0(i)         md2(i,jd(i)) = md(i,jd(i))      end if   end do   do k = msg + 1,pver      do i = 1,il2g         if ((k > jd(i) .and. k <= jb(i)) .and. eps0(i) > 0.) then            zdef(i) = zf(i,jd(i)) - zf(i,k)            md(i,k) = -alfa(i)/ (2.*eps0(i))*(exp(2.*epsm(i)*zdef(i))-1.

⌨️ 快捷键说明

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