diff --git a/physics/cu_gf_deep.F90 b/physics/cu_gf_deep.F90 index 0d1fc68c7..a1bca36c9 100644 --- a/physics/cu_gf_deep.F90 +++ b/physics/cu_gf_deep.F90 @@ -3,6 +3,7 @@ module cu_gf_deep use machine , only : kind_phys + use physcons, only : qamin real(kind=kind_phys), parameter::g=9.81 real(kind=kind_phys), parameter:: cp=1004. real(kind=kind_phys), parameter:: xlv=2.5e6 @@ -124,6 +125,11 @@ subroutine cu_gf_deep_run( & ,frh_out & ! fractional coverage ,ierr & ! ierr flags are error flags, used for debugging ,ierrc & ! the following should be set to zero if not available + ,nchem & + ,fscav & + ,chem3d & + ,wetdpc_deep & + ,do_smoke_transport & ,rand_mom & ! for stochastics mom, if temporal and spatial patterns exist ,rand_vmas & ! for stochastics vertmass, if temporal and spatial patterns exist ,rand_clos & ! for stochastics closures, if temporal and spatial patterns exist @@ -144,7 +150,7 @@ subroutine cu_gf_deep_run( & ,intent (in ) :: & nranflag,itf,ktf,its,ite, kts,kte,ipr,imid integer, intent (in ) :: & - ichoice + ichoice,nchem real(kind=kind_phys), dimension (its:ite,4) & ,intent (in ) :: rand_clos real(kind=kind_phys), dimension (its:ite) & @@ -163,17 +169,17 @@ subroutine cu_gf_deep_run( & ! outq = output q tendency (per s) ! outqc = output qc tendency (per s) ! pre = output precip - real(kind=kind_phys), dimension (its:ite,kts:kte) & + real(kind=kind_phys), dimension (its:ite,kts:kte) & ,intent (inout ) :: & cnvwt,outu,outv,outt,outq,outqc,cupclw - real(kind=kind_phys), dimension (its:ite) & + real(kind=kind_phys), dimension (its:ite) & ,intent (out ) :: & frh_out - real(kind=kind_phys), dimension (its:ite) & + real(kind=kind_phys), dimension (its:ite) & ,intent (inout ) :: & pre,xmb_out !$acc declare copy(cnvwt,outu,outv,outt,outq,outqc,cupclw,frh_out,pre,xmb_out) - real(kind=kind_phys), dimension (its:ite) & + real(kind=kind_phys), dimension (its:ite) & ,intent (in ) :: & hfx,qfx,xmbm_in,xmbs_in !$acc declare copyin(hfx,qfx,xmbm_in,xmbs_in) @@ -190,29 +196,36 @@ subroutine cu_gf_deep_run( & ! omega (omeg), windspeed (us,vs), and a flag (ierr) to turn off ! convection for this call only and at that particular gridpoint ! - real(kind=kind_phys), dimension (its:ite,kts:kte) & + real(kind=kind_phys), dimension (its:ite,kts:kte) & ,intent (in ) :: & dhdt,rho,t,po,us,vs,tn !$acc declare copyin(dhdt,rho,t,po,us,vs,tn) - real(kind=kind_phys), dimension (its:ite,kts:kte) & + real(kind=kind_phys), dimension (its:ite,kts:kte) & ,intent (inout ) :: & omeg !$acc declare copy(omeg) - real(kind=kind_phys), dimension (its:ite,kts:kte) & + real(kind=kind_phys), dimension (its:ite,kts:kte) & ,intent (inout) :: & q,qo,zuo,zdo,zdm !$acc declare copy(q,qo,zuo,zdo,zdm) - real(kind=kind_phys), dimension (its:ite) & + real(kind=kind_phys), dimension (its:ite) & ,intent (in ) :: & dx,z1,psur,xland !$acc declare copyin(dx,z1,psur,xland) - real(kind=kind_phys), dimension (its:ite) & + real(kind=kind_phys), dimension (its:ite) & ,intent (inout ) :: & mconv,ccn !$acc declare copy(mconv,ccn) - - - real(kind=kind_phys) & + real(kind=kind_phys), dimension (:,:,:) & + ,intent (inout) :: & + chem3d + logical, intent (in) :: do_smoke_transport + real(kind=kind_phys), dimension (:,:) & + , intent (out) :: wetdpc_deep + real(kind=kind_phys), intent (in) :: fscav(:) +!$acc declare copy(chem3d) copyout(wetdpc_deep) copyin(fscav) + + real(kind=kind_phys) & ,intent (in ) :: & dtime,ccnclean @@ -220,11 +233,11 @@ subroutine cu_gf_deep_run( & ! ! local ensemble dependent variables in this routine ! - real(kind=kind_phys), dimension (its:ite,1) :: & + real(kind=kind_phys), dimension (its:ite,1) :: & xaa0_ens - real(kind=kind_phys), dimension (its:ite,1) :: & + real(kind=kind_phys), dimension (its:ite,1) :: & edtc - real(kind=kind_phys), dimension (its:ite,kts:kte,1) :: & + real(kind=kind_phys), dimension (its:ite,kts:kte,1) :: & dellat_ens,dellaqc_ens,dellaq_ens,pwo_ens !$acc declare create(xaa0_ens,edtc,dellat_ens,dellaqc_ens,dellaq_ens,pwo_ens) ! @@ -292,8 +305,20 @@ subroutine cu_gf_deep_run( & ! xmb = total base mass flux ! hc = cloud moist static energy ! hkb = moist static energy at originating level - - real(kind=kind_phys), dimension (its:ite,kts:kte) :: & + real(kind=kind_phys), dimension (its:ite,kts:kte,nchem) :: & + chem + real(kind=kind_phys), dimension (its:ite,kts:kte,nchem) :: & + chem_cup,chem_up,chem_down,dellac,dellac2,chem_c,chem_pw,chem_pwd + real(kind=kind_phys), dimension (its:ite,nchem) :: & + chem_pwav,chem_psum + real(kind=kind_phys):: dtime_max,sum1,sum2 + real(kind=kind_phys), dimension (kts:kte) :: trac,trcflx_in,trcflx_out,trc,trco + real(kind=kind_phys), dimension (its:ite,kts:kte) :: pwdper, massflx + integer :: nv +!$acc declare create(chem,chem_cup,chem_up,chem_down,dellac,dellac2,chem_c,chem_pw,chem_pwd, & +!$acc chem_pwav,chem_psum,pwdper,massflux) + + real(kind=kind_phys), dimension (its:ite,kts:kte) :: & entr_rate_2d,mentrd_rate_2d,he,hes,qes,z, heo,heso,qeso,zo, & xhe,xhes,xqes,xz,xt,xq,qes_cup,q_cup,he_cup,hes_cup,z_cup, & p_cup,gamma_cup,t_cup, qeso_cup,qo_cup,heo_cup,heso_cup, & @@ -330,13 +355,13 @@ subroutine cu_gf_deep_run( & ! xaa0 = cloud work function with cloud effects (ensemble dependent) ! edt = epsilon - real(kind=kind_phys), dimension (its:ite) :: & - edt,edto,edtm,aa1,aa0,xaa0,hkb, & + real(kind=kind_phys), dimension (its:ite) :: & + edt,edto,edtm,aa1,aa0,xaa0,hkb, & hkbo,xhkb, & xmb,pwavo,ccnloss, & pwevo,bu,bud,cap_max, & cap_max_increment,closure_n,psum,psumh,sig,sigd - real(kind=kind_phys), dimension (its:ite) :: & + real(kind=kind_phys), dimension (its:ite) :: & axx,edtmax,edtmin,entr_rate integer, dimension (its:ite) :: & kzdown,kdet,k22,jmin,kstabi,kstabm,k22x,xland1, & @@ -372,10 +397,10 @@ subroutine cu_gf_deep_run( & character*50 :: ierrc(its:ite) character*4 :: cumulus - real(kind=kind_phys), dimension (its:ite,kts:kte) :: & + real(kind=kind_phys), dimension (its:ite,kts:kte) :: & up_massentr,up_massdetr,c1d & ,up_massentro,up_massdetro,dd_massentro,dd_massdetro - real(kind=kind_phys), dimension (its:ite,kts:kte) :: & + real(kind=kind_phys), dimension (its:ite,kts:kte) :: & up_massentru,up_massdetru,dd_massentru,dd_massdetru !$acc declare create(up_massentr,up_massdetr,c1d,up_massentro,up_massdetro,dd_massentro,dd_massdetro, & !$acc up_massentru,up_massdetru,dd_massentru,dd_massdetru) @@ -401,7 +426,8 @@ subroutine cu_gf_deep_run( & real(kind=kind_phys), dimension (its:ite,kts:kte) :: dtempdz integer, dimension (its:ite,kts:kte) :: k_inv_layers real(kind=kind_phys), dimension (its:ite) :: c0 ! HCB -!$acc declare create(pmin_lev,start_level,ktopkeep,dtempdz,k_inv_layers,c0) + real(kind=kind_phys), dimension (its:ite,kts:kte) :: c0t3d ! hli for smoke/dust wet scavenging +!$acc declare create(pmin_lev,start_level,ktopkeep,dtempdz,k_inv_layers,c0,c0t3d) ! rainevap from sas real(kind=kind_phys) zuh2(40) @@ -1058,14 +1084,14 @@ subroutine cu_gf_deep_run( & if(imid.eq.1)then call cup_up_moisture('mid',ierr,zo_cup,qco,qrco,pwo,pwavo, & p_cup,kbcon,ktop,dbyo,clw_all,xland1, & - qo,gammao_cup,zuo,qeso_cup,k22,qo_cup,c0, & + qo,gammao_cup,zuo,qeso_cup,k22,qo_cup,c0,c0t3d, & zqexec,ccn,ccnclean,rho,c1d,tn_cup,autoconv,up_massentr,up_massdetr,psum,psumh, & 1,itf,ktf, & its,ite, kts,kte) else call cup_up_moisture('deep',ierr,zo_cup,qco,qrco,pwo,pwavo, & p_cup,kbcon,ktop,dbyo,clw_all,xland1, & - qo,gammao_cup,zuo,qeso_cup,k22,qo_cup,c0, & + qo,gammao_cup,zuo,qeso_cup,k22,qo_cup,c0,c0t3d, & zqexec,ccn,ccnclean,rho,c1d,tn_cup,autoconv,up_massentr,up_massdetr,psum,psumh, & 1,itf,ktf, & its,ite, kts,kte) @@ -2013,6 +2039,186 @@ subroutine cu_gf_deep_run( & kts,kte,ierr,kbcon,xmb,psur,xland,qo_cup, & po_cup,qes_cup,pwavo,edto,pwevo,pre,outt,outq) !,outbuoy) +! +! +!>- atmospheric composition tracers +! +!> ## Determine whether to perform aerosol transport + if (do_smoke_transport .and. nchem > 0) then +! +! initialize tracers if they exist +! + chem (:,:,:) = 0. +!$acc kernels + do nv = 1,nchem + do k = 1, ktf + do i = 1, itf + chem(i,k,nv) = max(qamin, chem3d(i,k,nv)) + enddo + enddo + enddo + + wetdpc_deep = 0. + + chem_pwav(:,:) = 0. + chem_psum(:,:) = 0. + chem_pw (:,:,:) = 0. + chem_pwd (:,:,:) = 0. + pwdper (:,:) = 0. + chem_down(:,:,:) = 0. + chem_up (:,:,:) = 0. + chem_c (:,:,:) = 0. + chem_cup (:,:,:) = 0. + + do i=its,itf + if(ierr(i).eq.0)then + do k=kts,jmin(i) + if(pwavo(i).ne.0.) pwdper(i,k)=-edtc(i,1)*pwdo(i,k)/pwavo(i) + enddo + pwdper(i,:)=0. + do nv=1,nchem + do k=kts+1,ktf + chem_cup(i,k,nv)=.5*(chem(i,k-1,nv)+chem(i,k,nv)) + enddo + chem_cup(i,kts,nv)=chem(i,kts,nv) +! +! in updraft +! + do k=1,k22(i) + chem_up(i,k,nv)=chem_cup(i,k,nv) + enddo + do k=k22(i)+1,ktop(i) + chem_up(i,k,nv)=(chem_up(i,k-1,nv)*zuo(i,k-1) & + -.5*up_massdetr(i,k-1)*chem_up(i,k-1,nv)+ & + up_massentr(i,k-1)*chem(i,k-1,nv)) / & + (zuo(i,k-1)-.5*up_massdetr(i,k-1)+up_massentr(i,k-1)) + chem_c(i,k,nv)=fscav(nv)*chem_up(i,k,nv) + dz=zo_cup(i,K)-zo_cup(i,K-1) + trash2=chem_up(i,k,nv)-chem_c(i,k,nv) + trash=chem_c(i,k,nv)/(1.+c0t3d(i,k)*dz) + chem_pw=c0t3d(i,k)*dz*trash*zuo(i,k) + chem_up(i,k,nv)=trash2+trash + chem_pwav(i,nv)=chem_pwav(i,nv)+chem_pw(i,k,nv)! *g/dp + enddo + do k=ktop(i)+1,ktf + chem_up(i,k,nv)=chem_cup(i,k,nv) + enddo +! +! in downdraft +! + chem_down(i,jmin(i)+1,nv)=chem_cup(i,jmin(i)+1,nv) + chem_psum(i,nv)=0. + do ki=jmin(i),2,-1 + dp=100.*(po_cup(i,ki)-po_cup(i,ki+1)) + chem_down(i,ki,nv)=(chem_down(i,ki+1,nv)*zdo(i,ki+1) & + -.5_kind_phys*dd_massdetro(i,ki)*chem_down(i,ki+1,nv)+ & + dd_massentro(i,ki)*chem(i,ki,nv)) / & + (zdo(i,ki+1)-.5_kind_phys*dd_massdetro(i,ki)+dd_massentro(i,ki)) + chem_down(i,ki,nv)=chem_down(i,ki,nv)+pwdper(i,ki)*chem_pwav(i,nv) + chem_pwd(i,ki,nv)=max(0._kind_phys,pwdper(i,ki)*chem_pwav(i,nv)) + enddo +! total wet deposition + do k=1,ktf-1 + dp=100.*(po_cup(i,k)-po_cup(i,k+1)) + chem_psum(i,nv)=chem_psum(i,nv)+chem_pw(i,k,nv)*g !/dp + enddo + chem_psum(i,nv)=chem_psum(i,nv)*xmb(i)*dtime +! + enddo ! nchem + endif ! ierr=0 + enddo ! i + + dellac(:,:,:)=0. + + do nv=1,nchem + do i=its,itf + if(ierr(i).eq.0)then + dp=100.*(po_cup(i,1)-po_cup(i,2)) + dellac(i,1,nv)=dellac(i,1,nv)+(edto(i)*zdo(i,2)*chem_down(i,2,nv))*g/dp*xmb(i) + if(k22(i).eq.2)then + entupk=zuo(i,2) + dellac(i,1,nv)=dellac(i,1,nv)-entupk*chem_cup(i,2,nv)*g/dp*xmb(i) + endif + do k=kts+1,ktop(i)-1 + detup=0. + detdo=0. + entup=0. + entdo=0. + entdoj=0. + dp=100.*(po_cup(i,k)-po_cup(i,k+1)) + ! entrainment/detrainment for updraft + entdo=edto(i)*dd_massentro(i,k)*chem(i,k,nv) + detdo=edto(i)*dd_massdetro(i,k)*.5*(chem_down(i,k+1,nv)+chem_down(i,k,nv)) + entup=up_massentro(i,k)*chem(i,k,nv) + detup=up_massdetro(i,k)*.5*(chem_up(i,k+1,nv)+chem_up(i,k,nv)) + ! special levels + if(k == k22(i)-1) then + entup=zuo(i,k+1)*chem_cup(i,k+1,nv) + detup=0. + endif + if(k.eq.jmin(i))entdoj=edto(i)*zdo(i,k)*chem_cup(i,k,nv) +! mass budget + dellac(i,k,nv) =dellac(i,k,nv) + (detup+detdo-entdo-entup-entdoj)*g/dp*xmb(i) + enddo + dellac(i,ktop(i),nv)=zuo(i,ktop(i))*chem_up(i,ktop(i),nv)*g/dp*xmb(i) + endif ! ierr + enddo ! i + enddo ! nchem loop + +! fct for subsidence + dellac2(:,:,:)=0. + massflx(:,:)=0. + do nv=1,nchem +!$acc loop private(trcflx_in) + do i=its,itf + if(ierr(i).eq.0)then + trcflx_in(:)=0. + dtime_max=dtime + +! initialize fct routine + do k=kts,ktop(i) + dp=100._kind_phys*(po_cup(i,k)-po_cup(i,k+1)) + dtime_max=min(dtime_max,.5_kind_phys*dp) + massflx(i,k)=-xmb(i)*(zuo(i,k)-edto(i)*zdo(i,k)) + trcflx_in(k)=massflx(i,k)*chem_cup(i,k,nv) + enddo + trcflx_in(1)=0. + massflx(i,1)=0. + call fct1d3(ktop(i),kte,dtime_max,po_cup(i,:),chem(i,:,nv),massflx(i,:), & + trcflx_in,dellac2(i,:,nv),g) + do k=kts,ktop(i) + trash=chem (i,k,nv) + chem (i,k,nv)=chem (i,k,nv) + (dellac(i,k,nv)+dellac2(i,k,nv))*dtime + if(chem(i,k,nv).lt.qamin)then + dp=100.*(po_cup(i,k)-po_cup(i,k+1)) + wetdpc_deep(i,nv)=wetdpc_deep(i,nv)+(qamin-chem(i,k,nv))*dp/g/dtime + chem(i,k,nv)=qamin + endif + enddo + endif + + enddo ! i + enddo ! nchem loop + +!> - Store aerosol concentrations if present + do nv = 1, nchem + do i = 1, itf + do k = 1, ktf + if(ierr(i).eq.0) then + if (k <= ktop(i)) then + dp=100.*(po_cup(i,k)-po_cup(i,k+1)) + wetdpc_deep(i,nv)=wetdpc_deep(i,nv) + ((chem3d(i,k,nv)-chem(i,k,nv))*dp/(g*dtime)) + chem3d(i,k,nv) = chem(i,k,nv) + endif + endif + enddo + wetdpc_deep(i,nv)=max(wetdpc_deep(i,nv),qamin) + enddo + enddo +!$acc end kernels + + endif ! nchem > 0 + k=1 !$acc kernels do i=its,itf @@ -4101,7 +4307,7 @@ end subroutine cup_output_ens_3d !> Calculates moisture properties of the updraft. subroutine cup_up_moisture(name,ierr,z_cup,qc,qrc,pw,pwav, & p_cup,kbcon,ktop,dby,clw_all,xland1, & - q,gamma_cup,zu,qes_cup,k22,qe_cup,c0, & + q,gamma_cup,zu,qes_cup,k22,qe_cup,c0,c0t3d, & zqexec,ccn,ccnclean,rho,c1d,t,autoconv, & up_massentr,up_massdetr,psum,psumh, & itest,itf,ktf, & @@ -4137,11 +4343,13 @@ subroutine cup_up_moisture(name,ierr,z_cup,qc,qrc,pw,pwav, & real(kind=kind_phys), dimension (its:ite) & ,intent (in ) :: & zqexec,c0 + real(kind=kind_phys), dimension (its:ite,kts:kte), intent (out) :: c0t3d ! entr= entrainment rate integer, dimension (its:ite) & ,intent (in ) :: & kbcon,ktop,k22,xland1 !$acc declare copyin(p_cup,rho,q,zu,gamma_cup,qe_cup,up_massentr,up_massdetr,dby,qes_cup,z_cup,zqexec,c0,kbcon,ktop,k22,xland1) +!$acc declare copy(c0t3d) real(kind=kind_phys), intent (in ) :: & ! HCB ccnclean ! @@ -4218,6 +4426,9 @@ subroutine cup_up_moisture(name,ierr,z_cup,qc,qrc,pw,pwav, & c0_iceconv=0.01 c1d_b=c1d bdsp(:)=bdispm +!$acc kernels + c0t3d = 0. +!$acc end kernels ! !--- no precip for small clouds @@ -4288,6 +4499,7 @@ subroutine cup_up_moisture(name,ierr,z_cup,qc,qrc,pw,pwav, & else c0t = c0(i) * exp(c0_iceconv * (t(i,k) - 273.16)) endif + c0t3d(i,k)=c0t qc(i,k)= (qc(i,k-1)*zu(i,k-1)-.5*up_massdetr(i,k-1)* qc(i,k-1)+ & up_massentr(i,k-1)*q(i,k-1)) / & (zu(i,k-1)-.5*up_massdetr(i,k-1)+up_massentr(i,k-1)) @@ -4320,6 +4532,7 @@ subroutine cup_up_moisture(name,ierr,z_cup,qc,qrc,pw,pwav, & c0t = c0(i) * exp(c0_iceconv * (t(i,k) - 273.16)) endif if(is_mid)c0t=0.004 + c0t3d(i,k)=c0t if(autoconv .gt.1) c0t=c0(i) denom=zu(i,k-1)-.5*up_massdetr(i,k-1)+up_massentr(i,k-1) diff --git a/physics/cu_gf_driver.F90 b/physics/cu_gf_driver.F90 index d85b7ac52..92f8760b0 100644 --- a/physics/cu_gf_driver.F90 +++ b/physics/cu_gf_driver.F90 @@ -67,8 +67,8 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& fhour,fh_dfi_radar,ix_dfi_radar,num_dfi_radar,cap_suppress, & dfi_radar_max_intervals,ldiag3d,qci_conv,do_cap_suppress, & maxupmf,maxMF,do_mynnedmf,ichoice_in,ichoicem_in,ichoice_s_in, & - spp_cu_deep,spp_wts_cu_deep, & - errmsg,errflg) + spp_cu_deep,spp_wts_cu_deep,nchem,chem3d,fscav,wetdpc_deep, & + do_smoke_transport,errmsg,errflg) !------------------------------------------------------------- implicit none integer, parameter :: maxiens=1 @@ -86,7 +86,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& & spp_wts_cu_deep real(kind=kind_phys) :: spp_wts_cu_deep_tmp - logical, intent(in) :: do_cap_suppress + logical, intent(in) :: do_cap_suppress, do_smoke_transport real(kind=kind_phys), parameter :: aodc0=0.14 real(kind=kind_phys), parameter :: aodreturn=30. real(kind=kind_phys) :: dts,fpi,fp @@ -95,7 +95,7 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& integer :: ishallow_g3 ! depend on imfshalcnv !------------------------------------------------------------- integer :: its,ite, jts,jte, kts,kte - integer, intent(in ) :: im,km,ntracer + integer, intent(in ) :: im,km,ntracer, nchem integer, intent(in ) :: ichoice_in,ichoicem_in,ichoice_s_in logical, intent(in ) :: flag_init, flag_restart, do_mynnedmf logical, intent(in ) :: flag_for_scnv_generic_tend,flag_for_dcnv_generic_tend @@ -154,7 +154,11 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& integer, intent(in ) :: imfshalcnv integer, dimension(:), intent(inout) :: cactiv,cactiv_m -!$acc declare copy(cactiv,cactiv_m) + real(kind_phys), dimension(:), intent(in) :: fscav +!$acc declare copyin(fscav) + real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d + real(kind_phys), dimension(:,:), intent(inout) :: wetdpc_deep +!$acc declare copy(cactiv,cactiv_m,chem3d,wetdpc_deep) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -179,19 +183,20 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& real(kind=kind_phys), dimension (im) :: tau_ecmwf,edt,edtm,edtd,ter11,aa0,xlandi real(kind=kind_phys), dimension (im) :: pret,prets,pretm,hexec real(kind=kind_phys), dimension (im,10) :: forcing,forcing2 + real(kind=kind_phys), dimension (im,nchem) :: wetdpc_mid integer, dimension (im) :: kbcon, ktop,ierr,ierrs,ierrm,kpbli integer, dimension (im) :: k22s,kbcons,ktops,k22,jmin,jminm integer, dimension (im) :: kbconm,ktopm,k22m !$acc declare create(k22_shallow,kbcon_shallow,ktop_shallow,rand_mom,rand_vmas, & -!$acc rand_clos,gdc,gdc2,ht,ccn_gf,ccn_m,dx,frhm,frhd, & +!$acc rand_clos,gdc,gdc2,ht,ccn_gf,ccn_m,dx,frhm,frhd,wetdpc_mid, & !$acc outt,outq,outqc,phh,subm,cupclw,cupclws, & !$acc dhdt,zu,zus,zd,phf,zum,zdm,outum,outvm, & !$acc outts,outqs,outqcs,outu,outv,outus,outvs, & !$acc outtm,outqm,outqcm,submm,cupclwm, & !$acc cnvwt,cnvwts,cnvwtm,hco,hcdo,zdo,zdd,hcom,hcdom,zdom, & !$acc tau_ecmwf,edt,edtm,edtd,ter11,aa0,xlandi, & -!$acc pret,prets,pretm,hexec,forcing,forcing2, & +!$acc pret,prets,pretm,hexec,forcing,forcing2,wetdpc_mid, & !$acc kbcon, ktop,ierr,ierrs,ierrm,kpbli, & !$acc k22s,kbcons,ktops,k22,jmin,jminm,kbconm,ktopm,k22m) @@ -743,6 +748,11 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ,frhm & ,ierrm & ,ierrcm & + ,nchem & + ,fscav & + ,chem3d & + ,wetdpc_mid & + ,do_smoke_transport & ! the following should be set to zero if not available ,rand_mom & ! for stochastics mom, if temporal and spatial patterns exist ,rand_vmas & ! for stochastics vertmass, if temporal and spatial patterns exist @@ -825,6 +835,11 @@ subroutine cu_gf_driver_run(ntracer,garea,im,km,dt,flag_init,flag_restart,& ,frhd & ,ierr & ,ierrc & + ,nchem & + ,fscav & + ,chem3d & + ,wetdpc_deep & + ,do_smoke_transport & ! the following should be set to zero if not available ,rand_mom & ! for stochastics mom, if temporal and spatial patterns exist ,rand_vmas & ! for stochastics vertmass, if temporal and spatial patterns exist diff --git a/physics/cu_gf_driver.meta b/physics/cu_gf_driver.meta index 08e9de201..dce20064a 100644 --- a/physics/cu_gf_driver.meta +++ b/physics/cu_gf_driver.meta @@ -612,6 +612,44 @@ dimensions = () type = integer intent = in +[nchem] + standard_name = number_of_chemical_species_vertically_mixed + long_name = number of chemical species vertically mixed + units = count + dimensions = () + type = integer + intent = in +[chem3d] + standard_name = chem3d_mynn_pbl_transport + long_name = mynn pbl transport of smoke and dust + units = various + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) + type = real + kind = kind_phys + intent = inout +[fscav] + standard_name = smoke_dust_conv_wet_coef + long_name = smoke dust convetive wet scavanging coefficents + units = none + dimensions = (3) + type = real + kind = kind_phys + intent = in +[do_smoke_transport] + standard_name = do_smoke_conv_transport + long_name = flag for rrfs smoke convective transport + units = flag + dimensions = () + type = logical + intent = in +[wetdpc_deep] + standard_name = conv_wet_deposition_smoke_dust + long_name = convective wet removal of smoke and dust + units = kg kg-1 + dimensions = (horizontal_loop_extent,number_of_chemical_species_vertically_mixed) + type = real + kind = kind_phys + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/cu_gf_driver_post.F90 b/physics/cu_gf_driver_post.F90 index 111bf0863..6ed1321bc 100644 --- a/physics/cu_gf_driver_post.F90 +++ b/physics/cu_gf_driver_post.F90 @@ -15,7 +15,7 @@ module cu_gf_driver_post !> \section arg_table_cu_gf_driver_post_run Argument Table !! \htmlinclude cu_gf_driver_post_run.html !! - subroutine cu_gf_driver_post_run (im, km, t, q, prevst, prevsq, cactiv, cactiv_m, conv_act, conv_act_m, errmsg, errflg) + subroutine cu_gf_driver_post_run (im, km, t, q, prevst, prevsq, cactiv, cactiv_m, conv_act, conv_act_m, rrfs_sd, ntsmoke, ntdust, ntcoarsepm, chem3d, gq0, errmsg, errflg) use machine, only: kind_phys @@ -31,8 +31,11 @@ subroutine cu_gf_driver_post_run (im, km, t, q, prevst, prevsq, cactiv, cactiv_m integer, intent(in) :: cactiv_m(:) real(kind_phys), intent(out) :: conv_act(:) real(kind_phys), intent(out) :: conv_act_m(:) + logical, intent(in) :: rrfs_sd + integer, intent(in) :: ntsmoke, ntdust, ntcoarsepm + real(kind_phys), intent(inout) :: chem3d(:,:,:), gq0(:,:,:) character(len=*), intent(out) :: errmsg -!$acc declare copyin(t,q,cactiv,cactiv_m) copyout(prevst,prevsq,conv_act,conv_act_m) +!$acc declare copyin(t,q,cactiv,cactiv_m) copyout(prevst,prevsq,conv_act,conv_act_m,chem3d,gq0) integer, intent(out) :: errflg ! Local variables @@ -58,6 +61,12 @@ subroutine cu_gf_driver_post_run (im, km, t, q, prevst, prevsq, cactiv, cactiv_m conv_act_m(i)=0.0 endif enddo + + if (rrfs_sd) then + gq0(:,:,ntsmoke ) = chem3d(:,:,1) + gq0(:,:,ntdust ) = chem3d(:,:,2) + gq0(:,:,ntcoarsepm) = chem3d(:,:,3) + endif !$acc end kernels end subroutine cu_gf_driver_post_run diff --git a/physics/cu_gf_driver_post.meta b/physics/cu_gf_driver_post.meta index 6c6ceeb66..f8320d5c9 100644 --- a/physics/cu_gf_driver_post.meta +++ b/physics/cu_gf_driver_post.meta @@ -83,6 +83,34 @@ type = real kind = kind_phys intent = out +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection + units = flag + dimensions = () + type = logical + intent = in +[ntsmoke] + standard_name = index_for_smoke_in_tracer_concentration_array + long_name = tracer index for smoke + units = index + dimensions = () + type = integer + intent = in +[ntdust] + standard_name = index_for_dust_in_tracer_concentration_array + long_name = tracer index for dust + units = index + dimensions = () + type = integer + intent = in +[ntcoarsepm] + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter + units = index + dimensions = () + type = integer + intent = in [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP @@ -91,6 +119,22 @@ type = character kind = len=* intent = out +[chem3d] + standard_name = chem3d_mynn_pbl_transport + long_name = mynn pbl transport of smoke and dust + units = various + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) + type = real + kind = kind_phys + intent = inout +[gq0] + standard_name = tracer_concentration_of_new_state + long_name = tracer concentration updated by physics + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) + type = real + kind = kind_phys + intent = inout [errflg] standard_name = ccpp_error_code long_name = error code for error handling in CCPP diff --git a/physics/cu_gf_driver_pre.F90 b/physics/cu_gf_driver_pre.F90 index 98cc76b95..7ff66be21 100644 --- a/physics/cu_gf_driver_pre.F90 +++ b/physics/cu_gf_driver_pre.F90 @@ -17,6 +17,7 @@ module cu_gf_driver_pre !! subroutine cu_gf_driver_pre_run (flag_init, flag_restart, kdt, fhour, dtp, t, q, prevst, prevsq, & forcet, forceq, cactiv, cactiv_m, conv_act, conv_act_m, & + rrfs_sd, ntsmoke, ntdust, ntcoarsepm, chem3d, gq0, & errmsg, errflg) use machine, only: kind_phys @@ -25,6 +26,7 @@ subroutine cu_gf_driver_pre_run (flag_init, flag_restart, kdt, fhour, dtp, t, q, logical, intent(in) :: flag_init logical, intent(in) :: flag_restart + logical, intent(in) :: rrfs_sd integer, intent(in) :: kdt real(kind_phys), intent(in) :: fhour real(kind_phys), intent(in) :: dtp @@ -37,10 +39,12 @@ subroutine cu_gf_driver_pre_run (flag_init, flag_restart, kdt, fhour, dtp, t, q, real(kind_phys), intent(out) :: forceq(:,:) integer, intent(out) :: cactiv(:) integer, intent(out) :: cactiv_m(:) + integer, intent(in) :: ntsmoke, ntdust, ntcoarsepm !$acc declare copyout(forcet,forceq,cactiv,cactiv_m) real(kind_phys), intent(in) :: conv_act(:) real(kind_phys), intent(in) :: conv_act_m(:) -!$acc declare copyin(conv_act,conv_act_m) + real(kind_phys), intent(inout) :: chem3d(:,:,:), gq0(:,:,:) +!$acc declare copyin(conv_act,conv_act_m) copy(chem3d,gq0) character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -77,6 +81,12 @@ subroutine cu_gf_driver_pre_run (flag_init, flag_restart, kdt, fhour, dtp, t, q, !$acc kernels cactiv(:)=nint(conv_act(:)) cactiv_m(:)=nint(conv_act_m(:)) + + if (rrfs_sd) then + chem3d(:,:,1) = gq0(:,:,ntsmoke) + chem3d(:,:,2) = gq0(:,:,ntdust) + chem3d(:,:,3) = gq0(:,:,ntcoarsepm) + endif !$acc end kernels end subroutine cu_gf_driver_pre_run diff --git a/physics/cu_gf_driver_pre.meta b/physics/cu_gf_driver_pre.meta index 7fd66d19b..49cc98148 100644 --- a/physics/cu_gf_driver_pre.meta +++ b/physics/cu_gf_driver_pre.meta @@ -122,6 +122,50 @@ type = real kind = kind_phys intent = in +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection + units = flag + dimensions = () + type = logical + intent = in +[ntsmoke] + standard_name = index_for_smoke_in_tracer_concentration_array + long_name = tracer index for smoke + units = index + dimensions = () + type = integer + intent = in +[ntdust] + standard_name = index_for_dust_in_tracer_concentration_array + long_name = tracer index for dust + units = index + dimensions = () + type = integer + intent = in +[ntcoarsepm] + standard_name = index_for_coarse_particulate_matter_in_tracer_concentration_array + long_name = tracer index for coarse particulate matter + units = index + dimensions = () + type = integer + intent = in +[chem3d] + standard_name = chem3d_mynn_pbl_transport + long_name = mynn pbl transport of smoke and dust + units = various + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_chemical_species_vertically_mixed) + type = real + kind = kind_phys + intent = inout +[gq0] + standard_name = tracer_concentration_of_new_state + long_name = tracer concentration updated by physics + units = kg kg-1 + dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_tracers) + type = real + kind = kind_phys + intent = inout [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/smoke_dust/coarsepm_settling_mod.F90 b/physics/smoke_dust/coarsepm_settling_mod.F90 index 9061840c3..b044edb67 100755 --- a/physics/smoke_dust/coarsepm_settling_mod.F90 +++ b/physics/smoke_dust/coarsepm_settling_mod.F90 @@ -8,7 +8,7 @@ module coarsepm_settling_mod CONTAINS -SUBROUTINE coarsepm_settling_driver(dt,t_phy,rel_hum, & +SUBROUTINE coarsepm_settling_driver(dt,t_phy, & chem,rho_phy,dz8w,p8w,p_phy,sedim, & area,g,num_chem, & ids,ide, jds,jde, kds,kde, & @@ -24,7 +24,7 @@ SUBROUTINE coarsepm_settling_driver(dt,t_phy,rel_hum, & its,ite, jts,jte, kts,kte REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ),INTENT(INOUT ) :: chem REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & - INTENT(IN ) :: t_phy,p_phy,dz8w,p8w,rho_phy,rel_hum + INTENT(IN ) :: t_phy,p_phy,dz8w,p8w,rho_phy REAL(kind_phys), DIMENSION( ims:ime , jms:jme ),INTENT(IN ) :: area REAL(kind_phys), INTENT(IN ) :: dt,g @@ -64,7 +64,6 @@ SUBROUTINE coarsepm_settling_driver(dt,t_phy,rel_hum, & airmas(1,1,kk)=-(p8w(i,k+1,j)-p8w(i,k,j))*area(i,j)/g airden(1,1,kk)=rho_phy(i,k,j) tmp(1,1,kk)=t_phy(i,k,j) - rh(1,1,kk) = rel_hum(i,k,j) ! hli do nv = 1, num_chem chem_before(i,j,k,nv) = chem(i,k,j,nv) enddo @@ -82,7 +81,7 @@ SUBROUTINE coarsepm_settling_driver(dt,t_phy,rel_hum, & call settling(1, 1, lmx, 1,g,dyn_visc, & dust, tmp, p_mid, delz, airmas, & - den_dust, reff_dust, dt, bstl_dust, rh, idust, airden) + den_dust, reff_dust, dt, bstl_dust, idust, airden) kk = 0 do k = kts,kte @@ -111,7 +110,7 @@ END SUBROUTINE coarsepm_settling_driver subroutine settling(imx,jmx, lmx, nmx,g0,dyn_visc, & tc, tmp, p_mid, delz, airmas, & - den, reff, dt, bstl, rh, idust, airden) + den, reff, dt, bstl, idust, airden) ! **************************************************************************** ! * * ! * Calculate the loss by settling, using an implicit method * @@ -131,7 +130,7 @@ subroutine settling(imx,jmx, lmx, nmx,g0,dyn_visc, & INTEGER :: ntdt REAL(kind_phys), INTENT(IN) :: dt,g0,dyn_visc REAL(kind_phys), INTENT(IN) :: tmp(imx,jmx,lmx), delz(imx,jmx,lmx), & - airmas(imx,jmx,lmx), rh(imx,jmx,lmx), & + airmas(imx,jmx,lmx), & den(nmx), reff(nmx),p_mid(imx,jmx,lmx),& airden(imx,jmx,lmx) REAL(kind_phys), INTENT(INOUT) :: tc(imx,jmx,lmx,nmx) diff --git a/physics/smoke_dust/dep_data_mod.F90 b/physics/smoke_dust/dep_data_mod.F90 new file mode 100755 index 000000000..bf9ae7f0c --- /dev/null +++ b/physics/smoke_dust/dep_data_mod.F90 @@ -0,0 +1,193 @@ +!>\file dep_data_mod.F90 +!! This file contains data for the dry deposition modules. +module dep_data_mod + + use machine , only : kind_phys + + integer, parameter :: nvegtype = 25 + real(kind_phys), dimension(nvegtype), parameter :: & + kpart = (/500., 500., 500., 500., 500., & + 500., 500., 500., 500., 500., & + 500., 500., 500., 500., 500., & + 500., 500., 500., 500., 500., & + 500., 500., 500., 500., 500. /) + real(kind_phys), parameter :: max_dep_vel = 0.005 ! m/s (may need to set per species) + real(kind_phys), parameter :: dep_ref_hgt = 2.0 ! Meters + real(kind_phys), parameter :: pi = 3.1415926536 +! 3*PI + REAL(kind_phys), PARAMETER :: threepi=3.0*pi + real(kind_phys), parameter :: gravity = 9.81 +! mean gravitational acceleration [ m/sec**2 ] + REAL(kind_phys), PARAMETER :: grav=9.80622 + real(kind_phys), parameter :: boltzmann = 1.3807e-16 +! universal gas constant [ J/mol-K ] + REAL(kind_phys), PARAMETER :: rgasuniv=8.314510 +! Avogadro's Constant [ 1/mol ] + REAL, PARAMETER :: avo=6.0221367E23 + ! Boltzmann's Constant [ J / K ]i\ + REAL(kind_phys), PARAMETER :: boltz=rgasuniv/avo + real(kind_phys), parameter :: Cb = 2., Cim = 0.4, alpha = 0.8, Cin = 2.5, vv = 0.8 + real(kind_phys), parameter :: A_for = 0.1 ! forest + real(kind_phys), parameter :: A_grs = 0.2 ! grass + real(kind_phys), parameter :: A_wat = 100. ! water + real(kind_phys), parameter :: eps0_for = 0.8*0.01 ! forest + real(kind_phys), parameter :: eps0_grs = 0.4*0.01 ! grass + real(kind_phys), parameter :: eps0_wat = 0.6*0.01 ! water + + REAL(kind_phys), PARAMETER :: one3=1.0/3.0 + REAL(kind_phys), PARAMETER :: two3=2.0/3.0 +! SQRT( 2 ) + REAL(kind_phys), PARAMETER :: sqrt2=1.4142135623731 +! SQRT( PI ) + REAL(kind_phys), PARAMETER :: sqrtpi=1.7724539 + REAL(kind_phys) :: karman = 0.4 ! von Karman constant + REAL(kind_phys), PARAMETER :: conmin= 1.E-16 + REAL(kind_phys), PARAMETER :: pirs=3.14159265358979324 + REAL(kind_phys), PARAMETER :: f6dpi=6.0/pirs + REAL(kind_phys), PARAMETER :: f6dpim9=1.0E-9*f6dpi + REAL(kind_phys), PARAMETER :: rhosmoke = 1.4E3 + REAL(kind_phys), PARAMETER :: rhodust = 2.6E3 + REAL(kind_phys), PARAMETER :: smokefac=f6dpim9/rhosmoke + REAL(kind_phys), PARAMETER :: dustfac=f6dpim9/rhodust +! starting standard surface temperature [ K ] + REAL(kind_phys), PARAMETER :: tss0=288.15 + REAL(kind_phys), PARAMETER :: sigma1 = 1.8 + REAL(kind_phys), PARAMETER :: mean_diameter1 = 4.e-8 + REAL(kind_phys), PARAMETER :: fact_wfa = 1.e-9*6.0/pirs*exp(4.5*log(sigma1)**2)/mean_diameter1**3 + REAL(kind_phys), PARAMETER :: sginia=2.00 +! initial sigma-G for nucleimode + REAL(kind_phys), PARAMETER :: sginin=1.70 +! initial sigma-G for coarse mode + REAL(kind_phys), PARAMETER :: sginic=2.5 +! starting standard surface pressure [ Pa ] + REAL(kind_phys), PARAMETER :: pss0=101325.0 +! lowest particle diameter ( m ) + REAL(kind_phys), PARAMETER :: dgmin=1.0E-09 +! lowest particle density ( Kg/m**3 ) + REAL(kind_phys), PARAMETER :: densmin=1.0E03 +! index for Aitken mode number + INTEGER, PARAMETER :: vdnnuc=1 +! index for accumulation mode number + INTEGER, PARAMETER :: vdnacc=2 +! index for coarse mode number + INTEGER, PARAMETER :: vdncor=3 +! index for Aitken mode mass + INTEGER, PARAMETER :: vdmnuc=4 +! index for accumulation mode + INTEGER, PARAMETER :: vdmacc=5 +! index for fine mode mass (Aitken + accumulation) + INTEGER, PARAMETER :: vdmfine=6 +! index for coarse mode mass + INTEGER, PARAMETER :: vdmcor=7 +! index for Aitken mode number + INTEGER, PARAMETER :: vsnnuc=1 +! index for Accumulation mode number + INTEGER, PARAMETER :: vsnacc=2 +! index for coarse mode number + INTEGER, PARAMETER :: vsncor=3 +! index for Aitken mode mass + INTEGER, PARAMETER :: vsmnuc=4 +! index for accumulation mode mass + INTEGER, PARAMETER :: vsmacc=5 +! index for coarse mass + INTEGER, PARAMETER :: vsmcor=6 +! coarse mode exp( log^2( sigmag )/8 ) +! nuclei **4 + REAL(kind_phys) :: esn04 +! accumulation + REAL(kind_phys) :: esa04 + REAL(kind_phys) :: esc04 +! coarse +! nuclei **5 + REAL(kind_phys) :: esn05 + REAL(kind_phys) :: esa05 +! accumulation +! nuclei **8 + REAL(kind_phys) :: esn08 +! accumulation + REAL(kind_phys) :: esa08 + REAL(kind_phys) :: esc08 +! coarse +! nuclei **9 + REAL(kind_phys) :: esn09 + REAL(kind_phys) :: esa09 +! accumulation +! nuclei **12 + REAL(kind_phys) :: esn12 +! accumulation + REAL(kind_phys) :: esa12 + REAL(kind_phys) :: esc12 +! coarse mode +! nuclei **16 + REAL(kind_phys) :: esn16 +! accumulation + REAL(kind_phys) :: esa16 + REAL(kind_phys) :: esc16 +! coarse +! nuclei **20 + REAL(kind_phys) :: esn20 +! accumulation + REAL(kind_phys) :: esa20 + REAL(kind_phys) :: esc20 +! coarse +! nuclei **25 + REAL(kind_phys) :: esn25 + REAL(kind_phys) :: esa25 +! accumulation +! nuclei **24 + REAL(kind_phys) :: esn24 +! accumulation + REAL(kind_phys) :: esa24 + REAL(kind_phys) :: esc24 +! coarse +! nuclei **28 + REAL(kind_phys) :: esn28 +! accumulation + REAL(kind_phys) :: esa28 + REAL(kind_phys) :: esc28 +! coarse +! nuclei **32 + REAL(kind_phys) :: esn32 +! accumulation + REAL(kind_phys) :: esa32 + REAL(kind_phys) :: esc32 +! coarese +! nuclei **36 + REAL(kind_phys) :: esn36 +! accumulation + REAL(kind_phys) :: esa36 + REAL(kind_phys) :: esc36 +! coarse +! nuclei **49 + REAL(kind_phys) :: esn49 + REAL(kind_phys) :: esa49 +! accumulation +! nuclei **52 + REAL(kind_phys) :: esn52 + REAL(kind_phys) :: esa52 +! accumulation +! nuclei **64 + REAL(kind_phys) :: esn64 +! accumulation + REAL(kind_phys) :: esa64 + REAL(kind_phys) :: esc64 +! coarse + REAL(kind_phys) :: esn100 +! nuclei **100 +! nuclei **(-20) + REAL(kind_phys) :: esnm20 +! accumulation + REAL(kind_phys) :: esam20 + REAL(kind_phys) :: escm20 +! coarse +! nuclei **(-32) + REAL(kind_phys) :: esnm32 +! accumulation + REAL(kind_phys) :: esam32 + REAL(kind_phys) :: escm32 +!SAM 10/08 Gaussian quadrature constants for SOA_VBS deposition numerical +!integration + INTEGER, PARAMETER :: NGAUSdv= 7 ! Number of Gaussian Quadrature Points + REAL(kind_phys) :: xxlsgn, xxlsga, xxlsgc + REAL(kind_phys) :: Y_GQ(NGAUSdv), WGAUS(NGAUSdv) +end module dep_data_mod diff --git a/physics/smoke_dust/dep_dry_mod_emerson.F90 b/physics/smoke_dust/dep_dry_mod_emerson.F90 new file mode 100755 index 000000000..76fdc2411 --- /dev/null +++ b/physics/smoke_dust/dep_dry_mod_emerson.F90 @@ -0,0 +1,361 @@ +!>\file dep_dry_mod.F90 +!! This file is for the dry depostion driver. +!-------------REVISION HISTORY---------------! +! XX/XX/XXXX : original implementation (Ravan Ahmadov) +! 08/17/2023 : modified to follow Emerson et al., (2020) (Jordan Schnell) +! 08/17/2023 : gravitational settling folowing the coarse pm settling driver (Jordan Schnell) + +module dep_dry_emerson_mod + + use machine , only : kind_phys + use dep_data_mod ! JLS + use rrfs_smoke_config, only : num_chem, p_smoke, p_dust_1, p_coarse_pm + + implicit none + + private + + public :: dry_dep_driver_emerson + +contains + subroutine dry_dep_driver_emerson(rmol,ustar,znt,ndvel,ddvel,vgrav, & + chem,delz,snowh,t_phy,p_phy,rho_phy,ivgtyp,g0,dt, & + settling_flag,drydep_flux,settling_flux,dbg_opt, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) +! +! compute dry deposition velocity for aerosol particles +! Based on Emerson et al. (2020), PNAS, +! www.pnas.org/cgi/doi/10.1073/pnas.2014761117 +! Code adapted from Hee-Ryu and Min, (2022): +! https://agupubs.onlinelibrary.wiley.com/doi/epdf/10.1029/2021MS002792 +!---------------------------------------------------------------------- + IMPLICIT NONE + + INTEGER, INTENT(IN ) :: settling_flag,ndvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & + INTENT(IN) :: ustar, rmol, znt, snowh + REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & + INTENT(IN ) :: t_phy, rho_phy, p_phy, delz + INTEGER, DIMENSION(ims:ime,jms:jme), INTENT(IN) :: ivgtyp + REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), & + INTENT(INOUT ) :: chem + REAL(kind_phys), INTENT(IN) :: g0,dt + LOGICAL, INTENT(IN) :: dbg_opt + ! + ! Output arrays + REAL(kind_phys), DIMENSION( ims:ime, jms:jme, ndvel ), INTENT(INOUT) :: ddvel + REAL(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, ndvel), & + INTENT(OUT) :: vgrav + REAL(kind_phys), DIMENSION( ims:ime, jms:jme, ndvel ), INTENT(OUT) :: settling_flux, drydep_flux + ! Local + REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) :: aer_res + REAL(kind_phys), DIMENSION( ndvel ) :: cblk + ! Modpar variables, mass, density, diameter, knudsen number, mean free path + REAL(kind_phys) :: pmasssn,pmassa,pmassc,pdensn,pdensa,pdensc, & + dgnuc,dgacc,dgcor,knnuc,knacc,kncor,xlm + real(kind_phys) :: Cc ! Cunningham/slip correction factor [-] + real(kind_phys) :: DDp, Eb ! Brownian diffusion [] + real(kind_phys) :: Eim ! Impaction [] + real(kind_phys) :: Ein ! Interception [] + real(kind_phys) :: Sc ! Schmit number [] + real(kind_phys) :: St ! Stokes number [] + real(kind_phys) :: vg ! gravitational settling [cm/s] + real(kind_phys) :: A, eps0, dumalnsg ! land surface params [-] + real(kind_phys) :: amu, amu_corrected ! dynamic viscosity [g/s] + real(kind_phys) :: airkinvisc ! Air kinetic viscosity [cm2/s] + real(kind_phys) :: freepath ! Air molecular freepath [cm] + real(kind_phys) :: dp ! aerosol diameter [cm] + real(kind_phys) :: aerodens ! aerosol density [g/cm3] + real(kind_phys) :: Rs ! Surface resistance + real(kind_phys) :: vgpart + real(kind_phys) :: growth_fac,vsettl,dtmax,conver,converi,dzmin + real(kind_phys) :: rmol_local + real(kind_phys), dimension( kts:kte) :: rho_col, delz_col + real(kind_phys), dimension(ndvel) :: dt_settl, chem_before, chem_after + real(kind_phys), dimension( kts:kte, ndvel ) :: cblk_col, vg_col + integer, dimension(ndvel) :: ndt_settl + integer :: i, j, k, ntdt, nv + ! chem pointers (p_*) are not sequentially numbered, need to define so nv loops work + integer, dimension(ndvel) :: chem_pointers +!> -- Gas constant + real(kind_phys), parameter :: RSI = 8.314510 + chem_pointers(1) = p_smoke + chem_pointers(2) = p_dust_1 + chem_pointers(3) = p_coarse_pm + + growth_fac = 1.0 + conver=1.e-9 + converi=1.e9 + + do j = jts, jte + do i = its, ite + aer_res(i,j) = 0.0 + rmol_local = rmol(i,j) + do k = kts, kte + delz_col(k) = delz(i,k,j) + rho_col(k) = rho_phy(i,k,j) + do nv = 1, ndvel + cblk(nv) = chem(i,k,j,chem_pointers(nv)) + if ( k == kts ) then + ddvel(i,j,nv) = 0.0 + dt_settl(nv) = 0.0 + endif ! k==kts + end do ! nv + ! *** U.S. Standard Atmosphere 1962 page 14 expression + ! for dynamic viscosity = beta * T * sqrt(T) / ( T + S) + ! where beta = 1.458e-6 [ kg sec^-1 K**-0.5 ], s = 110.4 [ K ]. + amu = 1.458E-6 * t_phy(i,k,j) * sqrt(t_phy(i,k,j)) / ( t_phy(i,k,j) + 110.4 ) + ! Aerodynamic resistance + call depvel( rmol_local, dep_ref_hgt, znt(i,j), ustar(i,j), vgpart, aer_res(i,j) ) + ! depvel uses meters, need to convert to s/cm + aer_res(i,j) = max(aer_res(i,j)/100._kind_phys,0._kind_phys) + ! Air kinematic viscosity (cm^2/s) + airkinvisc = ( 1.8325e-4 * ( 416.16 / ( t_phy(i,k,j) + 120.0 ) ) * & + ( ( t_phy(i,k,j) / 296.16 )**1.5 ) ) / ( rho_phy(i,k,j) / 28.966e3 ) ! Convert density to mol/cm^3 + ! Air molecular freepath (cm) ! Check against XLM from above + freepath = 7.39758e-4 * airkinvisc / sqrt( t_phy(i,k,j) ) + do nv = 1, ndvel + if ( chem_pointers(nv) == p_smoke ) then + dp = 4.E-8 !dgacc + aerodens = 1.4e+3 !pdensa + elseif ( chem_pointers(nv) == p_dust_1) then + dp = 1.E-6 !dgacc + aerodens = 2.6e+3 !pdensa + elseif ( chem_pointers(nv) == p_coarse_pm ) then + dp = 4.5E-6 !dgcor + aerodens = 2.6e+3 !pdensc + else + continue + endif + ! Convert diameter to cm and aerodens to g/cm3 + aerodens = aerodens / 1000. + dp = dp * 1e+2 + ! Cunningham correction factor + Cc = 1. + 2. * freepath / dp * ( 1.257 + 0.4*exp( -0.55 * dp / freepath ) ) + ! Corrected dynamic viscosity (used for settling) + amu_corrected = amu / Cc + ! Gravitational Settling + vg = aerodens * dp * dp * gravity * 100. * Cc / & ! Convert gravity to cm/s^2 + ( 18. * airkinvisc * ( rho_phy(i,k,j) / 28.966e3 ) ) ! Convert density to mol/cm^3 + ! -- Rest of loop for the surface when deposition velocity needs to be cacluated + if ( k == kts ) then + ! Brownian Diffusion + DDp = ( boltzmann * t_phy(i,k,j) ) * Cc / (3. * pi * airkinvisc * ( rho_phy(i,k,j) / 28.966e3 ) * dp) ! Convert density to mol/cm^3 + ! Schmit number + Sc = airkinvisc / DDp + ! Brownian Diffusion + Eb = Cb * Sc**(-0.666666667) + ! Stokes number + St = ( 100. * ustar(i,j) ) * ( 100.* ustar(i,j) ) * vg / airkinvisc / ( gravity * 100.) ! Convert ustar to cm/s, gravity to cm/s^2 + ! Impaction + Eim = Cim * ( St / ( alpha + St ) )**1.7 + ! MODIS type lu, large roughness lengths (e.g., urban or forest) + ! ----------------------------------------------------------------------- + ! *** TO DO -- set A and eps0 for all land surface types *** !!! + ! ----------------------------------------------------------------------- + if ( ivgtyp(i,j) .eq. 13 .or. ivgtyp(i,j) .le. 5 ) then ! Forest + A = A_for + eps0 = eps0_for + else if ( ivgtyp(i,j) .eq. 17 ) then ! water + A = A_wat + eps0 = eps0_wat + else ! otherwise + A = A_grs + eps0 = eps0_grs + end if + ! Set if snow greater than 1 cm +! if ( snowh(i,j) .gt. 0.01 ) then ! snow +! A = A_wat +! eps0 = eps0_wat +! endif + ! Interception + Ein = Cin * ( dp / A )**vv + ! Surface resistance + Rs = 1. / ( ( ustar(i,j) * 100.) * ( Eb + Eim + Ein) * eps0 ) ! Convert ustar to cm/s + ! Compute final ddvel = aer_res + RS, set max at max_dep_vel in dep_data_mod.F[ m/s] + ! The /100. term converts from cm/s to m/s, required for MYNN. + ddvel(i,j,nv) = min( (1. / (aer_res(i,j) + Rs ))/100., max_dep_vel) + if ( dbg_opt ) then + WRITE(6,*) 'dry_dep_mod_emerson: i,j,nv',i,j,nv + WRITE(6,*) 'dry_dep_mod_emerson: deposition velocity (m/s) ',ddvel(i,j,nv) + endif + drydep_flux(i,j,nv) = chem(i,kts,j,chem_pointers(nv))*p_phy(i,kts,j) / & + (RSI*t_phy(i,kts,j))*ddvel(i,j,nv)*dt*1.E-6 + endif ! k == kts + vgrav(i,k,j,nv) = vg + ! Fill column variables + cblk_col(k,nv) = cblk(nv) + vg_col(k,nv) = vg + enddo ! nv + enddo ! k + ! -- Get necessary info for settling + ! -- Determine the maximum time-step satisying the CFL condition: + dzmin = minval(delz_col) + ntdt=INT(dt) + do nv = 1, ndvel + ! -- NOTE, diameters and densities are NOT converted to cm and g/cm3 like above + ! -- dt_settl calculations (from original coarsepm_settling) + if ( chem_pointers(nv) == p_smoke ) then + dp = 4.E-8 !dgacc + aerodens = 1.4e+3 !pdensa + elseif ( chem_pointers(nv) == p_dust_1) then + dp = 1.E-6 !dgacc + aerodens = 2.6e+3 !pdensa + elseif ( chem_pointers(nv) == p_coarse_pm ) then + dp = 4.5E-6 !dgcor + aerodens = 2.6e+3 !pdensc + else + continue + endif + ! 1.5E-5 = dyn_visc --> dust_data_mod.F90 + vsettl = 2.0 / 9.0 * g0 * aerodens * ( growth_fac * ( 0.5 * dp ))**2.0 / ( 0.5 * 1.5E-5 ) + dtmax = dzmin / vsettl + ndt_settl(nv) = MAX( 1, INT( ntdt /dtmax) ) + ! Limit maximum number of iterations + IF (ndt_settl(nv) > 12) ndt_settl(nv) = 12 + dt_settl(nv) = REAL(ntdt,kind=kind_phys) /REAL(ndt_settl(nv),kind=kind_phys) + enddo + do nv = 1, ndvel + chem_before(nv) = 0._kind_phys + do k = kts, kte + chem_before(nv) = chem_before(nv) + (cblk_col(k,nv) * rho_phy(i,k,j) * delz(i,k,j) ) ! ug/m2 + enddo + enddo + ! Perform gravitational settling if desired + if ( settling_flag == 1 ) then + call particle_settling(cblk_col,rho_col,delz_col,vg_col,dt_settl,ndt_settl,ndvel,kts,kte) + endif + ! Put cblk back into chem array + do nv= 1, ndvel + chem_after(nv) = 0._kind_phys + settling_flux(i,j,nv) = 0._kind_phys + do k = kts, kte + chem(i,k,j,chem_pointers(nv)) = cblk_col(k,nv) + chem_after(nv) = chem_after(nv) + (cblk_col(k,nv) * rho_phy(i,k,j) * delz(i,k,j) ) ! ug/m2 + enddo ! k + settling_flux(i,j,nv) = settling_flux(i,j,nv) + (chem_before(nv) - chem_after(nv)) ! ug/m2 + enddo ! nv + end do ! j + end do ! i +end subroutine dry_dep_driver_emerson +! +!-------------------------------------------------------------------------------- +! +subroutine depvel( rmol, zr, z0, ustar, vgpart, aer_res ) +!-------------------------------------------------- +! THIS FUNCTION HAS BEEN DESIGNED TO EVALUATE AN UPPER LIMIT +! FOR THE POLLUTANT DEPOSITION VELOCITY AS A FUNCTION OF THE +! SURFACE ROUGHNESS AND METEOROLOGICAL CONDITIONS. +! PROGRAM WRITTEN BY GREGORY J.MCRAE (NOVEMBER 1977) +! Modified by Darrell A. Winner (Feb. 1991) +! by Winfried Seidl (Aug. 1997) +!.....PROGRAM VARIABLES... +! RMOL - RECIPROCAL OF THE MONIN-OBUKHOV LENGTH +! ZR - REFERENCE HEIGHT +! Z0 - SURFACE ROUGHNESS HEIGHT +! USTAR - FRICTION VELOCITY U* +! AER_RES - AERODYNAMIC RESISTANCE +!.....REFERENCES... +! MCRAE, G.J. ET AL. (1983) MATHEMATICAL MODELING OF PHOTOCHEMICAL +! AIR POLLUTION, ENVIRONMENTAL QUALITY LABORATORY REPORT 18, +! CALIFORNIA INSTITUTE OF TECHNOLOGY, PASADENA, CALIFORNIA. +!.....RESTRICTIONS... +! 1. THE MODEL EDDY DIFFUSIVITIES ARE BASED ON MONIN-OBUKHOV +! SIMILARITY THEORY AND SO ARE ONLY APPLICABLE IN THE +! SURFACE LAYER, A HEIGHT OF O(30M). +! 2. ALL INPUT UNITS MUST BE CONSISTENT +! 3. THE PHI FUNCTIONS USED TO CALCULATE THE FRICTION +! VELOCITY U* AND THE POLLUTANT INTEGRALS ARE BASED +! ON THE WORK OF BUSINGER ET AL.(1971). +! 4. THE MOMENTUM AND POLLUTANT DIFFUSIVITIES ARE NOT +! THE SAME FOR THE CASES L<0 AND L>0. +!-------------------------------------------------- +! .. Scalar Arguments .. +!-------------------------------------------------- + REAL(kind_phys), intent(in) :: ustar, z0, zr + REAL(kind_phys), intent(out) :: vgpart, aer_res + REAL(kind_phys), intent(inout) :: rmol +!-------------------------------------------------- +! .. Local Scalars .. +!-------------------------------------------------- + INTEGER :: l + REAL(kind_phys) :: ao, ar, polint, vk +!-------------------------------------------------- +! .. Intrinsic Functions .. +!-------------------------------------------------- + INTRINSIC alog +!-------------------------------------------------- +! Set the von Karman constant +!-------------------------------------------------- + vk = karman +!-------------------------------------------------- +! DETERMINE THE STABILITY BASED ON THE CONDITIONS +! 1/L < 0 UNSTABLE +! 1/L = 0 NEUTRAL +! 1/L > 0 STABLE +!-------------------------------------------------- + if(abs(rmol) < 1.E-6 ) rmol = 0. + IF (rmol<0) THEN + ar = ((1.0-9.0*zr*rmol)**(0.25)+0.001)**2 + ao = ((1.0-9.0*z0*rmol)**(0.25)+0.001)**2 + polint = 0.74*(alog((ar-1.0)/(ar+1.0))-alog((ao-1.0)/(ao+1.0))) + ELSE IF (rmol==0.) THEN + polint = 0.74*alog(zr/z0) + ELSE + polint = 0.74_kind_phys*alog(zr/z0) + 4.7_kind_phys*rmol*(zr-z0) + END IF + vgpart = ustar*vk/polint + aer_res = polint/(karman*max(ustar,1.0e-4)) +end subroutine depvel +! +!-------------------------------------------------------------------------------- +! +! +!-------------------------------------------------------------------------------- +! +subroutine particle_settling(cblk,rho_phy,delz,vg,dt_settl,ndt_settl,ndvel,kts,kte) + IMPLICIT NONE + + INTEGER, INTENT(IN ) :: kts, kte, ndvel + REAL(kind_phys), DIMENSION(kts:kte), INTENT (IN) :: rho_phy, delz + REAL(kind_phys), DIMENSION(kts:kte,ndvel), INTENT(IN) :: vg + REAL(kind_phys), DIMENSION(kts:kte,ndvel), INTENT(INOUT) :: cblk + REAL(kind_phys), DIMENSION(ndvel), INTENT(IN) :: dt_settl + INTEGER, DIMENSION(ndvel), INTENT(IN) :: ndt_settl +! +!--- Local------ + INTEGER :: k,nv,n,l2 + REAL(kind_phys) :: temp_tc, transfer_to_below_level, vd_wrk1 + REAL(kind_phys), DIMENSION(kts:kte) :: delz_flip + + do k = kts,kte + delz_flip(k) = delz(kte-k+kts) + enddo + + do nv = 1, ndvel + do n = 1,ndt_settl(nv) + transfer_to_below_level = 0.0 + do k = kte,kts,-1 + l2 = kte - k + 1 + + temp_tc = cblk(k,nv) + + vd_wrk1 = dt_settl(nv) * vg(k,nv)/100. / delz_flip(l2) ! convert vg to m/s + + cblk(k,nv)= cblk(k,nv) * (1. - vd_wrk1) + transfer_to_below_level + if (k.gt.kts) then + transfer_to_below_level =(temp_tc*vd_wrk1)*((delz_flip(l2) & + *rho_phy(k))/(delz_flip(l2+1)*rho_phy(k-1))) ! [ug/kg] + endif + enddo ! k + enddo ! n + enddo ! nv +end subroutine particle_settling + +! +end module dep_dry_emerson_mod diff --git a/physics/smoke_dust/dep_dry_mod.F90 b/physics/smoke_dust/dep_dry_simple_mod.F90 similarity index 77% rename from physics/smoke_dust/dep_dry_mod.F90 rename to physics/smoke_dust/dep_dry_simple_mod.F90 index ea7dd9963..e47d3d974 100755 --- a/physics/smoke_dust/dep_dry_mod.F90 +++ b/physics/smoke_dust/dep_dry_simple_mod.F90 @@ -1,7 +1,7 @@ -!>\file dep_dry_mod.F90 +!>\file dep_dry_simple_mod.F90 !! This file is for the dry depostion driver. -module dep_dry_mod +module dep_dry_simple_mod use machine , only : kind_phys @@ -9,11 +9,11 @@ module dep_dry_mod private - public :: dry_dep_driver + public :: dry_dep_driver_simple contains - subroutine dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & + subroutine dry_dep_driver_simple(rmol,ust,ndvel,ddvel, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ) @@ -26,8 +26,6 @@ subroutine dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & its,ite, jts,jte, kts,kte REAL(kind_phys), DIMENSION( ims:ime , jms:jme ) , & INTENT(INOUT) :: ust, rmol - REAL(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ), & - INTENT(IN ) :: rel_hum REAL(kind_phys), PARAMETER :: kpart=500. REAL(kind_phys) :: dvpart @@ -56,14 +54,11 @@ subroutine dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & dvpart = dvpart*(1.+(-300.*rmol(i,j))**0.66667) ENDIF - IF (rel_hum(i,1,j)>0.8) THEN ! HIGH RELATIVE HUMIDITY CORRECTION - dvpart = dvpart*(1.+0.37*exp((rel_hum(i,1,j)-0.8)/0.2)) - END IF ddvel(i,j,nv) = MIN(0.50,dvpart) ! m/s enddo enddo enddo -end subroutine dry_dep_driver +end subroutine dry_dep_driver_simple -end module dep_dry_mod +end module dep_dry_simple_mod diff --git a/physics/smoke_dust/dust_fengsha_mod.F90 b/physics/smoke_dust/dust_fengsha_mod.F90 index 1e24c8947..54e66712d 100755 --- a/physics/smoke_dust/dust_fengsha_mod.F90 +++ b/physics/smoke_dust/dust_fengsha_mod.F90 @@ -22,7 +22,7 @@ module dust_fengsha_mod subroutine gocart_dust_fengsha_driver(dt, & chem,rho_phy,smois,p8w,ssm, & - isltyp,vegfra,snowh,xland,area,g,emis_dust, & + isltyp,snowh,xland,area,g,emis_dust, & ust,znt,clay,sand,rdrag,uthr, & num_emis_dust,num_chem,num_soil_layers, & ids,ide, jds,jde, kds,kde, & @@ -37,7 +37,6 @@ subroutine gocart_dust_fengsha_driver(dt, & ! 2d input variables REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: ssm ! Sediment supply map - REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: vegfra ! vegetative fraction (-) REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: snowh ! snow height (m) REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: xland ! dominant land use type REAL(kind_phys), DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: area ! area of grid cell @@ -141,9 +140,6 @@ subroutine gocart_dust_fengsha_driver(dt, & endif ! limit where there is lots of vegetation - if (vegfra(i,j) .gt. .17) then - ilwi = 0 - endif ! limit where there is snow on the ground if (snowh(i,j) .gt. 0) then diff --git a/physics/smoke_dust/module_add_emiss_burn.F90 b/physics/smoke_dust/module_add_emiss_burn.F90 index 6cdd2e071..95005b973 100755 --- a/physics/smoke_dust/module_add_emiss_burn.F90 +++ b/physics/smoke_dust/module_add_emiss_burn.F90 @@ -6,217 +6,156 @@ module module_add_emiss_burn use machine , only : kind_phys use rrfs_smoke_config CONTAINS - subroutine add_emis_burn(dtstep,dz8w,rho_phy,rel_hum, & - chem,julday,gmt,xlat,xlong, & - !luf_igbp,lu_fire1, & - vegtype,vfrac,peak_hr, & - time_int,ebu, & ! RAR - r_q,fhist,ext3d_smoke,ext3d_dust, & - ! nwfa,nifa, & - rainc,rainnc, swdown,smoke_forecast, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte ) - -! USE module_configure, only: grid_config_rec_type -! USE module_state_description - IMPLICIT NONE + subroutine add_emis_burn(dtstep,dz8w,rho_phy,pi, & + chem,julday,gmt,xlat,xlong, & + fire_end_hr, peak_hr,time_int, & + coef_bb_dc, fhist, hwp, hwp_prevd, & + swdown,ebb_dcycle, ebu_in, ebu,fire_type,& + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) -! TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags + IMPLICIT NONE - INTEGER, INTENT(IN ) :: julday, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & + INTEGER, INTENT(IN ) :: julday, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte real(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), & - INTENT(INOUT ) :: chem + INTENT(INOUT ) :: chem ! shall we set num_chem=1 here? real(kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme ), & - INTENT(IN) :: ebu - - real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(IN) :: xlat,xlong, rainc,rainnc,swdown, peak_hr, vfrac - real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(OUT) :: r_q ! RAR: - real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: fhist ! RAR: - real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(OUT) :: ext3d_smoke, ext3d_dust ! RAR: - integer, DIMENSION(ims:ime,jms:jme), INTENT(IN) :: vegtype - - real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(IN) :: dz8w,rho_phy,rel_hum -! real(kind_phys), DIMENSION(ims:ime,1:nlcat,jms:jme), INTENT(IN) :: luf_igbp - -! real(kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & -! OPTIONAL, INTENT(INOUT ) :: nwfa,nifa ! RAR: - - real(kind_phys), INTENT(IN) :: dtstep, gmt - real(kind_phys), INTENT(IN) :: time_int ! RAR: time in seconds since start of simulation - integer, INTENT(IN) :: smoke_forecast - - integer :: i,j,k,n,m - real(kind_phys) :: conv_rho, conv, ext2, dm_smoke, daero_num_wfa, daero_num_ifa !, lu_sum1_5, lu_sum12_14 - !real(kind_phys) :: ebumax -! CHARACTER (LEN=80) :: message - - INTEGER, PARAMETER :: kfire_max=51 ! max vertical level for BB plume rise - ! Diameters and standard deviations for emissions - ! the diameters are the volume (mass) geometric mean diameters, following MADE_SORGAM - real(kind_phys), PARAMETER :: dgvem_i= 0.08E-6 !0.03E-6 ! [ m ] - real(kind_phys), PARAMETER :: sgem_i = 1.8 !1.7 - - ! *** Accumulation mode: - real(kind_phys), PARAMETER :: dgvem_j= 0.3E-6 ! [ m ] - real(kind_phys), PARAMETER :: sgem_j = 2.0 - - ! *** Coarse mode - real(kind_phys), PARAMETER :: dgvem_c= 6.0E-6 ! [ m ] - real(kind_phys), PARAMETER :: sgem_c= 2.2 - real(kind_phys), PARAMETER :: pic= 3.14159 - - ! RAR: factors for getting number emissions rate from mass emissions rate following made_sorgam - real(kind_phys), PARAMETER :: fact_numn= 1.e-9*6.0/pic*exp(4.5*log(sgem_i)**2)/dgvem_i**3 ! Aitken mode - real(kind_phys), PARAMETER :: fact_numa= 1.e-9*6.0/pic*exp(4.5*log(sgem_j)**2)/dgvem_j**3 ! accumulation mode - real(kind_phys), PARAMETER :: fact_numc= 1.e-9*6.0/pic*exp(4.5*log(sgem_c)**2)/dgvem_c**3 ! coarse mode - - real(kind_phys), PARAMETER :: dens_oc_aer=1.4e3, dens_ec_aer=1.7e3 ! kg/m3 -! real(kind_phys), PARAMETER :: rinti=2.1813936e-8, cx=2.184936* 3600, timeq_max=3600.*24. ! constants for the diurnal cycle calculations - real(kind_phys), PARAMETER :: ax1=531., cx1=7800. ! For cropland, urban and small fires -! real(kind_phys), PARAMETER :: rinti=2.1813936e-8, ax2=3200., const2=100., coef2=10.6712963e-4, cx=2.184936* 3600, timeq_max=3600.*24. - real(kind_phys), PARAMETER :: rinti=2.1813936e-8, ax2=3400., const2=130., coef2=10.6712963e-4, cx2=7200., timeq_max=3600.*24. ! New parameters - real(kind_phys), PARAMETER :: sc_me= 4.0, ab_me=0.5 ! m2/g, scattering and absorption efficiency for smoke - -! Parameters used for the wfa and ifa in mp physics per Trude E. (NCAR) -! Water friendly: radius: 0.04 micron, standard deviation: 1.8, kappa (for hygroscopic growth): 0.2, real index of refraction: 1.53, imaginary index of refraction: 1e-7 -! Ice friendly: radius: 0.4 micron, standard deviation: 1.8, kappa : 0.04, real index of refraction: 1.56, imaginary index of refraction: 3e-3 + INTENT(INOUT ) :: ebu + real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(IN) :: xlat,xlong, swdown + real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(IN) :: hwp, peak_hr, fire_end_hr, ebu_in !, vfrac + real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: coef_bb_dc ! RAR: + real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(IN) :: hwp_prevd + + real(kind_phys), DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(IN) :: dz8w,rho_phy !,rel_hum + real(kind_phys), INTENT(IN) :: dtstep, gmt + real(kind_phys), INTENT(IN) :: time_int,pi ! RAR: time in seconds since start of simulation + INTEGER, DIMENSION(ims:ime,jms:jme), INTENT(IN) :: fire_type + integer, INTENT(IN) :: ebb_dcycle ! RAR: this is going to be namelist dependent, ebb_dcycle=means + real(kind_phys), DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: fhist +!>--local + integer :: i,j,k,n,m + real(kind_phys) :: conv_rho, conv, dm_smoke, dc_hwp, dc_gp, dc_fn !daero_num_wfa, daero_num_ifa !, lu_sum1_5, lu_sum12_14 + + INTEGER, PARAMETER :: kfire_max=51 ! max vertical level for BB plume rise + ! real, parameter :: cx = 2.184936 * 3600., rinti = 2.1813936e-8 , ax = 2000.6038 ! bx_bburn = 20.041288 * 3600., RAR: this depends on the vegetation class, location (local time) etc. - real(kind_phys) :: timeq, dt1,dt2,dtm ! For BB emis. diurnal cycle calculation - - timeq= gmt*3600. + real(time_int,4) + real(kind_phys) :: timeq, fire_age, age_hr, dt1,dt2,dtm ! For BB emis. diurnal cycle calculation + ! For Gaussian diurnal cycle + real(kind_phys), PARAMETER :: sc_factor=1. ! to scale up the wildfire emissions, TBD later + real(kind_phys), PARAMETER :: rinti=2.1813936e-8, ax2=3400., const2=130., & + coef2=10.6712963e-4, cx2=7200., timeq_max=3600.*24. +!>-- Fire parameters + real(kind_phys), dimension(1:5), parameter :: avg_fire_dur = (/8.9, 4.2, 3.3, 3.0, 1.4/) + real(kind_phys), dimension(1:5), parameter :: sigma_fire_dur = (/8.7, 6.0, 5.5, 5.2, 2.4/) + + timeq= gmt*3600._kind_phys + real(time_int,4) timeq= mod(timeq,timeq_max) -! Main loops to add BB emissions - do j=jts,jte - do i=its,ite - !if( luf_igbp(i,17,j)>0.99 .OR. ebu(i,1,j,p_ebu_smoke) < 1.e-6) cycle ! no BB emissions or water pixels - if( (1.-vfrac (i,j))>0.99 .OR. ebu(i,1,j) < 1.e-6) cycle ! no BB emissions or water pixels - - ! RAR: the decrease in the BB emissions after >18 hrs of forecast, the decrease occurs at night. The decrease occurs at night. - IF (time_int>64800. .AND. swdown(i,j)<.1 .AND. fhist(i,j)>.75 ) THEN - fhist(i,j)= 0.75 - ENDIF - IF (time_int>129600. .AND. swdown(i,j)<.1 .AND. fhist(i,j)>.5 ) THEN ! After 36 hr forecast - fhist(i,j)= 0.5 - ENDIF - - IF ( (rainc(i,j) + rainnc(i,j))>=10. .AND. fhist(i,j)>.3 ) THEN ! If it rains more than 1cm, then the BB emissions are reduced - fhist(i,j)= 0.3 - ENDIF - -! RAR: Grasslands (29% of ther western HRRR CONUS domain) probably also need to be added below, check this later -! RAR: In the HRRR CONUS domain (western part) crop 11%, 2% cropland/natural vegetation and 0.4% urban of pixels -!.OR. lu_index(i,j)==14) then ! Croplands(12), Urban and Built-Up(13), cropland/natural vegetation (14) mosaic in MODI-RUC vegetation classes +! RAR: Grasslands (29% of ther western HRRR CONUS domain) probably also need to +! be added below, check this later +! RAR: In the HRRR CONUS domain (western part) crop 11%, 2% cropland/natural +! vegetation and 0.4% urban of pixels +!.OR. lu_index(i,j)==14) then ! Croplands(12), Urban and Built-Up(13), +!cropland/natural vegetation (14) mosaic in MODI-RUC vegetation classes ! Peak hours for the fire activity depending on the latitude -! if (xlong(i,j)<-130.) then max_ti= 24.041288* 3600. ! peak at 24 UTC, fires in Alaska -! elseif (xlong(i,j)<-100.) then max_ti= 22.041288* 3600. ! peak at 22 UTC, fires in the western US -! elseif (xlong(i,j)<-70.) then ! peak at 20 UTC, fires in the eastern US, max_ti= 20.041288* 3600. +! if (xlong(i,j)<-130.) then max_ti= 24.041288* 3600. ! +! peak at 24 UTC, fires in Alaska +! elseif (xlong(i,j)<-100.) then max_ti= 22.041288* 3600. +! ! peak at 22 UTC, fires in the western US +! elseif (xlong(i,j)<-70.) then ! peak at 20 UTC, fires in +! the eastern US, max_ti= 20.041288* 3600. ! else max_ti= 18.041288* 3600. ! endif +! RAR: for option #1 ebb and frp are ingested for 24 hours. No modification is +! applied! + if (ebb_dcycle==1) then + do k=kts,kte + do i=its,ite + ebu(i,k,1)=ebu_in(i,1) ! RAR: + enddo + enddo + endif + + if (ebb_dcycle==2) then + + ! Constants for the fire diurnal cycle calculation + do j=jts,jte + do i=its,ite + fire_age= time_int + (fire_end_hr(i,j))*3600. + + SELECT CASE ( fire_type(i,j) ) !Ag, urban fires, bare land etc. + CASE (1) + ! these fires will have exponentially decreasing diurnal cycle, + ! We assume 1hr latency in ingesting the sat. data + coef_bb_dc(i,j) = 1._kind_phys/((2*pi)**0.5_kind_phys * sigma_fire_dur(1) *fire_age) * & + exp(- ( log(fire_age) - avg_fire_dur(1))**2 /(2*sigma_fire_dur(1)**2 )) + CASE (3) + age_hr= fire_age/3600._kind_phys + + IF (swdown(i,j)<.1 .AND. age_hr> 12. .AND. fhist(i,j)>0.75) THEN + fhist(i,j)= 0.75_kind_phys + ENDIF + IF (swdown(i,j)<.1 .AND. age_hr> 24. .AND. fhist(i,j)>0.5) THEN + fhist(i,j)= 0.5_kind_phys + ENDIF + IF (swdown(i,j)<.1 .AND. age_hr> 48. .AND. fhist(i,j)>0.25) THEN + fhist(i,j)= 0.25_kind_phys + ENDIF + + ! this is based on hwp, hourly or instantenous TBD + dc_hwp= ebu_in(i,j)* hwp(i,j)/ MAX(1._kind_phys,hwp_prevd(i,j)) + dc_hwp= MAX(0._kind_phys,dc_hwp) + + !coef_bb_dc(i,j)= sc_factor* fhist(i,j)* rate_ebb2(i,j)* (1. + log( + !hwp_(i,j)/ hwp_day_avg(i,j))) + + ! RAR: Gaussian profile for wildfires + dt1= abs(timeq - peak_hr(i,j)) + dt2= timeq_max - peak_hr(i,j) + timeq ! peak hour is always <86400. + dtm= MIN(dt1,dt2) + dc_gp = rinti*( ax2 * exp(- dtm**2/(2._kind_phys*cx2**2) ) + const2 - coef2*timeq ) + dc_gp = MAX(0._kind_phys,dc_gp) + + dc_fn = MAX(dc_hwp/dc_gp,3._kind_phys) + coef_bb_dc(i,j) = fhist(i,j)* dc_fn + CASE DEFAULT + END SELECT + enddo + enddo + endif + + do j=jts,jte + do i=its,ite + do k=kts,kfire_max + if (ebb_dcycle==1) then + conv= dtstep/(rho_phy(i,k,j)* dz8w(i,k,j)) + elseif (ebb_dcycle==2) then + conv= sc_factor*coef_bb_dc(i,j)*dtstep/(rho_phy(i,k,j)* dz8w(i,k,j)) + endif + dm_smoke= conv*ebu(i,k,j) + chem(i,k,j,p_smoke) = chem(i,k,j,p_smoke) + dm_smoke + chem(i,k,j,p_smoke) = MIN(chem(i,k,j,p_smoke),5.e+3) + + if ( dbg_opt .and. (k==kts .OR. k==kfire_max) ) then + WRITE(6,*) 'add_emiss_burn: i,j,k ',i,j,k + WRITE(6,*) 'add_emiss_burn: rho_phy(i,k,j),dz8w(i,k,j),conv',rho_phy(i,k,j),dz8w(i,k,j),conv + WRITE(6,*) 'add_emiss_burn: ebu(i,k,j),dm_smoke ', ebu(i,k,j),dm_smoke + endif + enddo + enddo + enddo - !IF ( lu_fire1(i,j)>0.9 ) then !Ag, urban fires, bare land etc. - IF ( vegtype(i,j)==12 .or. vegtype(i,j)==13 ) then !Ag, urban fires, bare land etc. - ! these fires will have exponentially decreasing diurnal cycle, these fires decrease 55% in 2 hours, end in 5 hours - r_q(i,j) = rinti* ax1 * exp(- (time_int**2)/(cx1**2) ) - ELSE - ! RAR: Gaussian profile for wildfires - dt1= abs(timeq - peak_hr(i,j)) - dt2= timeq_max - peak_hr(i,j) + timeq ! peak hour is always <86400. - dtm= MIN(dt1,dt2) - r_q(i,j) = rinti*( ax2 * exp(- dtm**2/(2.*cx2**2) ) + const2 - coef2*timeq ) - ENDIF - - r_q(i,j) = fhist(i,j)* max(0.,r_q(i,j)*timeq_max) - - !IF (swdown(i,j)<.1) THEN - ! r_q(i,j)= MIN(0.5,r_q(i,j)) ! lower BB emissions at night - !ENDIF - - !IF (.NOT. config_flags%bb_dcycle) THEN - !IF (.NOT. bb_dcycle) THEN - ! r_q(i,j)= fhist(i,j) ! no diurnal cycle - !END IF - - !IF (smoke_forecast == 0) THEN - r_q(i,j)= 1. - !END IF - - do k=kts,kfire_max - conv= r_q(i,j)*dtstep/(rho_phy(i,k,j)* dz8w(i,k,j)) - - ! RAR: in this case tracer_1 is fire emitted CO - ! conv_rho=r_q*4.828e-4/rho_phy(i,k,j)*dtstep/(dz8w(i,k,j)*60.) - ! chem(i,k,j,p_tracer_1) = chem(i,k,j,p_tracer_1) + ebu(i,k,j,p_ebu_co)*conv_rho - -! dm_oc_bb = conv* ebu(i,k,j,p_ebu_oc) ! Assume that BB primary PM25 is mostly OC, 1.25 is OM/OC ratio -! dm_p25_bb= conv* ebu(i,k,j,p_ebu_pm25) -! dm_ec_bb = conv* ebu(i,k,j,p_ebu_bc) -! dm_smk = conv* ebu(i,k,j,p_ebu_smoke) - !IF (k==kts) THEN ! Partition takes place here to avoid double counting of smold. and flam. BB emiss. - ! C11= (1.-flam_frac(i,j))*r_q(i,j) - !ELSE - ! C11= flam_frac(i,j)*r_q(i,j) - !ENDIF - dm_smoke= conv*ebu(i,k,j) -! print*,'hli dm_smoke',dm_smoke,conv,ebu(i,k,j,p_ebu_smoke) - - chem(i,k,j,p_smoke) = chem(i,k,j,p_smoke) + dm_smoke - chem(i,k,j,p_smoke) = MIN(chem(i,k,j,p_smoke),5.e+3) - - ! if ( k==kts ) then - ! WRITE(6,*) 'add_emiss_burn: gmt,dtstep,time_int ',gmt,dtstep,time_int - ! WRITE(*,*) 'add_emiss_burn: i,j,xlat(i,j),xlong(i,j) ',i,j,xlat(i,j),xlong(i,j) - !WRITE(*,*) 'add_emiss_burn: luf_igbp(i,:,j) ',luf_igbp(i,:,j) - !WRITE(*,*) 'add_emiss_burn: lu_fire1(i,j) ',lu_fire1(i,j) - ! WRITE(6,*) 'add_emiss_burn: timeq,peak_hr(i,j),fhist(i,j),r_q(i,j) ',timeq,peak_hr(i,j),fhist(i,j),r_q(i,j) - ! WRITE(*,*) 'add_emiss_burn: rainc(i,j),rainnc(i,j) ', rainc(i,j),rainnc(i,j) - ! endif - if ( dbg_opt .and. (k==kts .OR. k==kfire_max) ) then - WRITE(6,*) 'add_emiss_burn: i,j,k ',i,j,k - WRITE(6,*) 'add_emiss_burn: rho_phy(i,k,j),dz8w(i,k,j),conv ',rho_phy(i,k,j),dz8w(i,k,j),conv - WRITE(6,*) 'add_emiss_burn: ebu(i,k,j),dm_smoke ', ebu(i,k,j),dm_smoke - endif - - enddo - enddo - enddo - - ext2= sc_me + ab_me - do j=jts,jte - do k=kts,kte - do i=its,ite - - ! Check for NaNs, negative and too large numbers - IF (.NOT. (chem(i,k,j,p_smoke)>=0. .AND. chem(i,k,j,p_smoke)<1.1e+4)) THEN - chem(i,k,j,p_smoke)=1.e-16 - END IF - - ext3d_smoke(i,k,j)= 1.e-6* ext2* chem(i,k,j,p_smoke )*rho_phy(i,k,j)*dz8w(i,k,j) - ext3d_dust (i,k,j)= 1.e-6* ext2* chem(i,k,j,p_dust_1)*rho_phy(i,k,j)*dz8w(i,k,j) - enddo - enddo - enddo - - IF ( dbg_opt ) then - WRITE(*,*) 'add_emis_burn: i,j,k,ext2 ',i,j,k,ext2 - WRITE(*,*) 'add_emis_burn: rel_hum(its,kts,jts),rel_hum(ite,kfire_max,jte) ',rel_hum(its,kts,jts),rel_hum(ite,kfire_max,jte) - WRITE(*,*) 'add_emis_burn: ext3d_smoke(its,kts,jts),ext3d_smoke(ite,kfire_max,jte) ',ext3d_smoke(its,kts,jts),ext3d_smoke(ite,kfire_max,jte) - WRITE(*,*) 'add_emis_burn: ext3d_dust(its,kts,jts),ext3d_dust(ite,kfire_max,jte) ',ext3d_dust(its,kts,jts),ext3d_dust(ite,kfire_max,jte) - END IF - -! CASE DEFAULT -! call wrf_debug(15,'nothing done with burn emissions for chem array') -! END SELECT emiss_select END subroutine add_emis_burn END module module_add_emiss_burn + diff --git a/physics/smoke_dust/module_plumerise.F90 b/physics/smoke_dust/module_plumerise.F90 new file mode 100755 index 000000000..8a1d6ab25 --- /dev/null +++ b/physics/smoke_dust/module_plumerise.F90 @@ -0,0 +1,172 @@ +!>\file module_plumerise.F90 +!! This file is the fire plume rise driver. + + module module_plumerise + + use machine , only : kind_phys +! real(kind=kind_phys),parameter :: p1000mb = 100000. ! p at 1000mb (pascals) +!- Implementing the fire radiative power (FRP) methodology for biomass burning +!- emissions and convective energy estimation. +!- Saulo Freitas, Gabriel Pereira (INPE/UFJS, Brazil) +!- Ravan Ahmadov, Georg Grell (NOAA, USA) +!- The flag "plumerise_flag" defines the method: +!- =1 => original method +!- =2 => FRP based + +CONTAINS +subroutine ebu_driver ( flam_frac,ebu_in,ebu, & + theta_phy,q_vap, & ! RAR: moist is replaced with q_vap, SRB: t_phy is repalced by theta_phy + rho_phy,vvel,u_phy,v_phy,pi_phy, & ! SRB: p_phy is replaced by pi_phy + wind_phy, & ! SRB: added wind_phy + z_at_w,z,g,con_cp,con_rd, & ! scale_fire_emiss is part of config_flags + frp_inst, k_min, k_max, & ! RAR: + wind_eff_opt, & + kpbl_thetav, & ! SRB: added kpbl_thetav + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte, errmsg, errflg) + + use rrfs_smoke_config + use plume_data_mod + USE module_zero_plumegen_coms + USE module_smoke_plumerise + IMPLICIT NONE + + REAL(kind_phys), PARAMETER :: frp_threshold= 1.e+7 ! Minimum FRP (Watts) to distribute smoke in PBL + + REAL(kind_phys), PARAMETER :: zpbl_threshold = 2000. ! SRB: Minimum PBL depth to have plume rise + REAL(kind_phys), PARAMETER :: uspd_threshold = 5. ! SRB: Wind speed averaged across PBL depth to control smoke release levels + REAL(kind_phys), PARAMETER :: frp_threshold500 = 500.e+6 ! SRB: Minimum FRP (Watts) to have plume rise + + real(kind=kind_phys), DIMENSION( ims:ime, jms:jme), INTENT(IN ) :: frp_inst ! RAR: FRP array + + real(kind_phys), DIMENSION(ims:ime, jms:jme), INTENT(IN) :: kpbl_thetav ! SRB + + character(*), intent(inout) :: errmsg + integer, intent(inout) :: errflg + INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte + INTEGER, INTENT(IN ) :: wind_eff_opt + real(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT ) :: ebu + real(kind=kind_phys), INTENT(IN ) :: g, con_cp, con_rd + real(kind=kind_phys), DIMENSION( ims:ime, jms:jme ), INTENT(IN ) :: ebu_in + real(kind=kind_phys), DIMENSION( ims:ime, jms:jme ), INTENT(OUT ) :: flam_frac + real(kind=kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & + INTENT(IN ) :: z,z_at_w,vvel,u_phy,v_phy,rho_phy,pi_phy,q_vap,theta_phy,wind_phy ! RAR, SRB + +! Local variables... + INTEGER :: nv, i, j, k, kp1, kp2 + INTEGER, DIMENSION(ims:ime, jms:jme), INTENT (OUT) :: k_min, k_max ! Min and max ver. levels for BB injection spread + real(kind_phys), dimension (kte) :: u_in ,v_in ,w_in ,theta_in ,pi_in, rho_phyin ,qv_in ,zmid, z_lev, uspd ! SRB + real(kind=kind_phys) :: dz_plume, cpor, con_rocp, uspdavg ! SRB + + cpor =con_cp/con_rd + con_rocp=con_rd/con_cp + + IF ( dbg_opt ) then + WRITE(*,*) 'module_plumerise: its,ite,jts,jte ', its,ite,jts,jte + WRITE(*,*) 'module_plumerise: ims,ime,jms,jme ', ims,ime,jms,jme + WRITE(*,*) 'module_plumerise: maxval(ebu(:,kts,:)) ', maxval(ebu(:,kts,:)) + END IF + +! RAR: setting to zero the ebu emissions at the levels k>1, this is necessary when the plumerise is called, so the emissions at k>1 are updated + !do nv=1,num_ebu + do j=jts,jte + do k=kts+1,kte + do i=its,ite + ebu(i,k,j)=0. + enddo + enddo + enddo + !enddo + +! For now the flammable fraction is constant, based on the namelist. The next +! step to use LU index and meteorology to parameterize it + do j=jts,jte + do i=its,ite + flam_frac(i,j)= 0. + if (frp_inst(i,j) > frp_threshold) then + flam_frac(i,j)= 0.9 + end if + enddo + enddo + + +! RAR: new FRP based approach +! Haiqin: do_plumerise is added to the namelist options +check_pl: IF (do_plumerise) THEN ! if the namelist option is set for plumerise + do j=jts,jte + do i=its,ite + + do k=kts,kte + u_in(k)= u_phy(i,k,j) + v_in(k)= v_phy(i,k,j) + w_in(k)= vvel(i,k,j) + qv_in(k)= q_vap(i,k,j) + pi_in(k)= pi_phy(i,k,j) + zmid(k)= z(i,k,j)-z_at_w(i,kts,j) + z_lev(k)= z_at_w(i,k,j)-z_at_w(i,kts,j) + rho_phyin(k)= rho_phy(i,k,j) + theta_in(k)= theta_phy(i,k,j) + uspd(k)= wind_phy(i,k,j) ! SRB + enddo + + IF (dbg_opt) then + WRITE(*,*) 'module_plumerise: i,j ',i,j + WRITE(*,*) 'module_plumerise: frp_inst(i,j) ',frp_inst(i,j) + WRITE(*,*) 'module_plumerise: ebu(i,kts,j) ',ebu(i,kts,j) + WRITE(*,*) 'module_plumerise: u_in(10),v_in(10),w_in(kte),qv_in(10),pi_in(10) ',u_in(10),v_in(10),w_in(kte),qv_in(10),pi_in(10) + WRITE(*,*) 'module_plumerise: zmid(kte),z_lev(kte),rho_phyin(kte),theta_in(kte) ',zmid(kte),z_lev(kte),rho_phyin(kte),theta_in(kte) + END IF + +! RAR: the plume rise calculation step: + CALL plumerise(kte,1,1,1,1,1,1, & + u_in, v_in, w_in, theta_in ,pi_in, & + rho_phyin, qv_in, zmid, z_lev, & + wind_eff_opt, & + frp_inst(i,j), k_min(i,j), & + k_max(i,j), dbg_opt, g, con_cp, & + con_rd, cpor, errmsg, errflg ) + if(errflg/=0) return + + kp1= k_min(i,j) + kp2= k_max(i,j) + dz_plume= z_at_w(i,kp2,j) - z_at_w(i,kp1,j) + +! SRB: Adding condition for overwriting plumerise levels + uspdavg=SUM(uspd(kts:kpbl_thetav(i,j)))/kpbl_thetav(i,j) !Average wind speed within the boundary layer + + IF ((frp_inst(i,j) .gt. frp_threshold) .AND. (frp_inst(i,j) .le. frp_threshold500) .AND. & + (z_at_w(i,kpbl_thetav(i,j),j) .gt. zpbl_threshold) .AND. (wind_eff_opt .eq. 1)) THEN + kp1=1 + IF (uspdavg .ge. uspd_threshold) THEN ! Too windy + kp2=kpbl_thetav(i,j)/3 + ELSE + kp2=kpbl_thetav(i,j) + END IF + dz_plume= z_at_w(i,kp2,j) - z_at_w(i,kp1,j) + do k=kp1,kp2-1 + ebu(i,k,j)= ebu_in(i,j)* (z_at_w(i,k+1,j)-z_at_w(i,k,j))/dz_plume + enddo + ELSE + do k=kp1,kp2-1 + ebu(i,k,j)= flam_frac(i,j)* ebu_in(i,j)* (z_at_w(i,k+1,j)-z_at_w(i,k,j))/dz_plume + enddo + ebu(i,kts,j)= (1.-flam_frac(i,j))* ebu_in(i,j) + END IF +! SRB: End modification + + IF ( dbg_opt ) then + WRITE(*,*) 'module_plumerise: i,j ',i,j + WRITE(*,*) 'module_plumerise: k_min(i,j), k_max(i,j) ',kp1, kp2 ! SRB: replaced k_min, k_max with kp1, kp2 + END IF +! endif check_frp + enddo + enddo + + ENDIF check_pl + +end subroutine ebu_driver + +END module module_plumerise diff --git a/physics/smoke_dust/module_plumerise1.F90 b/physics/smoke_dust/module_plumerise1.F90 deleted file mode 100755 index 3c23faa6a..000000000 --- a/physics/smoke_dust/module_plumerise1.F90 +++ /dev/null @@ -1,214 +0,0 @@ -!>\file module_plumerise1.F90 -!! This file is the fire plume rise driver. - - module module_plumerise1 - - use machine , only : kind_phys - real(kind=kind_phys),parameter :: p1000mb = 100000. ! p at 1000mb (pascals) -!- Implementing the fire radiative power (FRP) methodology for biomass burning -!- emissions and convective energy estimation. -!- Saulo Freitas, Gabriel Pereira (INPE/UFJS, Brazil) -!- Ravan Ahmadov, Georg Grell (NOAA, USA) -!- The flag "plumerise_flag" defines the method: -!- =1 => original method -!- =2 => FRP based -!------------------------------------------------------------------------- -! -! use module_zero_plumegen_coms -! integer, parameter :: nveg_agreg = 4 -! integer, parameter :: tropical_forest = 1 -! integer, parameter :: boreal_forest = 2 -! integer, parameter :: savannah = 3 - -! integer, parameter :: grassland = 4 -! real(kind_phys), dimension(nveg_agreg) :: firesize,mean_fct -! character(len=20), parameter :: veg_name(nveg_agreg) = (/ & -! 'Tropical-Forest', & -! 'Boreal-Forest ', & -! 'Savanna ', & -! 'Grassland ' /) -! character(len=20), parameter :: spc_suf(nveg_agreg) = (/ & -! 'agtf' , & ! trop forest -! 'agef' , & ! extratrop forest -! 'agsv' , & ! savanna -! 'aggr' /) ! grassland - -CONTAINS -subroutine ebu_driver ( flam_frac,ebb_smoke,ebu, & - t_phy,q_vap, & ! RAR: moist is replaced with q_vap - rho_phy,vvel,u_phy,v_phy,p_phy, & - z_at_w,z,g,con_cp,con_rd, & ! scale_fire_emiss is part of config_flags - plume_frp, k_min, k_max, & ! RAR: - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte, errmsg, errflg) - - use rrfs_smoke_config - use plume_data_mod - USE module_zero_plumegen_coms - USE module_smoke_plumerise - IMPLICIT NONE - - REAL(kind_phys), PARAMETER :: frp_threshold= 1.e+7 ! Minimum FRP (Watts) to have plume rise - - real(kind=kind_phys), DIMENSION( ims:ime, jms:jme, 2 ), INTENT(IN ) :: plume_frp ! RAR: FRP etc. array - -! TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags - character(*), intent(inout) :: errmsg - integer, intent(inout) :: errflg - INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte -! real(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme, num_moist ), & -! INTENT(IN ) :: moist - real(kind=kind_phys), DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT ) :: ebu - - real(kind=kind_phys), INTENT(IN ) :: g, con_cp, con_rd - real(kind=kind_phys), DIMENSION( ims:ime, jms:jme ), INTENT(IN ) :: ebb_smoke - real(kind=kind_phys), DIMENSION( ims:ime, jms:jme ), INTENT(OUT ) :: flam_frac - -! real(kind=kind_phys), DIMENSION( ims:ime, 1, jms:jme ), & -! INTENT(IN ) :: ebu_in -! real(kind=kind_phys), DIMENSION( ims:ime, jms:jme ), & -! INTENT(IN ) :: & -! mean_fct_agtf,mean_fct_agef,& -! mean_fct_agsv,mean_fct_aggr,firesize_agtf,firesize_agef, & -! firesize_agsv,firesize_aggr - - real(kind=kind_phys), DIMENSION( ims:ime , kms:kme , jms:jme ) , & - INTENT(IN ) :: t_phy,z,z_at_w,vvel,u_phy,v_phy,rho_phy,p_phy,q_vap ! RAR - ! real(kind=kind_phys), INTENT(IN ) :: dtstep - -! Local variables... - INTEGER :: nv, i, j, k, kp1, kp2 - INTEGER, DIMENSION(ims:ime, jms:jme), INTENT (OUT) :: k_min, k_max ! Min and max ver. levels for BB injection spread - !real(kind_phys), dimension (num_ebu) :: eburn_in - !real(kind_phys), dimension (kte,num_ebu) :: eburn_out - real(kind_phys), dimension (kte) :: u_in ,v_in ,w_in ,theta_in ,pi_in, rho_phyin ,qv_in ,zmid, z_lev - real(kind=kind_phys) :: dz_plume, cpor, con_rocp - - !INTEGER, PARAMETER :: kfire_max=30 -! real(kind_phys), dimension(nveg_agreg) :: firesize,mean_fct -! real(kind_phys) :: sum, ffirs, ratio -! real(kind_phys),save,dimension(its:ite,jts:jte) :: ffirs -! nspecies=num_ebu -! write(0,*)'plumerise' - -! RAR: -! do j=jts,jte: -! do i=its,ite -! ebu(i,kts,j,p_ebu_smoke)= ebb_smoke(i,j) -! ebu(i,kts,j,p_ebu_no) = ebu_in(i,1,j,p_ebu_in_no) -! ebu(i,kts,j,p_ebu_co) = ebu_in(i,1,j,p_ebu_in_co) -! ebu(i,kts,j,p_ebu_so2) = ebu_in(i,1,j,p_ebu_in_so2) -! ebu(i,kts,j,p_ebu_dms) = ebu_in(i,1,j,p_ebu_in_dms) -! ebu(i,kts,j,p_ebu_oc) = ebu_in(i,1,j,p_ebu_in_oc) -! ebu(i,kts,j,p_ebu_bc) = ebu_in(i,1,j,p_ebu_in_bc) -! ebu(i,kts,j,p_ebu_pm25) = ebu_in(i,1,j,p_ebu_in_pm25) -! ebu(i,kts,j,p_ebu_pm10) = ebu_in(i,1,j,p_ebu_in_pm10) -! enddo -! enddo - cpor =con_cp/con_rd - con_rocp=con_rd/con_cp - - IF ( dbg_opt ) then - WRITE(*,*) 'module_plumerise1: its,ite,jts,jte ', its,ite,jts,jte - WRITE(*,*) 'module_plumerise1: ims,ime,jms,jme ', ims,ime,jms,jme - !WRITE(*,*) 'module_plumerise1: p_ebu_smoke,num_ebu: ', p_ebu_smoke,num_ebu - WRITE(*,*) 'module_plumerise1: maxval(ebu(:,kts,:)) ', maxval(ebu(:,kts,:)) - END IF - !endif - -! RAR: setting to zero the ebu emissions at the levels k>1, this is necessary when the plumerise is called, so the emissions at k>1 are updated - !do nv=1,num_ebu - do j=jts,jte - do k=kts+1,kte - do i=its,ite - ebu(i,k,j)=0. - enddo - enddo - enddo - !enddo - -! For now the flammable fraction is constant, based on the namelist. The next -! step to use LU index and meteorology to parameterize it - do j=jts,jte - do i=its,ite - flam_frac(i,j)= 0. - if (plume_frp(i,j,1) > frp_threshold) then - flam_frac(i,j)= 0.9 - end if - enddo - enddo - - -! RAR: new FRP based approach -!check_pl: IF (config_flags%plumerise_flag == 2 ) THEN ! if the namelist option is set for plumerise -! Haiqin: plumerise_flag is added to the namelist options -check_pl: IF (do_plumerise) THEN ! if the namelist option is set for plumerise - do j=jts,jte - do i=its,ite - ! k_min(i,j)=0 - ! k_max(i,j)=0 - -! check_frp: if (.NOT.do_plumerise) then ! namelist option -! ebu(i,kts,j)= ebb_smoke(i,j) -! else - - do k=kts,kte - u_in(k)= u_phy(i,k,j) - v_in(k)= v_phy(i,k,j) - w_in(k)= vvel(i,k,j) - qv_in(k)= q_vap(i,k,j) ! RAR: moist(i,k,j,p_qv) - !pi_in(k)= cp*(p_phy(i,k,j)/p1000mb)**rcp - pi_in(k)= con_cp*(p_phy(i,k,j)/p1000mb)**con_rocp - zmid(k)= z(i,k,j)-z_at_w(i,kts,j) - z_lev(k)= z_at_w(i,k,j)-z_at_w(i,kts,j) - rho_phyin(k)= rho_phy(i,k,j) - theta_in(k)= t_phy(i,k,j)/pi_in(k)*con_cp - !theta_in(k)= t_phy(i,k,j)/pi_in(k)*cp - enddo - - IF (dbg_opt) then - WRITE(*,*) 'module_plumerise1: i,j ',i,j - WRITE(*,*) 'module_plumerise1: plume_frp(i,j,:) ',plume_frp(i,j,:) - WRITE(*,*) 'module_plumerise1: ebu(i,kts,j) ',ebu(i,kts,j) - WRITE(*,*) 'module_plumerise1: u_in(10),v_in(10),w_in(kte),qv_in(10),pi_in(10) ',u_in(10),v_in(10),w_in(kte),qv_in(10),pi_in(10) - WRITE(*,*) 'module_plumerise1: zmid(kte),z_lev(kte),rho_phyin(kte),theta_in(kte) ',zmid(kte),z_lev(kte),rho_phyin(kte),theta_in(kte) - WRITE(*,*) 'module_plumerise1: t_phy(i,kte,j),pi_in(kte)',t_phy(i,kte,j),pi_in(kte) - END IF - -! RAR: the plume rise calculation step: - CALL plumerise(kte,1,1,1,1,1,1, & - !firesize,mean_fct, & - !num_ebu, eburn_in, eburn_out, & - u_in, v_in, w_in, theta_in ,pi_in, & - rho_phyin, qv_in, zmid, z_lev, & - plume_frp(i,j,1), k_min(i,j), & - k_max(i,j), dbg_opt, g, con_cp, & - con_rd, cpor, errmsg, errflg ) - !k_max(i,j), config_flags%debug_chem ) - if(errflg/=0) return - - kp1= k_min(i,j) - kp2= k_max(i,j) - dz_plume= z_at_w(i,kp2,j) - z_at_w(i,kp1,j) - - do k=kp1,kp2-1 - ebu(i,k,j)= flam_frac(i,j)* ebb_smoke(i,j)* (z_at_w(i,k+1,j)-z_at_w(i,k,j))/dz_plume - enddo - ebu(i,kts,j)= (1.-flam_frac(i,j))* ebb_smoke(i,j) - - IF ( dbg_opt ) then - WRITE(*,*) 'module_plumerise1: i,j ',i,j - WRITE(*,*) 'module_plumerise1: k_min(i,j), k_max(i,j) ',k_min(i,j), k_max(i,j) - END IF -! endif check_frp - enddo - enddo - - ENDIF check_pl - -end subroutine ebu_driver - -END module module_plumerise1 diff --git a/physics/smoke_dust/module_smoke_plumerise.F90 b/physics/smoke_dust/module_smoke_plumerise.F90 index 61be06181..0fca91de4 100755 --- a/physics/smoke_dust/module_smoke_plumerise.F90 +++ b/physics/smoke_dust/module_smoke_plumerise.F90 @@ -14,9 +14,9 @@ module module_smoke_plumerise use machine , only : kind_phys - use plume_data_mod, only : num_frp_plume, p_frp_hr, p_frp_std, & + use plume_data_mod, only : num_frp_plume, p_frp_hr, p_frp_std !tropical_forest, boreal_forest, savannah, grassland, & - wind_eff + ! wind_eff USE module_zero_plumegen_coms !real(kind=kind_phys),parameter :: rgas=r_d @@ -24,16 +24,16 @@ module module_smoke_plumerise CONTAINS ! RAR: - subroutine plumerise(m1,m2,m3,ia,iz,ja,jz, & -! firesize,mean_fct, & - ! nspecies,eburn_in,eburn_out, & + subroutine plumerise(m1,m2,m3,ia,iz,ja,jz, & up,vp,wp,theta,pp,dn0,rv,zt_rams,zm_rams, & + wind_eff_opt, & frp_inst,k1,k2, dbg_opt, g, cp, rgas, & cpor, errmsg, errflg ) implicit none LOGICAL, INTENT (IN) :: dbg_opt + INTEGER, INTENT (IN) :: wind_eff_opt ! INTEGER, PARAMETER :: ihr_frp=1, istd_frp=2!, imean_fsize=3, istd_fsize=4 ! RAR: @@ -43,6 +43,7 @@ subroutine plumerise(m1,m2,m3,ia,iz,ja,jz, & integer :: ng,m1,m2,m3,ia,iz,ja,jz,ibcon,mynum,i,j,k,imm,ixx,ispc !,nspecies + INTEGER, INTENT (OUT) :: k1,k2 character(*), intent(inout) :: errmsg integer, intent(inout) :: errflg @@ -68,10 +69,13 @@ subroutine plumerise(m1,m2,m3,ia,iz,ja,jz, & ! integer, parameter :: grassland = 4 ! real(kind=kind_phys), dimension(nveg_agreg) :: firesize,mean_fct - INTEGER, PARAMETER :: wind_eff = 1 + INTEGER :: wind_eff type(plumegen_coms), pointer :: coms +! Set wind effect from namelist + wind_eff = wind_eff_opt + ! integer:: iloop !REAL(kind=kind_phys), INTENT (IN) :: convert_smold_to_flam diff --git a/physics/smoke_dust/module_wetdep_ls.F90 b/physics/smoke_dust/module_wetdep_ls.F90 index 87212920b..8ba8f67d9 100755 --- a/physics/smoke_dust/module_wetdep_ls.F90 +++ b/physics/smoke_dust/module_wetdep_ls.F90 @@ -3,17 +3,18 @@ module module_wetdep_ls use machine , only : kind_phys - use rrfs_smoke_config, only : p_qc, alpha => wetdep_ls_alpha + use rrfs_smoke_config, only : p_smoke, p_dust_1, p_coarse_pm, p_qc, alpha => wetdep_ls_alpha contains subroutine wetdep_ls(dt,var,rain,moist, & - rho,nchem,num_moist,dz8w,vvel, & + rho,nchem,num_moist,ndvel,dz8w,vvel, & + wetdpr_smoke, wetdpr_dust, wetdpr_coarsepm, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ) implicit none - integer, intent(in) :: nchem, num_moist, & + integer, intent(in) :: nchem, num_moist, ndvel, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte @@ -21,6 +22,8 @@ subroutine wetdep_ls(dt,var,rain,moist, real(kind_phys), dimension( ims:ime, kms:kme, jms:jme, num_moist),intent(in) :: moist real(kind_phys), dimension( ims:ime, kms:kme, jms:jme),intent(in) :: rho,dz8w,vvel real(kind_phys), dimension( ims:ime, kms:kme, jms:jme,1:nchem),intent(inout) :: var + real(kind_phys), dimension( ims:ime, jms:jme ), intent(out) :: & + wetdpr_smoke, wetdpr_dust, wetdpr_coarsepm real(kind_phys), dimension( ims:ime, jms:jme),intent(in) :: rain real(kind_phys), dimension( its:ite, jts:jte) :: var_sum,var_rmv real(kind_phys), dimension( its:ite, kts:kte, jts:jte) :: var_rmvl @@ -29,6 +32,9 @@ subroutine wetdep_ls(dt,var,rain,moist, integer :: nv,i,j,k,km,kb,kbeg !real(kind_phys), parameter :: alpha = .5 ! scavenging factor + wetdpr_smoke =0. + wetdpr_dust =0. + wetdpr_coarsepm=0. do nv=1,nchem do i=its,ite @@ -68,6 +74,14 @@ subroutine wetdep_ls(dt,var,rain,moist, if(var(i,k,j,nv).gt.1.e-16 .and. moist(i,k,j,p_qc).gt.0.)then factor = max(0.,frc(i,j)*rho(i,k,j)*dz8w(i,k,j)*vvel(i,k,j)) dvar=alpha*factor/(1+factor)*var(i,k,j,nv) +! Accumulate diags + if (nv .eq. p_smoke ) then + wetdpr_smoke(i,j) = wetdpr_smoke(i,j) + dvar * rho(i,k,j) * dt * 1.E-6 + elseif (nv .eq. p_dust_1 ) then + wetdpr_dust(i,j) = wetdpr_dust(i,j) + dvar * rho(i,k,j) * dt * 1.E-6 + elseif (nv .eq. p_coarse_pm ) then + wetdpr_coarsepm(i,j) = wetdpr_coarsepm(i,j) + dvar * rho(i,k,j) * dt * 1.E-6 + endif var(i,k,j,nv)=max(1.e-16,var(i,k,j,nv)-dvar) endif enddo diff --git a/physics/smoke_dust/plume_data_mod.F90 b/physics/smoke_dust/plume_data_mod.F90 index 3d4b21c37..3f0bcdecd 100755 --- a/physics/smoke_dust/plume_data_mod.F90 +++ b/physics/smoke_dust/plume_data_mod.F90 @@ -45,7 +45,6 @@ module plume_data_mod integer, parameter :: savannah = 3 integer, parameter :: grassland = 4 integer, parameter :: nveg_agreg = 4 - integer, parameter :: wind_eff = 1 public diff --git a/physics/smoke_dust/rrfs_smoke_config.F90 b/physics/smoke_dust/rrfs_smoke_config.F90 index 58d4c5846..d7478986b 100755 --- a/physics/smoke_dust/rrfs_smoke_config.F90 +++ b/physics/smoke_dust/rrfs_smoke_config.F90 @@ -15,30 +15,31 @@ module rrfs_smoke_config !-- constant paramters real(kind=kind_phys), parameter :: epsilc = 1.e-12 - !-- aerosol module configurations - integer :: chem_opt = 1 + integer :: chem_opt = 1 integer :: kemit = 1 integer :: dust_opt = 5 - integer :: seas_opt = 2 + integer :: seas_opt = 0 ! turn off by default logical :: do_plumerise = .true. integer :: addsmoke_flag = 1 + integer :: smoke_forecast = 1 integer :: plumerisefire_frq=60 integer :: wetdep_ls_opt = 1 integer :: drydep_opt = 1 - integer :: coarsepm_settling = 1 - logical :: bb_dcycle = .false. - logical :: aero_ind_fdb = .false. + integer :: pm_settling = 1 + integer :: nfire_types = 5 + integer :: ebb_dcycle = 2 ! 1: read in ebb_smoke(i,24), 2: daily logical :: dbg_opt = .true. - integer :: smoke_forecast = 0 ! 0 read in ebb_smoke(i,24) + logical :: aero_ind_fdb = .false. + logical :: add_fire_heat_flux= .false. + logical :: do_rrfs_sd = .true. +! integer :: wind_eff_opt = 1 + logical :: extended_sd_diags = .false. real(kind_phys) :: wetdep_ls_alpha = .5 ! scavenging factor ! -- integer, parameter :: CHEM_OPT_GOCART= 1 - integer, parameter :: call_chemistry = 1 - integer, parameter :: num_moist=3, num_chem=20, num_emis_seas=5, num_emis_dust=5 - - integer, parameter :: DUST_OPT_FENGSHA = 5 + integer, parameter :: num_moist=2, num_chem=20, num_emis_seas=5, num_emis_dust=5 ! -- hydrometeors integer, parameter :: p_qv=1 @@ -52,41 +53,19 @@ module rrfs_smoke_config integer :: numgas = 0 !-- tracers - integer, parameter :: p_so2=1 - integer, parameter :: p_sulf=2 - integer, parameter :: p_dms=3 - integer, parameter :: p_msa=4 - integer, parameter :: p_p25=5, p_smoke=5 - integer, parameter :: p_bc1=6 - integer, parameter :: p_bc2=7 - integer, parameter :: p_oc1=8 - integer, parameter :: p_oc2=9 - integer, parameter :: p_dust_1=10 - integer, parameter :: p_dust_2=11 - integer, parameter :: p_dust_3=12 - integer, parameter :: p_dust_4=13 - integer, parameter :: p_dust_5=14, p_coarse_pm=14 - integer, parameter :: p_seas_1=15 - integer, parameter :: p_seas_2=16 - integer, parameter :: p_seas_3=17 - integer, parameter :: p_seas_4=18 - integer, parameter :: p_seas_5=19 - integer, parameter :: p_p10 =20 - - integer, parameter :: p_edust1=1,p_edust2=2,p_edust3=3,p_edust4=4,p_edust5=5 - integer, parameter :: p_eseas1=1,p_eseas2=2,p_eseas3=3,p_eseas4=4,p_eseas5=5 - - integer :: p_ho=0,p_h2o2=0,p_no3=0 + integer, parameter :: p_smoke=5 + integer, parameter :: p_dust_1=10 + integer, parameter :: p_dust_2=11 + integer, parameter :: p_dust_3=12 + integer, parameter :: p_dust_4=13 + integer, parameter :: p_dust_5=14, p_coarse_pm=14 + integer, parameter :: p_seas_1=15 + integer, parameter :: p_seas_2=16 + integer, parameter :: p_seas_3=17 + integer, parameter :: p_seas_4=18 + integer, parameter :: p_seas_5=19 - ! constants - real(kind=kind_phys), PARAMETER :: airmw = 28.97 - real(kind=kind_phys), PARAMETER :: mw_so2_aer = 64.066 - real(kind=kind_phys), PARAMETER :: mw_so4_aer = 96.066 - real(kind=kind_phys), parameter :: smw = 32.00 - real(kind=kind_phys), parameter :: mwdry = 28. -! d is the molecular weight of dry air (28.966), w/d = 0.62197, and -! (d - w)/d = 0.37803 -! http://atmos.nmsu.edu/education_and_outreach/encyclopedia/humidity.htm + integer, parameter :: p_edust1=1,p_edust2=2,p_edust3=3,p_edust4=4,p_edust5=5 ! -- fire options ! integer, parameter :: num_plume_data = 1 diff --git a/physics/smoke_dust/rrfs_smoke_postpbl.meta b/physics/smoke_dust/rrfs_smoke_postpbl.meta index 50f7afae7..392a6ea6b 100755 --- a/physics/smoke_dust/rrfs_smoke_postpbl.meta +++ b/physics/smoke_dust/rrfs_smoke_postpbl.meta @@ -1,8 +1,7 @@ [ccpp-table-properties] name = rrfs_smoke_postpbl type = scheme - dependencies = dep_dry_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90 - + dependencies = dep_dry_simple_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90,dep_dry_mod_emerson.F90,dep_data_mod.F90 ######################################################################## [ccpp-arg-table] name = rrfs_smoke_postpbl_run diff --git a/physics/smoke_dust/rrfs_smoke_wrapper.F90 b/physics/smoke_dust/rrfs_smoke_wrapper.F90 index c9a6344b8..eb7f83af6 100755 --- a/physics/smoke_dust/rrfs_smoke_wrapper.F90 +++ b/physics/smoke_dust/rrfs_smoke_wrapper.F90 @@ -7,19 +7,20 @@ module rrfs_smoke_wrapper use machine , only : kind_phys use rrfs_smoke_config, only : kemit, dust_opt, seas_opt, do_plumerise, & addsmoke_flag, plumerisefire_frq, wetdep_ls_opt, & - drydep_opt, coarsepm_settling, aero_ind_fdb, & - dbg_opt, smoke_forecast, wetdep_ls_alpha, & + drydep_opt, pm_settling, aero_ind_fdb, ebb_dcycle, & + dbg_opt,smoke_forecast,wetdep_ls_alpha,do_rrfs_sd, & + ebb_dcycle, extended_sd_diags,add_fire_heat_flux, & num_moist, num_chem, num_emis_seas, num_emis_dust, & - DUST_OPT_FENGSHA, p_qv, p_atm_shum, p_atm_cldq, & + p_qv, p_atm_shum, p_atm_cldq, & p_smoke, p_dust_1, p_coarse_pm, epsilc - use dust_data_mod, only : dust_alpha, dust_gamma, dust_moist_opt, & + use dust_data_mod, only : dust_alpha, dust_gamma, dust_moist_opt, & dust_moist_correction, dust_drylimit_factor - use plume_data_mod, only : p_frp_std, p_frp_hr, num_frp_plume use seas_mod, only : gocart_seasalt_driver use dust_fengsha_mod, only : gocart_dust_fengsha_driver - use dep_dry_mod, only : dry_dep_driver + use dep_dry_simple_mod, only : dry_dep_driver_simple + use dep_dry_emerson_mod, only : dry_dep_driver_emerson use module_wetdep_ls, only : wetdep_ls - use module_plumerise1, only : ebu_driver + use module_plumerise, only : ebu_driver use module_add_emiss_burn, only : add_emis_burn use coarsepm_settling_mod, only : coarsepm_settling_driver @@ -27,13 +28,81 @@ module rrfs_smoke_wrapper private - public :: rrfs_smoke_wrapper_run + public :: rrfs_smoke_wrapper_run, rrfs_smoke_wrapper_init + + integer :: plume_wind_eff contains !>\defgroup rrfs_smoke_wrapper rrfs-sd emission driver Module !> \ingroup gsd_chem_group !! This is the rrfs-sd emission driver Module + +!> \section arg_table_rrfs_smoke_wrapper_init Argument Table +!! \htmlinclude rrfs_smoke_wrapper_init.html +!! + subroutine rrfs_smoke_wrapper_init( seas_opt_in, & ! sea salt namelist + drydep_opt_in, pm_settling_in, & ! Dry Dep namelist + wetdep_ls_opt_in,wetdep_ls_alpha_in, & ! Wet dep namelist + rrfs_sd, do_plumerise_in, plumerisefire_frq_in, & ! smoke namelist + plume_wind_eff_in,add_fire_heat_flux_in, & ! smoke namelist + addsmoke_flag_in, ebb_dcycle_in, smoke_forecast_in, & ! Smoke namelist + dust_opt_in, dust_alpha_in, dust_gamma_in, & ! Dust namelist + dust_moist_opt_in, & ! Dust namelist + dust_moist_correction_in, dust_drylimit_factor_in, & ! Dust namelist + aero_ind_fdb_in, & ! Feedback namelist + extended_sd_diags_in,dbg_opt_in, & ! Other namelist + errmsg, errflg ) + + +!>-- Namelist + real(kind_phys), intent(in) :: dust_alpha_in, dust_gamma_in, wetdep_ls_alpha_in + real(kind_phys), intent(in) :: dust_moist_correction_in + real(kind_phys), intent(in) :: dust_drylimit_factor_in + integer, intent(in) :: dust_opt_in,dust_moist_opt_in, wetdep_ls_opt_in, pm_settling_in, seas_opt_in + integer, intent(in) :: drydep_opt_in + logical, intent(in) :: aero_ind_fdb_in,dbg_opt_in, extended_sd_diags_in, add_fire_heat_flux_in + integer, intent(in) :: smoke_forecast_in, plume_wind_eff_in, plumerisefire_frq_in + integer, intent(in) :: addsmoke_flag_in, ebb_dcycle_in + logical, intent(in) :: do_plumerise_in, rrfs_sd + character(len=*),intent(out):: errmsg + integer, intent(out) :: errflg + + errmsg = '' + errflg = 0 + +!>-- Assign namelist values + !>-Dust + dust_alpha = dust_alpha_in + dust_gamma = dust_gamma_in + dust_moist_opt = dust_moist_opt_in + dust_moist_correction = dust_moist_correction_in + dust_drylimit_factor = dust_drylimit_factor_in + dust_opt = dust_opt_in + !>-Sea Salt + seas_opt = seas_opt_in + !>-Dry and wet deposition + drydep_opt = drydep_opt_in + pm_settling = pm_settling_in + wetdep_ls_opt = wetdep_ls_opt_in + wetdep_ls_alpha = wetdep_ls_alpha_in + !>-Smoke + do_rrfs_sd = rrfs_sd + ebb_dcycle = ebb_dcycle_in + do_plumerise = do_plumerise_in + plumerisefire_frq = plumerisefire_frq_in + addsmoke_flag = addsmoke_flag_in + smoke_forecast = smoke_forecast_in + plume_wind_eff = plume_wind_eff_in + add_fire_heat_flux = add_fire_heat_flux_in + !>-Feedback + aero_ind_fdb = aero_ind_fdb_in + !>-Other + extended_sd_diags = extended_sd_diags_in + dbg_opt = dbg_opt_in + + end subroutine rrfs_smoke_wrapper_init + !! \section arg_table_rrfs_smoke_wrapper_run Argument Table !! \htmlinclude rrfs_smoke_wrapper_run.html !! @@ -42,126 +111,107 @@ module rrfs_smoke_wrapper subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, & u10m, v10m, ustar, rlat, rlon, tskin, pb2d, t2m, dpt2m, & pr3d, ph3d,phl3d, prl3d, tk3d, us3d, vs3d, spechum, w, & - nsoil, smc, vegtype, soiltyp, sigmaf, dswsfc, zorl, snow, julian, & - idat, rain_cpl, rainc_cpl, exch, hf2d, g, pi, con_cp, con_rd, con_fv, & - dust12m_in, emi_in, smoke_RRFS, ntrac, qgrs, gq0, chem3d, tile_num, & + nsoil, smc, vegtype_dom, vegtype_frac, soiltyp, nlcat, & + dswsfc, zorl, snow, julian,recmol, & + idat, rain_cpl, rainc_cpl, hf2d, g, pi, con_cp, con_rd, con_fv, & + dust12m_in, emi_ant_in, smoke_RRFS, smoke2d_RRFS, & + ntrac, qgrs, gq0, chem3d, tile_num, & ntsmoke, ntdust, ntcoarsepm, imp_physics, imp_physics_thompson, & - nwfa, nifa, emanoc, emdust, emseas, & - ebb_smoke_hr, frp_hr, frp_std_hr, & - coef_bb, ebu_smoke,fhist, min_fplume, max_fplume, hwp, wetness, & - smoke_ext, dust_ext, ndvel, ddvel_inout,rrfs_sd, & - dust_moist_opt_in, dust_moist_correction_in, dust_drylimit_factor_in, & - dust_alpha_in, dust_gamma_in, fire_in, & - seas_opt_in, dust_opt_in, drydep_opt_in, coarsepm_settling_in, & - do_plumerise_in, plumerisefire_frq_in, addsmoke_flag_in, & - wetdep_ls_opt_in,wetdep_ls_alpha_in, fire_heat_flux_out, & - frac_grid_burned_out, & - smoke_forecast_in, aero_ind_fdb_in,dbg_opt_in,errmsg,errflg) - + nwfa, nifa, emanoc, emdust, emseas, drydep_flux_out, wetdpr, & + ebb_smoke_in, frp_output, coef_bb, ebu_smoke,fhist,min_fplume, & + max_fplume, hwp, hwp_ave, wetness, ndvel, ddvel_inout,fire_in, & + fire_heat_flux_out, frac_grid_burned_out, kpbl,oro, & + errmsg,errflg ) + implicit none integer, intent(in) :: im,kte,kme,ktau,nsoil,tile_num,jdate(8),idat(8) - integer, intent(in) :: ntrac, ntsmoke, ntdust, ntcoarsepm, ndvel + integer, intent(in) :: ntrac, ntsmoke, ntdust, ntcoarsepm, ndvel, nlcat real(kind_phys),intent(in) :: dt, julian, g, pi, con_cp, con_rd, con_fv - logical, intent(in) :: aero_ind_fdb_in,dbg_opt_in - integer, intent(in) :: smoke_forecast_in integer, parameter :: ids=1,jds=1,jde=1, kds=1 integer, parameter :: ims=1,jms=1,jme=1, kms=1 integer, parameter :: its=1,jts=1,jte=1, kts=1 - integer, dimension(:), intent(in) :: land, vegtype, soiltyp - real(kind_phys), dimension(:,:), intent(in) :: smc - real(kind_phys), dimension(:,:,:), intent(in) :: dust12m_in - real(kind_phys), dimension(:,:,:), intent(in) :: smoke_RRFS - real(kind_phys), dimension(:,:), intent(in) :: emi_in - real(kind_phys), dimension(:), intent(in) :: u10m, v10m, ustar, dswsfc, & - garea, rlat,rlon, tskin, pb2d, sigmaf, zorl, snow, & - rain_cpl, rainc_cpl, hf2d, t2m, dpt2m - real(kind_phys), dimension(:,:), intent(in) :: ph3d, pr3d - real(kind_phys), dimension(:,:), intent(in) :: phl3d, prl3d, tk3d, & - us3d, vs3d, spechum, exch, w + integer, dimension(:), intent(in) :: land, vegtype_dom, soiltyp + real(kind_phys), dimension(:,:), intent(in) :: smc + real(kind_phys), dimension(:,:,:), intent(in) :: dust12m_in + real(kind_phys), dimension(:,:,:), intent(in) :: smoke_RRFS + real(kind_phys), dimension(:,:), intent(in) :: smoke2d_RRFS + real(kind_phys), dimension(:,:), intent(in) :: emi_ant_in + real(kind_phys), dimension(:), intent(in) :: u10m, v10m, ustar, dswsfc, & + recmol, garea, rlat,rlon, tskin, pb2d, zorl, snow, & + rain_cpl, rainc_cpl, hf2d, t2m, dpt2m + real(kind_phys), dimension(:,:), intent(in) :: vegtype_frac + real(kind_phys), dimension(:,:), intent(in) :: ph3d, pr3d + real(kind_phys), dimension(:,:), intent(in) :: phl3d, prl3d, tk3d, us3d, vs3d, spechum, w real(kind_phys), dimension(:,:,:), intent(inout) :: qgrs, gq0 real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d - real(kind_phys), dimension(:), intent(inout) :: emdust, emseas, emanoc - real(kind_phys), dimension(:), intent(inout) :: ebb_smoke_hr, frp_hr, frp_std_hr - real(kind_phys), dimension(:), intent(inout) :: coef_bb, fhist - real(kind_phys), dimension(:,:), intent(inout) :: ebu_smoke - real(kind_phys), dimension(:,:), intent(inout) :: fire_in - real(kind_phys), dimension(:), intent(out) :: fire_heat_flux_out - real(kind_phys), dimension(:), intent(out) :: frac_grid_burned_out - real(kind_phys), dimension(:), intent(inout) :: max_fplume, min_fplume - real(kind_phys), dimension(:), intent( out) :: hwp - real(kind_phys), dimension(:,:), intent(out) :: smoke_ext, dust_ext - real(kind_phys), dimension(:,:), intent(inout) :: nwfa, nifa - real(kind_phys), dimension(:,:), intent(inout) :: ddvel_inout - real(kind_phys), dimension(:), intent(in) :: wetness - real(kind_phys), intent(in) :: dust_alpha_in, dust_gamma_in, wetdep_ls_alpha_in - real(kind_phys), intent(in) :: dust_moist_correction_in - real(kind_phys), intent(in) :: dust_drylimit_factor_in - integer, intent(in) :: dust_moist_opt_in - integer, intent(in) :: imp_physics, imp_physics_thompson - integer, intent(in) :: seas_opt_in, dust_opt_in, drydep_opt_in, & - coarsepm_settling_in, plumerisefire_frq_in, & - addsmoke_flag_in, wetdep_ls_opt_in - logical, intent(in ) :: do_plumerise_in, rrfs_sd - character(len=*), intent(out) :: errmsg - integer, intent(out) :: errflg - + real(kind_phys), dimension(:), intent(inout) :: emdust, emseas, emanoc + real(kind_phys), dimension(:), intent(inout) :: ebb_smoke_in,coef_bb, frp_output, fhist + real(kind_phys), dimension(:,:), intent(inout) :: ebu_smoke + real(kind_phys), dimension(:,:), intent(inout) :: fire_in + real(kind_phys), dimension(:), intent(out) :: fire_heat_flux_out, frac_grid_burned_out + real(kind_phys), dimension(:), intent(inout) :: max_fplume, min_fplume + real(kind_phys), dimension(:), intent( out) :: hwp + real(kind_phys), dimension(:), intent(inout) :: hwp_ave + real(kind_phys), dimension(:,:), intent(inout) :: nwfa, nifa + real(kind_phys), dimension(:,:), intent(inout) :: ddvel_inout + real(kind_phys), dimension(:,:), intent(inout) :: drydep_flux_out + real(kind_phys), dimension(:,:), intent(inout) :: wetdpr + real(kind_phys), dimension(:), intent(in) :: wetness + integer, intent(in) :: imp_physics, imp_physics_thompson + integer, dimension(:), intent(in) :: kpbl + real(kind_phys), dimension(:), intent(in) :: oro + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + +!>-- Local Variables real(kind_phys), dimension(ims:im, kms:kme, jms:jme) :: ebu real(kind_phys), dimension(1:im, 1:kme,jms:jme) :: rri, t_phy, u_phy, v_phy, & - p_phy, z_at_w, dz8w, p8w, t8w, rho_phy, vvel, zmid, exch_h - - real(kind_phys), dimension(ims:im, jms:jme) :: u10, v10, ust, tsk, & - xland, xlat, xlong, dxy, pbl, hfx, rcav, rnav - + p_phy,pi_phy,wind_phy,theta_phy,z_at_w, dz8w, p8w, t8w, & + rho_phy, vvel, zmid + real(kind_phys), dimension(ims:im, jms:jme) :: frp_inst, u10, v10, ust, tsk, & + xland, xlat, xlong, dxy, pbl, hfx, rnav, hwp_local, & + wetdpr_smoke_local, wetdpr_dust_local, wetdpr_coarsepm_local !>- sea salt & chemistry variables real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_moist) :: moist real(kind_phys), dimension(ims:im, kms:kme, jms:jme, 1:num_chem ) :: chem real(kind_phys), dimension(ims:im, 1, jms:jme, 1:num_emis_seas ) :: emis_seas real(kind_phys), dimension(ims:im, jms:jme) :: seashelp - +!>-- indexes, time integer :: ide, ime, ite, kde, julday - + real(kind_phys) :: gmt !>- dust & chemistry variables real(kind_phys), dimension(ims:im, jms:jme) :: ssm, rdrag, uthr, snowh ! fengsha dust - real(kind_phys), dimension(ims:im, jms:jme) :: vegfrac, rmol, swdown, znt, clayf, sandf + real(kind_phys), dimension(ims:im, jms:jme) :: rmol, swdown, znt, clayf, sandf + real(kind_phys), dimension(ims:im, nlcat, jms:jme) :: vegfrac real(kind_phys), dimension(ims:im, nsoil, jms:jme) :: smois real(kind_phys), dimension(ims:im, 1:1, jms:jme, 1:num_emis_dust) :: emis_dust integer, dimension(ims:im, jms:jme) :: isltyp, ivgtyp - !>- plume variables ! -- buffers - real(kind_phys), dimension(ims:im, jms:jme) :: ebu_in - real(kind_phys), dimension(ims:im, jms:jme, num_frp_plume ) :: plume_frp - real(kind_phys), dimension(ims:im, jms:jme ) :: coef_bb_dc, flam_frac, & - fire_hist, peak_hr - real(kind_phys), dimension(ims:im,kms:kme,jms:jme ) :: ext3d_smoke, ext3d_dust - integer, dimension(ims:im, jms:jme ) :: min_fplume2, max_fplume2 - logical :: call_fire + real(kind_phys), dimension(ims:im, jms:jme ) :: coef_bb_dc, flam_frac, frp_in, & + fire_hist, peak_hr, lu_nofire, lu_qfire, ebu_in, & + fire_end_hr, hwp_day_avg, kpbl_thetav + integer, dimension(ims:im, jms:jme ) :: min_fplume2, max_fplume2, fire_type + logical :: call_plume, reset_hwp_ave !>- optical variables - real(kind_phys), dimension(ims:im, kms:kme, jms:jme) :: rel_hum - real(kind_phys), dimension(ims:im, jms:jme, ndvel) :: ddvel - + real(kind_phys), dimension(ims:im, jms:jme, ndvel) :: ddvel, settling_flux, drydep_flux_local + real(kind_phys), dimension(ims:im, kms:kme, jms:jme, ndvel) :: vgrav !>-- anthropogentic variables real(kind_phys), dimension(ims:im) :: emis_anoc real(kind_phys), dimension(ims:im, jms:jme, 1) :: sedim - - real(kind_phys) :: gmt - !> -- parameter to caluclate wfa&ifa (m) real(kind_phys), parameter :: mean_diameter1= 4.E-8, sigma1=1.8 real(kind_phys), parameter :: mean_diameter2= 1.E-6, sigma2=1.8 - real(kind_phys), parameter :: kappa_oc = 0.2 - real(kind_phys), parameter :: kappa_dust = 0.04 real(kind_phys) :: fact_wfa, fact_ifa !> -- aerosol density (kg/m3) real(kind_phys), parameter :: density_dust= 2.6e+3, density_sulfate=1.8e+3 real(kind_phys), parameter :: density_oc = 1.4e+3, density_seasalt=2.2e+3 - real(kind_phys), dimension(im) :: daero_emis_wfa, daero_emis_ifa -!>-- local variables +!> -- other real(kind_phys), dimension(im) :: wdgust, snoweq integer :: current_month, current_hour, hour_int real(kind_phys) :: curr_secs @@ -172,21 +222,7 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, errmsg = '' errflg = 0 - if (.not. rrfs_sd) return - -!>-- options to turn on/off sea-salt, dust, plume-rising - seas_opt = seas_opt_in - dust_opt = dust_opt_in - drydep_opt = drydep_opt_in - do_plumerise = do_plumerise_in - plumerisefire_frq = plumerisefire_frq_in - addsmoke_flag = addsmoke_flag_in - smoke_forecast = smoke_forecast_in - aero_ind_fdb = aero_ind_fdb_in - dbg_opt = dbg_opt_in - wetdep_ls_opt = wetdep_ls_opt_in - wetdep_ls_alpha = wetdep_ls_alpha_in - coarsepm_settling = coarsepm_settling_in + if (.not. do_rrfs_sd) return ! -- set domain ide=im @@ -199,19 +235,19 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, emis_seas = 0. emis_dust = 0. peak_hr = 0. + fire_type = 0 + lu_qfire = 0. + lu_nofire = 0. flam_frac = 0. - ext3d_smoke = 0. - ext3d_dust = 0. daero_emis_wfa = 0. daero_emis_ifa = 0. - rcav = 0. rnav = 0. curr_secs = ktau * dt current_month=jdate(2) ! needed for the dust input data current_hour =jdate(5)+1 ! =1 at 00Z - hour_int=ktau*dt/3600. ! hours since the simulation start + hour_int=floor(ktau*dt/3600.) ! hours since the simulation start gmt = real(mod(idat(5)+hour_int,24)) julday = int(julian) @@ -223,70 +259,49 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ! -- compute incremental convective and large-scale rainfall do i=its,ite - rcav(i,1)=max(rainc_cpl(i)*1000. , 0.) ! meter to mm rnav(i,1)=max((rain_cpl(i)-rainc_cpl(i))*1000., 0.) ! meter to mm coef_bb_dc(i,1) = coef_bb(i) fire_hist (i,1) = fhist (i) enddo + ! Is this a reset timestep (00:00 + dt)? + reset_hwp_ave = mod(int(curr_secs-dt),3600) == 0 ! plumerise frequency in minutes set up by the namelist input - call_fire = (do_plumerise .and. (plumerisefire_frq > 0)) - if (call_fire) call_fire = (mod(int(curr_secs), max(1, 60*plumerisefire_frq)) == 0) .or. (ktau == 2) + call_plume = (do_plumerise .and. (plumerisefire_frq > 0)) + if (call_plume) call_plume = (mod(int(curr_secs), max(1, 60*plumerisefire_frq)) == 0) .or. (ktau == 2) !>- get ready for chemistry run call rrfs_smoke_prep( & - current_month, current_hour, gmt, con_rd, con_fv, & + ktau,current_month, current_hour, gmt, con_rd, con_fv, con_cp, & u10m,v10m,ustar,land,garea,rlat,rlon,tskin, & - pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & - nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & - snow,dust12m_in,emi_in,smoke_RRFS, & - hf2d, pb2d, g, pi, hour_int, & + pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,w, & + nsoil,smc,vegtype_dom,soiltyp,nlcat,vegtype_frac,dswsfc,zorl, & + snow,dust12m_in,emi_ant_in,smoke_RRFS,smoke2d_RRFS,coef_bb_dc, & + hf2d, pb2d, g, pi, hour_int, peak_hr, & u10,v10,ust,tsk,xland,xlat,xlong,dxy, & - rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & - t8w,exch_h, & + rri,t_phy,u_phy,v_phy,p_phy,pi_phy,wind_phy,theta_phy, & + rho_phy,dz8w,p8w,t8w,recmol, & z_at_w,vvel,zmid, & ntrac,gq0, & num_chem,num_moist, & ntsmoke, ntdust,ntcoarsepm, & - moist,chem,plume_frp,ebu_in, & - ebb_smoke_hr, frp_hr, frp_std_hr, emis_anoc, & - smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & - snowh,clayf,rdrag,sandf,ssm,uthr,rel_hum, & + moist,chem,ebu_in,kpbl_thetav,ebb_smoke_in, & + fhist,frp_in, hwp_day_avg, fire_end_hr, & + emis_anoc,smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & + snowh,clayf,rdrag,sandf,ssm,uthr,oro, hwp_local, & + t2m,dpt2m,wetness,kpbl, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - -! Make this global, calculate at 1st time step only -!>-- for plumerise -- - - do j=jts,jte - do i=its,ite - peak_hr(i,j)= fire_in(i,10) - enddo - enddo + its,ite, jts,jte, kts,kte ) - IF (ktau==1) THEN - do j=jts,jte - do i=its,ite - if (xlong(i,j)<230.) then - peak_hr(i,j)= 0.0* 3600. ! peak at 24 UTC, fires in Alaska - elseif(xlong(i,j)<245.) then - peak_hr(i,j)= 23.0* 3600. - elseif (xlong(i,j)<260.) then - peak_hr(i,j)= 22.0* 3600. ! peak at 22 UTC, fires in the western US - elseif (xlong(i,j)<275.) then - peak_hr(i,j)= 21.0* 3600. - elseif (xlong(i,j)<290.) then ! peak at 20 UTC, fires in the eastern US - peak_hr(i,j)= 20.0* 3600. - else - peak_hr(i,j)= 19.0* 3600. - endif - enddo - enddo - ENDIF + do j=jts,jte + do i=its,ite + peak_hr(i,j)= fire_in(i,1) + enddo + enddo - IF (ktau==1) THEN + IF (ktau==1) THEN ebu = 0. do j=jts,jte do i=its,ite @@ -296,18 +311,35 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, enddo enddo enddo - ELSE - do k=kts,kte - do i=its,ite - ebu(i,k,1)=ebu_smoke(i,k) - enddo - enddo - ENDIF + ENDIF +!RAR: change this to the fractional LU type; fire_type: 0- no fires, 1- Ag +! or urban fires, 2- prescribed fires in wooded area, 3- wildfires + if (ebb_dcycle==2) then + do j=jts,jte + do i=its,ite + if (ebu_in(i,j)<0.01) then + fire_type(i,j) = 0 + else + ! Permanent wetlands, snow/ice, water, barren tundra + lu_nofire(i,j) = vegfrac(i,11,j) + vegfrac(i,15,j) + vegfrac(i,17,j) + vegfrac(i,20,j) + ! cropland, urban, cropland/natural mosaic, barren and sparsely vegetated + lu_qfire(i,j) = vegfrac(i,12,j) + vegfrac(i,13,j) + vegfrac(i,14,j) + vegfrac(i,16,j) + if (lu_nofire(i,j)>0.95) then + fire_type(i,j) = 0 + else if (lu_qfire(i,j)>0.95) then + fire_type(i,j) = 1 + else + fire_type(i,j) = 3 ! RAR: need to add another criteria for fire_type=2, i.e. prescribed fires + end if + end if + end do + end do + endif !>- compute sea-salt - ! -- compute sea salt (opt=2) - if (seas_opt == 2) then + ! -- compute sea salt (opt=1) + if (seas_opt == 1) then call gocart_seasalt_driver(dt,rri,t_phy, & u_phy,v_phy,chem,rho_phy,dz8w,u10,v10,ust,p8w,tsk, & xland,xlat,xlong,dxy,g,emis_seas,pi, & @@ -318,15 +350,9 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, endif !-- compute dust (opt=5) - if (dust_opt==DUST_OPT_FENGSHA) then - ! Set at compile time in dust_data_mod: - dust_alpha = dust_alpha_in - dust_gamma = dust_gamma_in - dust_moist_opt = dust_moist_opt_in - dust_moist_correction = dust_moist_correction_in - dust_drylimit_factor = dust_drylimit_factor_in + if (dust_opt==5) then call gocart_dust_fengsha_driver(dt,chem,rho_phy,smois,p8w,ssm, & - isltyp,vegfrac,snowh,xland,dxy,g,emis_dust,ust,znt, & + isltyp,snowh,xland,dxy,g,emis_dust,ust,znt, & clayf,sandf,rdrag,uthr, & num_emis_dust,num_chem,nsoil, & ids,ide, jds,jde, kds,kde, & @@ -340,43 +366,57 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !-- /scratch2/BMC/ap-fc/Ravan/rapid-refresh/WRFV3.9/smoke ! Every hour (per namelist) the ebu_driver is called to calculate ebu, but ! the plumerise is controlled by the namelist option of plumerise_flag - if (call_fire) then + if (add_fire_heat_flux) then + do i = its,ite + if ( coef_bb_dc(i,1)*frp_in(i,1) .ge. 1.E7 ) then + fire_heat_flux_out(i) = min(max(0.,0.88*coef_bb_dc(i,1)*frp_in(i,1) / & + 0.55/dxy(i,1)) ,5000.) ! JLS - W m-2 [0 - 10,000] + frac_grid_burned_out(i) = min(max(0., 1.3*0.0006*coef_bb_dc(i,1)*frp_in(i,1)/dxy(i,1) ),1.) + else + fire_heat_flux_out(i) = 0.0 + frac_grid_burned_out(i) = 0.0 + endif + enddo + endif + if (call_plume) then + ! Apply the diurnal cycle coefficient to frp_inst () + do j=jts,jte + do i=its,ite + frp_inst(i,j) = frp_in(i,j)*coef_bb_dc(i,j) + enddo + enddo + call ebu_driver ( & flam_frac,ebu_in,ebu, & - t_phy,moist(:,:,:,p_qv), & - rho_phy,vvel,u_phy,v_phy,p_phy, & + theta_phy,moist(:,:,:,p_qv), & + rho_phy,vvel,u_phy,v_phy,pi_phy,wind_phy, & z_at_w,zmid,g,con_cp,con_rd, & - plume_frp, min_fplume2, max_fplume2, & ! new approach + frp_inst, min_fplume2, max_fplume2, & + plume_wind_eff, & + kpbl_thetav, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte, errmsg, errflg ) if(errflg/=0) return - do i = its,ite - if ( plume_frp(i,1,p_frp_hr) .ge. 1.E7 ) then - fire_heat_flux_out(i) = min(max(0.,0.88*plume_frp(i,1,p_frp_hr)/0.55/dxy(i,1)) ,50000.) ! JLS - W m-2 [0 - 10,000] - frac_grid_burned_out(i) = min(max(0., 1.3*0.0006*plume_frp(i,1,p_frp_hr)/dxy(i,1) ),1.) - else - fire_heat_flux_out(i) = 0.0 - frac_grid_burned_out(i) = 0.0 - endif - enddo end if + ! -- add biomass burning emissions at every timestep if (addsmoke_flag == 1) then - call add_emis_burn(dt,dz8w,rho_phy,rel_hum,chem, & - julday,gmt,xlat,xlong, & - ivgtyp, vegfrac, peak_hr, & ! RAR - curr_secs,ebu, & - coef_bb_dc,fire_hist,ext3d_smoke,ext3d_dust, & - rcav, rnav,swdown,smoke_forecast, & + call add_emis_burn(dt,dz8w,rho_phy,pi, & + chem,julday,gmt,xlat,xlong, & + fire_end_hr, peak_hr,curr_secs, & + coef_bb_dc,fire_hist,hwp_local,hwp_day_avg, & + swdown,ebb_dcycle,ebu_in,ebu,fire_type, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ) endif - !>-- compute coarsepm setting - if (coarsepm_settling == 1) then - call coarsepm_settling_driver(dt,t_phy,rel_hum, & + !>-- compute coarsepm setting if using simple dry dep option and + ! pm_settling is on. This is necessary becasue the simple scheme + ! does not have an explicty settling routine, Emersion (opt=1) does. + if (drydep_opt == 2 .and. pm_settling == 1) then + call coarsepm_settling_driver(dt,t_phy, & chem(:,:,:,p_coarse_pm), & rho_phy,dz8w,p8w,p_phy,sedim, & dxy,g,1, & @@ -384,18 +424,29 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte ) endif - !>-- compute dry deposition + !>-- compute dry deposition, based on Emerson et al., (2020) if (drydep_opt == 1) then - - call dry_dep_driver(rmol,ust,ndvel,ddvel,rel_hum, & + call dry_dep_driver_emerson(rmol,ust,znt,ndvel,ddvel, & + vgrav,chem,dz8w,snowh,t_phy,p_phy,rho_phy,ivgtyp,g,dt, & + pm_settling,drydep_flux_local,settling_flux,dbg_opt, & ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) - + its,ite, jts,jte, kts,kte ) do nv=1,ndvel - do i=its,ite - ddvel_inout(i,nv)=ddvel(i,1,nv) + do i=its,ite + ddvel_inout(i,nv)=ddvel(i,1,nv) + enddo enddo + !>-- compute dry deposition based on simple parameterization (HRRR-Smoke) + elseif (drydep_opt == 2) then + call dry_dep_driver_simple(rmol,ust,ndvel,ddvel, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + do nv=1,ndvel + do i=its,ite + ddvel_inout(i,nv)=ddvel(i,1,nv) + enddo enddo else ddvel_inout(:,:)=0. @@ -403,35 +454,49 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !>- large-scale wet deposition if (wetdep_ls_opt == 1) then - call wetdep_ls(dt,chem,rnav,moist, & - rho_phy,num_chem,num_moist,dz8w,vvel, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & - its,ite, jts,jte, kts,kte) + call wetdep_ls(dt,chem,rnav,moist, & + rho_phy,num_chem,num_moist,ndvel, dz8w,vvel,& + wetdpr_smoke_local, wetdpr_dust_local, & + wetdpr_coarsepm_local, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & + its,ite, jts,jte, kts,kte ) + if ( extended_sd_diags .or. dbg_opt) then + do i = its, ite + wetdpr(i,1) = wetdpr(i,1) + wetdpr_smoke_local (i,1) + wetdpr(i,2) = wetdpr(i,2) + wetdpr_dust_local (i,1) + wetdpr(i,3) = wetdpr(i,3) + wetdpr_coarsepm_local(i,1) + enddo + endif endif +! Smoke emisisons diagnostic do k=kts,kte do i=its,ite ebu_smoke(i,k)=ebu(i,k,1) enddo enddo - !---- diagnostic output of hourly wildfire potential (07/2021) + if (ktau == 1 .or. reset_hwp_ave) then + hwp_ave = 0. + endif hwp = 0. do i=its,ite - wdgust(i)=max(1.68*sqrt(us3d(i,1)**2+vs3d(i,1)**2),3.) - snoweq(i)=max((25.-snow(i))/25.,0.) - hwp(i)=0.237*wdgust(i)**1.11*max(t2m(i)-dpt2m(i),15.)**0.92*((1.-wetness(i))**6.95)*snoweq(i) ! Eric 08/2022 - enddo - -!---- diagnostic output of smoke & dust optical extinction (12/2021) - do k=kts,kte - do i=its,ite - smoke_ext(i,k) = ext3d_smoke(i,k,1) - dust_ext (i,k) = ext3d_dust (i,k,1) - enddo + hwp(i)=hwp_local(i,1) + hwp_ave(i) = hwp_ave(i) + hwp(i)*dt enddo + +!---- diagnostic output of dry deposition & gravitational settling fluxes + if ( drydep_opt == 1 .and. (extended_sd_diags .or. dbg_opt) ) then + do nv = 1, ndvel + do i=its,ite + drydep_flux_out(i,nv) = drydep_flux_out(i,nv) + & + drydep_flux_local(i,1,nv) + & + settling_flux(i,1,nv) + enddo + enddo + endif !------------------------------------- !---- put smoke stuff back into tracer array do k=kts,kte @@ -456,19 +521,18 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, !-- to output for diagnostics do i = 1, im emseas (i) = emis_seas(i,1,1,1)*1.e+9 ! size bin 1 sea salt emission: ug/m2/s + emanoc (i) = emis_anoc (i) ! anthropogenic organic carbon: ug/m2/s emdust (i) = emis_dust(i,1,1,1) + emis_dust(i,1,1,2) + & emis_dust(i,1,1,3) + emis_dust(i,1,1,4) ! dust emission: ug/m2/s - emanoc (i) = emis_anoc (i) ! anthropogenic organic carbon: ug/m2/s coef_bb (i) = coef_bb_dc(i,1) + frp_output (i) = coef_bb_dc(i,1)*frp_in(i,1) fhist (i) = fire_hist (i,1) min_fplume (i) = real(min_fplume2(i,1)) max_fplume (i) = real(max_fplume2(i,1)) - emseas (i) = sandf(i,1) ! sand for dust - emanoc (i) = uthr (i,1) ! u threshold for dust enddo do i = 1, im - fire_in(i,10) = peak_hr(i,1) + fire_in(i,1) = peak_hr(i,1) enddo !-- to provide real aerosol emission for Thompson MP @@ -500,46 +564,51 @@ subroutine rrfs_smoke_wrapper_run(im, kte, kme, ktau, dt, garea, land, jdate, end subroutine rrfs_smoke_wrapper_run - subroutine rrfs_smoke_prep( & - current_month,current_hour,gmt,con_rd,con_fv, & - u10m,v10m,ustar,land,garea,rlat,rlon,ts2d, & - pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w, & - nsoil,smc,vegtype,soiltyp,sigmaf,dswsfc,zorl, & - snow_cpl,dust12m_in,emi_in,smoke_RRFS, & - hf2d, pb2d, g, pi, hour_int, & - u10,v10,ust,tsk,xland,xlat,xlong,dxy, & - rri,t_phy,u_phy,v_phy,p_phy,rho_phy,dz8w,p8w, & - t8w,exch_h, & - z_at_w,vvel,zmid, & - ntrac,gq0, & - num_chem, num_moist, & - ntsmoke, ntdust, ntcoarsepm, & - moist,chem,plume_frp,ebu_in, & - ebb_smoke_hr, frp_hr, frp_std_hr, emis_anoc, & - smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & - snowh,clayf,rdrag,sandf,ssm,uthr,rel_hum, & - ids,ide, jds,jde, kds,kde, & - ims,ime, jms,jme, kms,kme, & + subroutine rrfs_smoke_prep( & + ktau,current_month,current_hour,gmt,con_rd,con_fv,con_cp, & + u10m,v10m,ustar,land,garea,rlat,rlon,ts2d, & + pr3d,ph3d,phl3d,tk3d,prl3d,us3d,vs3d,spechum,w, & + nsoil,smc,vegtype_dom,soiltyp,nlcat,vegtype_frac,dswsfc,zorl, & + snow_cpl,dust12m_in,emi_ant_in,smoke_RRFS,smoke2d_RRFS,coef_bb_dc, & + hf2d, pb2d, g, pi, hour_int, peak_hr, & + u10,v10,ust,tsk,xland,xlat,xlong,dxy, & + rri,t_phy,u_phy,v_phy,p_phy,pi_phy,wind_phy,theta_phy, & + rho_phy,dz8w,p8w,t8w,recmol, & + z_at_w,vvel,zmid, & + ntrac,gq0, & + num_chem, num_moist, & + ntsmoke, ntdust, ntcoarsepm, & + moist,chem,ebu_in,kpbl_thetav,ebb_smoke_in, & + fhist,frp_in, hwp_day_avg, fire_end_hr, & + emis_anoc,smois,ivgtyp,isltyp,vegfrac,rmol,swdown,znt,hfx,pbl, & + snowh,clayf,rdrag,sandf,ssm,uthr,oro,hwp_local, & + t2m,dpt2m,wetness,kpbl, & + ids,ide, jds,jde, kds,kde, & + ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte) !Chem input configuration - integer, intent(in) :: current_month, current_hour, hour_int + integer, intent(in) :: current_month, current_hour, hour_int, nlcat !FV3 input variables - integer, intent(in) :: nsoil - integer, dimension(ims:ime), intent(in) :: land, vegtype, soiltyp + integer, intent(in) :: nsoil, ktau + integer, dimension(ims:ime), intent(in) :: land, vegtype_dom, soiltyp, kpbl integer, intent(in) :: ntrac - real(kind=kind_phys), intent(in) :: g, pi, gmt, con_rd, con_fv + real(kind=kind_phys), intent(in) :: g, pi, gmt, con_rd, con_fv, con_cp real(kind=kind_phys), dimension(ims:ime), intent(in) :: & - u10m, v10m, ustar, garea, rlat, rlon, ts2d, sigmaf, dswsfc, & - zorl, snow_cpl, pb2d, hf2d + u10m, v10m, ustar, garea, rlat, rlon, ts2d, dswsfc, & + zorl, snow_cpl, pb2d, hf2d, oro, t2m, dpt2m, wetness, recmol + real(kind=kind_phys), dimension(ims:ime, nlcat), intent(in) :: vegtype_frac real(kind=kind_phys), dimension(ims:ime, nsoil), intent(in) :: smc real(kind=kind_phys), dimension(ims:ime, 12, 5), intent(in) :: dust12m_in - real(kind=kind_phys), dimension(ims:ime, 24, 3), intent(in) :: smoke_RRFS - real(kind=kind_phys), dimension(ims:ime, 1), intent(in) :: emi_in + real(kind=kind_phys), dimension(ims:ime, 24, 2), intent(in) :: smoke_RRFS +! This is a place holder for ebb_dcycle == 2, currently set to hold a single +! value, which is the previous day's average of hwp, frp, ebb, fire_end + real(kind=kind_phys), dimension(ims:ime, 4), intent(in) :: smoke2d_RRFS + real(kind=kind_phys), dimension(ims:ime, 1), intent(in) :: emi_ant_in real(kind=kind_phys), dimension(ims:ime, kms:kme), intent(in) :: pr3d,ph3d real(kind=kind_phys), dimension(ims:ime, kts:kte), intent(in) :: & - phl3d,tk3d,prl3d,us3d,vs3d,spechum,exch,w + phl3d,tk3d,prl3d,us3d,vs3d,spechum,w real(kind=kind_phys), dimension(ims:ime, kts:kte,ntrac), intent(in) :: gq0 @@ -551,53 +620,60 @@ subroutine rrfs_smoke_prep( & real(kind_phys), dimension(ims:ime, jms:jme),intent(out) :: ebu_in - real(kind_phys), dimension(ims:ime, jms:jme, num_frp_plume), intent(out) :: plume_frp integer,dimension(ims:ime, jms:jme), intent(out) :: isltyp, ivgtyp real(kind_phys), dimension(ims:ime, kms:kme, jms:jme), intent(out) :: & rri, t_phy, u_phy, v_phy, p_phy, rho_phy, dz8w, p8w, t8w, vvel, & - zmid, exch_h, rel_hum + zmid, pi_phy, theta_phy, wind_phy real(kind_phys), dimension(ims:ime, jms:jme), intent(out) :: & - u10, v10, ust, tsk, xland, xlat, xlong, dxy, vegfrac, rmol, swdown, znt, & - pbl, hfx, snowh, clayf, rdrag, sandf, ssm, uthr + u10, v10, ust, tsk, xland, xlat, xlong, dxy, rmol, swdown, znt, & + pbl, hfx, snowh, clayf, rdrag, sandf, ssm, uthr, hwp_local + real(kind_phys), dimension(ims:ime, nlcat, jms:jme), intent(out) :: vegfrac real(kind_phys), dimension(ims:ime, kms:kme, jms:jme, num_moist), intent(out) :: moist real(kind_phys), dimension(ims:ime, kms:kme, jms:jme, num_chem), intent(out) :: chem real(kind_phys), dimension(ims:ime, kms:kme, jms:jme), intent(out) :: z_at_w real(kind_phys), dimension(ims:ime, nsoil, jms:jme), intent(out) :: smois - real(kind_phys), dimension(ims:ime), intent(inout) :: ebb_smoke_hr, frp_hr, frp_std_hr - real(kind_phys), dimension(ims:ime), intent(inout) :: emis_anoc - !real(kind_phys), dimension(ims:ime, jms:jme, num_plume_data) :: plume + real(kind_phys), dimension(ims:ime,jms:jme), intent(inout) :: frp_in, fire_end_hr, fhist, coef_bb_dc + real(kind_phys), dimension(ims:ime,jms:jme), intent(inout) :: hwp_day_avg, peak_hr + real(kind_phys), dimension(ims:ime), intent(inout) :: emis_anoc,ebb_smoke_in real(kind_phys), parameter :: conv_frp = 1.e+06_kind_phys ! FRP conversion factor, MW to W - real(kind_phys), parameter :: frpc = 1._kind_phys ! FRP conversion factor (Regional) + real(kind_phys), parameter :: frpc = 1._kind_phys ! FRP conversion factor (Regional) ! -- local variables - integer i,ip,j,k,kp,kk,kkp,nv,l,ll,n + integer i,ip,j,k,k1,kp,kk,kkp,nv,l,ll,n,nl + real(kind_phys) :: SFCWIND,WIND,DELWIND,DZ,wdgust,snoweq,THETA + real(kind_phys), dimension(ims:ime, kms:kme, jms:jme) :: THETAV + real(kind_phys), dimension(ims:ime, jms:jme) :: windgustpot + real(kind_phys), dimension(ims:ime, jms:jme), intent(out) :: kpbl_thetav + real(kind_phys), parameter :: delta_theta4gust = 0.5 + real(kind=kind_phys),parameter :: p1000mb = 100000. ! -- initialize fire emissions - !plume = 0._kind_phys - plume_frp = 0._kind_phys ebu_in = 0._kind_phys - ebb_smoke_hr = 0._kind_phys + ebb_smoke_in = 0._kind_phys emis_anoc = 0._kind_phys - frp_hr = 0._kind_phys - frp_std_hr = 0._kind_phys + frp_in = 0._kind_phys + hwp_day_avg = 0._kind_phys + fire_end_hr = 0._kind_phys ! -- initialize output arrays isltyp = 0._kind_phys ivgtyp = 0._kind_phys rri = 0._kind_phys t_phy = 0._kind_phys + theta_phy = 0._kind_phys u_phy = 0._kind_phys v_phy = 0._kind_phys + wind_phy = 0._kind_phys p_phy = 0._kind_phys + pi_phy = 0._kind_phys rho_phy = 0._kind_phys dz8w = 0._kind_phys p8w = 0._kind_phys t8w = 0._kind_phys vvel = 0._kind_phys zmid = 0._kind_phys - exch_h = 0._kind_phys u10 = 0._kind_phys v10 = 0._kind_phys ust = 0._kind_phys @@ -621,7 +697,6 @@ subroutine rrfs_smoke_prep( & moist = 0._kind_phys chem = 0._kind_phys z_at_w = 0._kind_phys - rel_hum = 0._kind_phys do i=its,ite u10 (i,1)=u10m (i) @@ -642,12 +717,14 @@ subroutine rrfs_smoke_prep( & sandf(i,1)=dust12m_in(i,current_month,3) ssm (i,1)=dust12m_in(i,current_month,4) uthr (i,1)=dust12m_in(i,current_month,5) - ivgtyp (i,1)=vegtype(i) + ivgtyp (i,1)=vegtype_dom (i) isltyp (i,1)=soiltyp(i) - vegfrac(i,1)=sigmaf (i) + do nl = 1,nlcat + vegfrac(i,nl,1)=vegtype_frac (i,nl) + enddo + rmol (i,1)=recmol (i) enddo - rmol=0. do k=1,nsoil do j=jts,jte @@ -690,38 +767,28 @@ subroutine rrfs_smoke_prep( & p_phy(i,k,j)=prl3d(i,kkp) u_phy(i,k,j)=us3d(i,kkp) v_phy(i,k,j)=vs3d(i,kkp) - rho_phy(i,k,j)=p_phy(i,k,j)/(con_rd*t_phy(i,k,j)*(1.+con_fv*spechum(i,kkp))) + pi_phy(i,k,j) = con_cp*(p_phy(i,k,j)/p1000mb)**(con_rd/con_cp) + theta_phy(i,k,j) = t_phy(i,k,j)/pi_phy(i,k,j)*con_cp + wind_phy(i,k,j) = sqrt(u_phy(i,k,j)**2 + v_phy(i,k,j)**2) + ! from mp_thompson.F90 ; rho = con_eps*prsl/(con_rd*tgrs*(qv+con_eps)) + ! from mynnd + rho_phy(i,k,j)=p_phy(i,k,j)/(con_rd*t_phy(i,k,j)) !*(1.+con_fv*spechum(i,kkp))) rri(i,k,j)=1./rho_phy(i,k,j) vvel(i,k,j)=-w(i,kkp)*rri(i,k,j)/g moist(i,k,j,:)=0. moist(i,k,j,1)=gq0(i,kkp,p_atm_shum) if (t_phy(i,k,j) > 265.) then moist(i,k,j,2)=gq0(i,kkp,p_atm_cldq) - moist(i,k,j,3)=0. if (moist(i,k,j,2) < 1.e-8) moist(i,k,j,2)=0. else moist(i,k,j,2)=0. - moist(i,k,j,3)=gq0(i,kkp,p_atm_cldq) - if(moist(i,k,j,3) < 1.e-8)moist(i,k,j,3)=0. endif - !rel_hum(i,k,j) = min(0.95,spechum(i,kkp)) - rel_hum(i,k,j) = min(0.95, moist(i,k,j,1) / & - (3.80*exp(17.27*(t_phy(i,k,j)-273.)/ & - (t_phy(i,k,j)-36.))/(.01*p_phy(i,k,j)))) - rel_hum(i,k,j) = max(0.1,rel_hum(i,k,j)) !-- zmid(i,k,j)=phl3d(i,kkp)/g enddo enddo enddo - ! -- the imported atmospheric heat diffusivity is only available up to kte-1 - do k=kts,kte-1 - do i=its,ite - exch_h(i,k,1)=exch(i,k) - enddo - enddo - do j=jts,jte do k=2,kte do i=its,ite @@ -739,24 +806,110 @@ subroutine rrfs_smoke_prep( & ! -- anthropogenic organic carbon do i=its,ite - emis_anoc(i) = emi_in(i,1) + emis_anoc(i) = emi_ant_in(i,1) enddo - if (hour_int<24) then - do j=jts,jte - do i=its,ite - ebb_smoke_hr(i) = smoke_RRFS(i,hour_int+1,1) ! smoke - frp_hr (i) = smoke_RRFS(i,hour_int+1,2) ! frp - frp_std_hr (i) = smoke_RRFS(i,hour_int+1,3) ! std frp - ebu_in (i,j) = ebb_smoke_hr(i) - plume_frp(i,j,p_frp_hr ) = conv_frp* frp_hr (i) - plume_frp(i,j,p_frp_std) = conv_frp* frp_std_hr (i) - enddo - enddo +!---- Calculate PBLH and K-PBL based on virtual potential temperature profile +!---- First calculate THETAV + do j = jts,jte + do i = its,ite + do k = kts,kte + THETA = t_phy(i,k,j) * (1.E5/p_phy(i,k,j))**0.286 + THETAV(i,k,j) = THETA * (1. + 0.61 * (moist(i,k,j,p_qv))) + enddo + enddo + enddo +!---- Now use the UPP code to deterimine the height and level + do i = its, ite + do j = jts, jte + if ( THETAV(i,kts+1,j) .lt. ( THETAV(i,kts,j) + delta_theta4gust) ) then + do k = kts+1, kte + k1 = k +!--- give theta-v at the sfc a 0.5K boost in the PBLH definition + if ( THETAV(i,kts+k-1,j) .gt. ( THETAV(i,kts,j) + delta_theta4gust) ) then + exit + endif + enddo + kpbl_thetav(i,j) = k1 + else + kpbl_thetav(i,j) = kts + 1 + endif + enddo + enddo + +!---- Calculate wind gust potential and HWP + do i = its,ite + SFCWIND = sqrt(u10m(i)**2+v10m(i)**2) + windgustpot(i,1) = SFCWIND + if (kpbl_thetav(i,1)+1 .ge. kts+1 ) then + do k=kts+1,int(kpbl_thetav(i,1))+1 + WIND = sqrt(us3d(i,k)**2+vs3d(i,k)**2) + DELWIND = WIND - SFCWIND + DZ = zmid(i,k,1) - oro(i) + DELWIND = DELWIND*(1.0-MIN(0.5,DZ/2000.)) + windgustpot(i,1) = max(windgustpot(i,1),SFCWIND+DELWIND) + enddo + endif + enddo + hwp_local = 0. + do i=its,ite + wdgust=max(windgustpot(i,1),3.) + snoweq=max((25.-snow_cpl(i))/25.,0.) + hwp_local(i,1)=0.177*wdgust**0.97*max(t2m(i)-dpt2m(i),15.)**1.03*((1.-wetness(i))**0.4)*snoweq ! Eric update 11/2023 + enddo +! Set paramters for ebb_dcycle option + if (ebb_dcycle == 1 ) then + if (hour_int .le. 24) then + do j=jts,jte + do i=its,ite + + ebu_in (i,j) = smoke_RRFS(i,hour_int+1,1) ! smoke + frp_in (i,j) = smoke_RRFS(i,hour_int+1,2)*conv_frp ! frp + fire_end_hr(i,j) = 0.0 + hwp_day_avg(i,j) = 0.0 + ebb_smoke_in (i) = ebu_in(i,j) + enddo + enddo + endif endif + ! RAR: here we need to initialize various arrays in order to apply HWP to + ! diurnal cycle + ! if ebb_dcycle/=2 then those arrays=0, we need to read in temporal + if (ebb_dcycle == 2) then + do i=its, ite + do j=jts, jte + ebu_in (i,j) = smoke2d_RRFS(i,1)!/86400. + frp_in (i,j) = smoke2d_RRFS(i,2)*conv_frp + fire_end_hr (i,j) = smoke2d_RRFS(i,3) + hwp_day_avg (i,j) = smoke2d_RRFS(i,4) + ebb_smoke_in(i ) = ebu_in(i,j) + enddo + enddo + end if - ! We will add a namelist variable, real :: flam_frac_global + if (ktau==1) then + do j=jts,jte + do i=its,ite + fhist (i,j) = 1. + coef_bb_dc (i,j) = 1. + if (xlong(i,j)<230.) then + peak_hr(i,j)= 0.0* 3600. ! peak at 24 UTC, fires in Alaska + elseif(xlong(i,j)<245.) then + peak_hr(i,j)= 23.0* 3600. + elseif (xlong(i,j)<260.) then + peak_hr(i,j)= 22.0* 3600. ! peak at 22 UTC, fires in the western US + elseif (xlong(i,j)<275.) then + peak_hr(i,j)= 21.0* 3600. + elseif (xlong(i,j)<290.) then ! peak at 20 UTC, fires in the eastern US + peak_hr(i,j)= 20.0* 3600. + else + peak_hr(i,j)= 19.0* 3600. + endif + enddo + enddo + endif + ! We will add a namelist variable, real :: flam_frac_global do k=kms,kte do i=ims,ime chem(i,k,jts,p_smoke )=max(epsilc,gq0(i,k,ntsmoke )) @@ -765,9 +918,8 @@ subroutine rrfs_smoke_prep( & enddo enddo - - end subroutine rrfs_smoke_prep + !> @} end module rrfs_smoke_wrapper diff --git a/physics/smoke_dust/rrfs_smoke_wrapper.meta b/physics/smoke_dust/rrfs_smoke_wrapper.meta index 7b22b9799..393c5d3d8 100755 --- a/physics/smoke_dust/rrfs_smoke_wrapper.meta +++ b/physics/smoke_dust/rrfs_smoke_wrapper.meta @@ -1,9 +1,191 @@ [ccpp-table-properties] name = rrfs_smoke_wrapper type = scheme - dependencies = dep_dry_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise1.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90,coarsepm_settling_mod.F90 + dependencies = dep_dry_simple_mod.F90,module_wetdep_ls.F90,dust_data_mod.F90,dust_fengsha_mod.F90,module_add_emiss_burn.F90,module_plumerise.F90,module_smoke_plumerise.F90,module_zero_plumegen_coms.F90,plume_data_mod.F90,rrfs_smoke_config.F90,seas_data_mod.F90,seas_mod.F90,seas_ngac_mod.F90,coarsepm_settling_mod.F90, dep_dry_mod_emerson.F90,dep_data_mod.F90 ######################################################################## +[ccpp-arg-table] + name = rrfs_smoke_wrapper_init + type = scheme +[seas_opt_in] + standard_name = control_for_smoke_sea_salt + long_name = rrfs smoke sea salt emission option + units = index + dimensions = () + type = integer + intent = in +[drydep_opt_in] + standard_name = control_for_smoke_dry_deposition + long_name = rrfs smoke dry deposition option + units = index + dimensions = () + type = integer + intent = in +[pm_settling_in] + standard_name = control_for_smoke_pm_settling + long_name = rrfs smoke pm settling option + units = index + dimensions = () + type = integer + intent = in +[wetdep_ls_opt_in] + standard_name = control_for_smoke_wet_deposition + long_name = rrfs smoke large scale wet deposition option + units = index + dimensions = () + type = integer + intent = in +[wetdep_ls_alpha_in] + standard_name = alpha_for_ls_wet_depoistion + long_name = alpha paramter for ls wet deposition + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[rrfs_sd] + standard_name = do_smoke_coupling + long_name = flag controlling rrfs_sd collection (default off) + units = flag + dimensions = () + type = logical + intent = in +[add_fire_heat_flux_in] + standard_name = flag_for_fire_heat_flux + long_name = flag to add fire heat flux to LSM + units = flag + dimensions = () + type = logical + intent = in +[do_plumerise_in] + standard_name = do_smoke_plumerise + long_name = rrfs smoke plumerise option + units = index + dimensions = () + type = logical + intent = in +[plumerisefire_frq_in] + standard_name = smoke_plumerise_frequency + long_name = rrfs smoke add smoke option + units = min + dimensions = () + type = integer + intent = in +[plume_wind_eff_in] + standard_name = option_for_wind_effects_on_smoke_plumerise + long_name = wind effect plumerise option + units = index + dimensions = () + type = integer + intent = in +[addsmoke_flag_in] + standard_name = control_for_smoke_biomass_burning_emissions + long_name = rrfs smoke add smoke option + units = index + dimensions = () + type = integer + intent = in +[ebb_dcycle_in] + standard_name = control_for_diurnal_cycle_of_biomass_burning_emissions + long_name = rrfs smoke diurnal cycle option + units = index + dimensions = () + type = integer + intent = in +[smoke_forecast_in] + standard_name = do_smoke_forecast + long_name = index for rrfs smoke forecast + units = index + dimensions = () + type = integer + intent = in +[dust_opt_in] + standard_name = control_for_smoke_dust + long_name = rrfs smoke dust chem option + units = index + dimensions = () + type = integer + intent = in +[dust_alpha_in] + standard_name = alpha_fengsha_dust_scheme + long_name = alpha paramter for fengsha dust scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[dust_gamma_in] + standard_name = gamma_fengsha_dust_scheme + long_name = gamma paramter for fengsha dust scheme + units = none + dimensions = () + type = real + kind = kind_phys + intent = in +[dust_moist_opt_in] + standard_name = control_for_dust_soil_moisture_option + long_name = smoke dust moisture parameterization 1 - fecan 2 - shao + units = index + dimensions = () + type = integer + active = (do_smoke_coupling) + intent = in +[dust_moist_correction_in] + standard_name = dust_moist_correction_fengsha_dust_scheme + long_name = moisture correction term for fengsha dust emission + units = none + dimensions = () + type = real + kind = kind_phys + active = (do_smoke_coupling) + intent = in +[dust_drylimit_factor_in] + standard_name = dust_drylimit_factor_fengsha_dust_scheme + long_name = moisture correction term for drylimit in fengsha dust emission + units = none + dimensions = () + type = real + kind = kind_phys + active = (do_smoke_coupling) + intent = in +[aero_ind_fdb_in] + standard_name = do_smoke_aerosol_indirect_feedback + long_name = flag for rrfs wfa ifa emission + units = flag + dimensions = () + type = logical + intent = in +[extended_sd_diags_in] + standard_name = flag_for_extended_smoke_dust_diagnostics + long_name = flag for extended smoke dust diagnostics + units = flag + dimensions = () + type = logical + intent = in +[dbg_opt_in] + standard_name = do_smoke_debug + long_name = flag for rrfs smoke plumerise debug + units = flag + dimensions = () + type = logical + intent = in +[errmsg] + standard_name = ccpp_error_message + long_name = error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=* + intent = out +[errflg] + standard_name = ccpp_error_code + long_name = error code for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out + +##################################################################### [ccpp-arg-table] name = rrfs_smoke_wrapper_run type = scheme @@ -224,7 +406,7 @@ type = real kind = kind_phys intent = inout -[vegtype] +[vegtype_dom] standard_name = vegetation_type_classification long_name = vegetation type at each grid cell units = index @@ -238,11 +420,18 @@ dimensions = (horizontal_loop_extent) type = integer intent = in -[sigmaf] - standard_name = bounded_vegetation_area_fraction - long_name = areal fractional cover of green vegetation bounded on the bottom +[nlcat] + standard_name = number_of_vegetation_categories + long_name = number of vegetation categories + units = count + dimensions = () + type = integer + intent = in +[vegtype_frac] + standard_name = fraction_of_vegetation_category + long_name = fraction of horizontal grid area occupied by given vegetation category units = frac - dimensions = (horizontal_loop_extent) + dimensions = (horizontal_loop_extent,number_of_vegetation_categories) type = real kind = kind_phys intent = in @@ -278,6 +467,14 @@ type = real kind = kind_phys intent = in +[recmol] + standard_name = reciprocal_of_obukhov_length + long_name = one over obukhov length + units = m-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [idat] standard_name = date_and_time_at_model_initialization_in_iso_order long_name = initialization date and time @@ -301,14 +498,6 @@ type = real kind = kind_phys intent = in -[exch] - standard_name = atmosphere_heat_diffusivity - long_name = diffusivity for heat - units = m2 s-1 - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = in [hf2d] standard_name = instantaneous_surface_upward_sensible_heat_flux long_name = surface upward sensible heat flux valid for current call @@ -365,7 +554,7 @@ type = real kind = kind_phys intent = in -[emi_in] +[emi_ant_in] standard_name = anthropogenic_background_input long_name = anthropogenic background input units = various @@ -377,7 +566,15 @@ standard_name = emission_smoke_RRFS long_name = emission fire RRFS units = various - dimensions = (horizontal_loop_extent,24,3) + dimensions = (horizontal_loop_extent,24,2) + type = real + kind = kind_phys + intent = in +[smoke2d_RRFS] + standard_name = emission_smoke_prvd_RRFS + long_name = emission fire RRFS daily + units = various + dimensions = (horizontal_loop_extent,4) type = real kind = kind_phys intent = in @@ -494,7 +691,7 @@ type = real kind = kind_phys intent = inout -[ebb_smoke_hr] +[ebb_smoke_in] standard_name = surface_smoke_emission long_name = emission of surface smoke units = ug m-2 s-1 @@ -502,7 +699,7 @@ type = real kind = kind_phys intent = inout -[frp_hr] +[frp_output] standard_name = frp_hourly long_name = hourly fire radiative power units = MW @@ -510,14 +707,6 @@ type = real kind = kind_phys intent = inout -[frp_std_hr] - standard_name = frp_std_hourly - long_name = hourly stdandard deviation of fire radiative power - units = MW - dimensions = (horizontal_loop_extent) - type = real - kind = kind_phys - intent = inout [coef_bb] standard_name = coef_bb_dc long_name = coef to estimate the fire emission @@ -558,6 +747,22 @@ type = real kind = kind_phys intent = inout +[drydep_flux_out] + standard_name = dry_deposition_flux + long_name = rrfs dry deposition flux + units = ug m-2 + dimensions = (horizontal_loop_extent,number_of_chemical_species_deposited) + type = real + kind = kind_phys + intent = inout +[wetdpr] + standard_name = mp_wet_deposition_smoke_dust + long_name = large scale wet deposition of smoke and dust + units = kg kg-1 + dimensions = (horizontal_loop_extent,number_of_chemical_species_vertically_mixed) + type = real + kind = kind_phys + intent = inout [hwp] standard_name = hourly_wildfire_potential long_name = rrfs hourly fire weather potential @@ -566,6 +771,14 @@ type = real kind = kind_phys intent = out +[hwp_ave] + standard_name = hourly_wildfire_potential_average + long_name = rrfs hourly fire weather potential average + units = none + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout [wetness] standard_name = normalized_soil_wetness_for_land_surface_model long_name = normalized soil wetness @@ -574,22 +787,6 @@ type = real kind = kind_phys intent = in -[smoke_ext] - standard_name = extinction_coefficient_in_air_due_to_smoke - long_name = extinction coefficient in air due to smoke - units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out -[dust_ext] - standard_name = extinction_coefficient_in_air_due_to_dust - long_name = extinction coefficient in air due to dust - units = various - dimensions = (horizontal_loop_extent,vertical_layer_dimension) - type = real - kind = kind_phys - intent = out [ndvel] standard_name = number_of_chemical_species_deposited long_name = number of chemical pbl deposited @@ -605,55 +802,6 @@ type = real kind = kind_phys intent = inout -[rrfs_sd] - standard_name = do_smoke_coupling - long_name = flag controlling rrfs_sd collection (default off) - units = flag - dimensions = () - type = logical - intent = in -[dust_moist_opt_in] - standard_name = control_for_dust_soil_moisture_option - long_name = smoke dust moisture parameterization 1 - fecan 2 - shao - units = index - dimensions = () - type = integer - active = (do_smoke_coupling) - intent = in -[dust_moist_correction_in] - standard_name = dust_moist_correction_fengsha_dust_scheme - long_name = moisture correction term for fengsha dust emission - units = none - dimensions = () - type = real - kind = kind_phys - active = (do_smoke_coupling) - intent = in -[dust_drylimit_factor_in] - standard_name = dust_drylimit_factor_fengsha_dust_scheme - long_name = moisture correction term for drylimit in fengsha dust emission - units = none - dimensions = () - type = real - kind = kind_phys - active = (do_smoke_coupling) - intent = in -[dust_alpha_in] - standard_name = alpha_fengsha_dust_scheme - long_name = alpha paramter for fengsha dust scheme - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[dust_gamma_in] - standard_name = gamma_fengsha_dust_scheme - long_name = gamma paramter for fengsha dust scheme - units = none - dimensions = () - type = real - kind = kind_phys - intent = in [fire_in] standard_name = smoke_fire_auxiliary_input long_name = smoke fire auxiliary input variables @@ -662,84 +810,6 @@ type = real kind = kind_phys intent = inout -[seas_opt_in] - standard_name = control_for_smoke_sea_salt - long_name = rrfs smoke sea salt emission option - units = index - dimensions = () - type = integer - intent = in -[dust_opt_in] - standard_name = control_for_smoke_dust - long_name = rrfs smoke dust chem option - units = index - dimensions = () - type = integer - intent = in -[drydep_opt_in] - standard_name = control_for_smoke_dry_deposition - long_name = rrfs smoke dry deposition option - units = index - dimensions = () - type = integer - intent = in -[coarsepm_settling_in] - standard_name = control_for_smoke_coarsepm_settling - long_name = rrfs smoke coarsepm settling option - units = index - dimensions = () - type = integer - intent = in -[wetdep_ls_opt_in] - standard_name = control_for_smoke_wet_deposition - long_name = rrfs smoke large scale wet deposition option - units = index - dimensions = () - type = integer - intent = in -[wetdep_ls_alpha_in] - standard_name = alpha_for_ls_wet_depoistion - long_name = alpha paramter for ls wet deposition - units = none - dimensions = () - type = real - kind = kind_phys - intent = in -[do_plumerise_in] - standard_name = do_smoke_plumerise - long_name = rrfs smoke plumerise option - units = index - dimensions = () - type = logical - intent = in -[plumerisefire_frq_in] - standard_name = smoke_plumerise_frequency - long_name = rrfs smoke add smoke option - units = min - dimensions = () - type = integer - intent = in -[addsmoke_flag_in] - standard_name = control_for_smoke_biomass_burning_emissions - long_name = rrfs smoke add smoke option - units = index - dimensions = () - type = integer - intent = in -[smoke_forecast_in] - standard_name = do_smoke_forecast - long_name = index for rrfs smoke forecast - units = index - dimensions = () - type = integer - intent = in -[aero_ind_fdb_in] - standard_name = do_smoke_aerosol_indirect_feedback - long_name = flag for rrfs wfa ifa emission - units = flag - dimensions = () - type = logical - intent = in [fire_heat_flux_out] standard_name = surface_fire_heat_flux long_name = heat flux of fire at the surface @@ -756,12 +826,20 @@ type = real kind = kind_phys intent = out -[dbg_opt_in] - standard_name = do_smoke_debug - long_name = flag for rrfs smoke plumerise debug - units = flag - dimensions = () - type = logical +[kpbl] + standard_name = vertical_index_at_top_of_atmosphere_boundary_layer + long_name = PBL top model level index + units = index + dimensions = (horizontal_loop_extent) + type = integer + intent = in +[oro] + standard_name = height_above_mean_sea_level + long_name = height_above_mean_sea_level + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys intent = in [errmsg] standard_name = ccpp_error_message diff --git a/physics/smoke_dust/seas_mod.F90 b/physics/smoke_dust/seas_mod.F90 index 1d18046ad..e5e63e909 100755 --- a/physics/smoke_dust/seas_mod.F90 +++ b/physics/smoke_dust/seas_mod.F90 @@ -185,7 +185,6 @@ subroutine gocart_seasalt_driver(dt,alt,t_phy,u_phy, & chem(i,kts,j,p_seas_3) = chem(i,kts,j,p_seas_3) + tc(3)*converi chem(i,kts,j,p_seas_4) = chem(i,kts,j,p_seas_4) + tc(4)*converi chem(i,kts,j,p_seas_5) = chem(i,kts,j,p_seas_5) + tc(5)*converi - !print*,'hli tc(2),chem(i,kts,j,p_seas_2)',tc(2),chem(i,kts,j,p_seas_2) ! for output diagnostics emis_seas(i,1,j,p_eseas1) = bems(1)