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 + -
显示快捷键?