diff --git a/physics/module_MYNNSFC_wrapper.F90 b/physics/module_MYNNSFC_wrapper.F90 index 271ca5a24..c8c5c1db4 100644 --- a/physics/module_MYNNSFC_wrapper.F90 +++ b/physics/module_MYNNSFC_wrapper.F90 @@ -57,7 +57,7 @@ end subroutine mynnsfc_wrapper_finalize !###=================================================================== SUBROUTINE mynnsfc_wrapper_run( & & im,levs, & - & itimestep,iter, & + & itimestep,iter,flag_iter, & & flag_init,flag_restart,lsm,lsm_ruc,& & sigmaf,vegtype,shdmax,ivegsrc, & !intent(in) & z0pert,ztpert, & !intent(in) @@ -111,6 +111,15 @@ SUBROUTINE mynnsfc_wrapper_run( & ! & EP_2 => con_eps ! USE module_sf_mynn, only : SFCLAY_mynn +!tgs - info on iterations: +! flag_iter- logical, execution or not (im) +! when iter = 1, flag_iter = .true. for all grids im ! +! when iter = 2, flag_iter = .true. when wind < 2 im ! +! for both land and ocean (when nstf_name1 > 0) im ! +! flag_guess-logical, .true.= guess step to get CD et al im ! +! when iter = 1, flag_guess = .true. when wind < 2 im ! +! when iter = 2, flag_guess = .false. for all grids im ! + !------------------------------------------------------------------- implicit none @@ -141,6 +150,7 @@ SUBROUTINE mynnsfc_wrapper_run( & integer, intent(in) :: im, levs integer, intent(in) :: iter, itimestep, lsm, lsm_ruc + logical, dimension(:), intent(in) :: flag_iter logical, intent(in) :: flag_init,flag_restart,lprnt integer, intent(in) :: ivegsrc integer, intent(in) :: sfc_z0_type ! option for calculating surface roughness length over ocean @@ -194,7 +204,7 @@ SUBROUTINE mynnsfc_wrapper_run( & real, dimension(im) :: & & hfx, znt, psim, psih, & & chs, ck, cd, mavail, xland, GZ1OZ0, & - & cpm, qgh, qfx, qsfc_ruc, snowh_wat + & cpm, qgh, qfx, snowh_wat real(kind=kind_phys), dimension(im,levs) :: & & pattern_spp_pbl, dz, th, qv @@ -249,10 +259,9 @@ SUBROUTINE mynnsfc_wrapper_run( & where (icy) znt_ice=znt_ice*0.01 ! qsfc ruc - qsfc_ruc = 0.0 if (lsm==lsm_ruc) then - where (dry) qsfc_ruc = qsfc_lnd_ruc - where (icy) qsfc_ruc = qsfc_ice_ruc + where (dry) qsfc_lnd = qsfc_lnd_ruc/(1.+qsfc_lnd_ruc) ! spec. hum + where (icy) qsfc_ice = qsfc_ice_ruc/(1.+qsfc_ice_ruc) ! spec. hum. end if ! if (lprnt) then @@ -291,12 +300,12 @@ SUBROUTINE mynnsfc_wrapper_run( & CP=cp,G=g,ROVCP=rcp,R=r_d,XLV=xlv, & SVP1=svp1,SVP2=svp2,SVP3=svp3,SVPT0=svpt0, & EP1=ep_1,EP2=ep_2,KARMAN=karman, & - ISFFLX=isfflx,isftcflx=isftcflx,LSM=lsm, & + ISFFLX=isfflx,isftcflx=isftcflx,LSM=lsm,LSM_RUC=lsm_ruc, & iz0tlnd=iz0tlnd,psi_opt=psi_opt, & & sigmaf=sigmaf,vegtype=vegtype,shdmax=shdmax,ivegsrc=ivegsrc, & !intent(in) & z0pert=z0pert,ztpert=ztpert, & !intent(in) & redrag=redrag,sfc_z0_type=sfc_z0_type, & !intent(in) - itimestep=itimestep,iter=iter, & + itimestep=itimestep,iter=iter,flag_iter=flag_iter, & wet=wet, dry=dry, icy=icy, & !intent(in) tskin_wat=tskin_wat, tskin_lnd=tskin_lnd, tskin_ice=tskin_ice, & !intent(in) tsurf_wat=tsurf_wat, tsurf_lnd=tsurf_lnd, tsurf_ice=tsurf_ice, & !intent(in) @@ -318,7 +327,7 @@ SUBROUTINE mynnsfc_wrapper_run( & ZNT=znt,USTM=ustm,ZOL=zol,MOL=mol,RMOL=rmol, & psim=psim,psih=psih, & HFLX=hflx,HFX=hfx,QFLX=qflx,QFX=qfx,LH=lh,FLHC=flhc,FLQC=flqc, & - QGH=qgh,QSFC=qsfc,QSFC_RUC=qsfc_ruc, & + QGH=qgh,QSFC=qsfc, & U10=u10,V10=v10,TH2=th2,T2=t2,Q2=q2, & GZ1OZ0=GZ1OZ0,WSPD=wspd,wstar=wstar, & spp_pbl=spp_pbl,pattern_spp_pbl=pattern_spp_pbl, & diff --git a/physics/module_MYNNSFC_wrapper.meta b/physics/module_MYNNSFC_wrapper.meta index b91a026e3..c6301ec21 100644 --- a/physics/module_MYNNSFC_wrapper.meta +++ b/physics/module_MYNNSFC_wrapper.meta @@ -69,6 +69,14 @@ type = integer intent = in optional = F +[flag_iter] + standard_name = flag_for_iteration + long_name = flag for iteration + units = flag + dimensions = (horizontal_loop_extent) + type = logical + intent = in + optional = F [flag_init] standard_name = flag_for_first_timestep long_name = flag signaling first time step for time integration loop diff --git a/physics/module_sf_mynn.F90 b/physics/module_sf_mynn.F90 index fc987b627..c98dc2169 100644 --- a/physics/module_sf_mynn.F90 +++ b/physics/module_sf_mynn.F90 @@ -131,11 +131,12 @@ SUBROUTINE SFCLAY_mynn( & PSFCPA,PBLH,MAVAIL,XLAND,DX, & !in CP,G,ROVCP,R,XLV, & !in SVP1,SVP2,SVP3,SVPT0,EP1,EP2,KARMAN, & !in - ISFFLX,isftcflx,lsm,iz0tlnd,psi_opt, & !in + ISFFLX,isftcflx,lsm,lsm_ruc, & !in + iz0tlnd,psi_opt, & !in & sigmaf,vegtype,shdmax,ivegsrc, & !intent(in) & z0pert,ztpert, & !intent(in) & redrag,sfc_z0_type, & !intent(in) - itimestep,iter, & !in + itimestep,iter,flag_iter, & !in wet, dry, icy, & !intent(in) tskin_wat, tskin_lnd, tskin_ice, & !intent(in) tsurf_wat, tsurf_lnd, tsurf_ice, & !intent(in) @@ -157,7 +158,7 @@ SUBROUTINE SFCLAY_mynn( & ZNT,USTM,ZOL,MOL,RMOL, & PSIM,PSIH, & HFLX,HFX,QFLX,QFX,LH,FLHC,FLQC, & - QGH,QSFC,QSFC_RUC, & + QGH,QSFC, & U10,V10,TH2,T2,Q2, & GZ1OZ0,WSPD,WSTAR, & spp_pbl,pattern_spp_pbl, & @@ -268,7 +269,7 @@ SUBROUTINE SFCLAY_mynn( & REAL, INTENT(IN) :: EP1,EP2,KARMAN REAL, INTENT(IN) :: CP,G,ROVCP,R,XLV !,DX !NAMELIST/CONFIGURATION OPTIONS: - INTEGER, INTENT(IN) :: ISFFLX, LSM + INTEGER, INTENT(IN) :: ISFFLX, LSM, LSM_RUC INTEGER, OPTIONAL, INTENT(IN) :: ISFTCFLX, IZ0TLND INTEGER, OPTIONAL, INTENT(IN) :: spp_pbl, psi_opt integer, intent(in) :: ivegsrc @@ -329,13 +330,12 @@ SUBROUTINE SFCLAY_mynn( & WSTAR LOGICAL, DIMENSION( ims:ime ), INTENT(IN) :: & - & wet, dry, icy +& wet, dry, icy, flag_iter REAL, DIMENSION( ims:ime ), INTENT(IN) :: & & tskin_wat, tskin_lnd, tskin_ice, & & tsurf_wat, tsurf_lnd, tsurf_ice, & - & snowh_wat, snowh_lnd, snowh_ice, & - & qsfc_ruc + & snowh_wat, snowh_lnd, snowh_ice REAL, DIMENSION( ims:ime), INTENT(INOUT) :: & & ZNT_wat, ZNT_lnd, ZNT_ice, & @@ -410,25 +410,25 @@ SUBROUTINE SFCLAY_mynn( & UST_LND(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001) UST_ICE(i)=MAX(0.04*SQRT(U1D(i)*U1D(i) + V1D(i)*V1D(i)),0.001) MOL(i)=0.0 - QSFC(i)=QV3D(i,kts)/(1.+QV3D(i,kts)) - QSFC_WAT(i)=QSFC(i) - QSFC_LND(i)=QSFC(i) - QSFC_ICE(i)=QSFC(i) qstar(i)=0.0 QFX(i)=0. HFX(i)=0. QFLX(i)=0. HFLX(i)=0. + if ( LSM == LSM_RUC ) then + !- qsfc_lnd and qsfc_ice are already available + QSFC(i)=QV3D(i,kts)/(1.+QV3D(i,kts)) + QSFC_WAT(i)=QSFC(i) + else + QSFC(i)=QV3D(i,kts)/(1.+QV3D(i,kts)) + QSFC_WAT(i)=QSFC(i) + QSFC_LND(i)=QSFC(i) + QSFC_ICE(i)=QSFC(i) + endif ! lsm==lsm_ruc ENDDO - ELSE - IF (LSM == 3) THEN - DO i=its,ite - QSFC_LND(i)=QSFC_RUC(i) - ENDDO - ENDIF ENDIF - CALL SFCLAY1D_mynn( & + CALL SFCLAY1D_mynn(flag_iter, & J,U1D,V1D,T1D,QV1D,P1D,dz8w1d, & U1D2,V1D2,dz2w1d, & PSFCPA,PBLH,MAVAIL,XLAND,DX, & @@ -438,7 +438,7 @@ SUBROUTINE SFCLAY_mynn( & sigmaf,vegtype,shdmax,ivegsrc, & !intent(in) z0pert,ztpert, & !intent(in) redrag,sfc_z0_type, & !intent(in) - itimestep,iter, & + itimestep,iter,lsm,lsm_ruc, & wet, dry, icy, & !intent(in) tskin_wat, tskin_lnd, tskin_ice, & !intent(in) tsurf_wat, tsurf_lnd, tsurf_ice, & !intent(in) @@ -476,7 +476,7 @@ END SUBROUTINE SFCLAY_MYNN !! which are passed to subsequent scheme to calculate the fluxes. !! This scheme has options to calculate the fluxes and near-surface !! diagnostics, as was needed in WRF, but these are skipped for FV3. - SUBROUTINE SFCLAY1D_mynn( & + SUBROUTINE SFCLAY1D_mynn(flag_iter, & J,U1D,V1D,T1D,QV1D,P1D,dz8w1d,U1D2,V1D2,dz2w1d, & PSFCPA,PBLH,MAVAIL,XLAND,DX, & CP,G,ROVCP,R,XLV,SVP1,SVP2,SVP3,SVPT0, & @@ -485,7 +485,7 @@ SUBROUTINE SFCLAY1D_mynn( & sigmaf,vegtype,shdmax,ivegsrc, & !intent(in) z0pert,ztpert, & !intent(in) redrag,sfc_z0_type, & !intent(in) - itimestep,iter, & + itimestep,iter,lsm,lsm_ruc, & wet, dry, icy, & !intent(in) tskin_wat, tskin_lnd, tskin_ice, & !intent(in) tsurf_wat, tsurf_lnd, tsurf_ice, & !intent(in) @@ -524,7 +524,7 @@ SUBROUTINE SFCLAY1D_mynn( & INTEGER, INTENT(IN) :: ids,ide, jds,jde, kds,kde, & ims,ime, jms,jme, kms,kme, & its,ite, jts,jte, kts,kte, & - J, itimestep, iter + J, itimestep, iter, lsm, lsm_ruc REAL, PARAMETER :: XKA=2.4E-5 !molecular diffusivity REAL, PARAMETER :: PRT=1. !prandlt number @@ -580,7 +580,7 @@ SUBROUTINE SFCLAY1D_mynn( & USTM LOGICAL, DIMENSION( ims:ime ), INTENT(IN) :: & - & wet, dry, icy + & wet, dry, icy, flag_iter REAL, DIMENSION( ims:ime ), INTENT(in) :: & & tskin_wat, tskin_lnd, tskin_ice, & @@ -659,6 +659,118 @@ SUBROUTINE SFCLAY1D_mynn( & REAL :: restar,VISC,DQG,OLDUST,OLDTST !------------------------------------------------------------------- + DO I=its,ite + + ! PSFC ( in cmb) is used later in saturation checks + PSFC(I)=PSFCPA(I)/1000. + !tgs - do computations if flag_iter(i) = .true. + if ( flag_iter(i) ) then + + IF (ITIMESTEP == 1) THEN + !initialize surface specific humidity and mixing ratios for land, ice and water + IF (wet(i)) THEN + TSK_wat(I) = tskin_wat(i) + IF (TSK_wat(I) .LT. 273.15) THEN + !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) + E1=SVP1*EXP(4648*(1./273.15 - 1./TSK_wat(I)) - & + & 11.64*LOG(273.15/TSK_wat(I)) + 0.02265*(273.15 - TSK_wat(I))) + ELSE + !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) + E1=SVP1*EXP(SVP2*(TSK_wat(I)-SVPT0)/(TSK_wat(i)-SVP3)) + ENDIF + QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + QSFCMR_wat(I)=EP2*E1/(PSFC(I)-E1) !mixing ratio + IF(QSFC_wat(I)>1..or.QSFC_wat(I)<0.) print *,' QSFC_wat(I)',itimestep,i,QSFC_wat(I),TSK_wat(i) + ENDIF + IF (dry(i)) THEN + TSK_lnd(I) = tskin_lnd(i) + if( lsm == lsm_ruc) then + QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) !mixing ratio + else + TABS = 0.5*(TSK_lnd(I) + T1D(I)) + IF (TABS .LT. 273.15) THEN + !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) + E1=SVP1*EXP(4648*(1./273.15 - 1./TABS) - & + & 11.64*LOG(273.15/TABS) + 0.02265*(273.15 - TABS)) + ELSE + !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) + E1=SVP1*EXP(SVP2*(TABS-SVPT0)/(TABS-SVP3)) + ENDIF + QSFC_lnd(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + QSFC_lnd(I)=0.5*(QSFC_lnd(I) + QSFC(I)) + QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) !mixing ratio + endif ! lsm + IF(QSFC_lnd(I)>1..or.QSFC_lnd(I)<0.) print *,' QSFC_lnd(I)',itimestep,i,QSFC_lnd(I),Tskin_lnd(i),tsurf_lnd(i),qsfc(i) + ENDIF + IF (icy(i)) THEN + TSK_ice(I) = tskin_ice(i) + if( lsm == lsm_ruc) then + QSFCMR_ice(I)=QSFC_ice(I)/(1.-QSFC_ice(I)) !mixing ratio + else + IF (TSK_ice(I) .LT. 273.15) THEN + !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) + E1=SVP1*EXP(4648*(1./273.15 - 1./TSK_ice(I)) - & + & 11.64*LOG(273.15/TSK_ice(I)) + 0.02265*(273.15 - TSK_ice(I))) + ELSE + !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) + E1=SVP1*EXP(SVP2*(TSK_ice(I)-SVPT0)/(TSK_ice(i)-SVP3)) + ENDIF + QSFC_ice(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + QSFCMR_ice(I)=EP2*E1/(PSFC(I)-E1) !mixing ratio + endif ! lsm + IF(QSFC_ice(I)>1..or.QSFC_ice(I)<0.) print *,' QSFC_ice(I)',itimestep,i,QSFC_ice(I),TSK_ice(i) + ENDIF + + ELSE + + ! Use what comes out of the NST, LSM, SICE after check + IF (wet(i)) then + TSK_wat(I) = tskin_wat(i) + IF (TSK_wat(I) .LT. 273.15) THEN + !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) + E1=SVP1*EXP(4648*(1./273.15 - 1./TSK_wat(I)) - & + & 11.64*LOG(273.15/TSK_wat(I)) + 0.02265*(273.15 - TSK_wat(I))) + ELSE + !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) + E1=SVP1*EXP(SVP2*(TSK_wat(I)-SVPT0)/(TSK_wat(i)-SVP3)) + ENDIF + QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + ENDIF + IF (dry(i).and.(QSFC_lnd(I)>1..or.QSFC_lnd(I)<0.)) then + !print *,'bad QSFC_lnd(I)',itimestep,iter,i,QSFC_lnd(I),TSKin_lnd(I) + TABS = 0.5*(TSKin_lnd(I) + T1D(I)) + IF (TABS .LT. 273.15) THEN + !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) + E1=SVP1*EXP(4648*(1./273.15 - 1./TABS) - & + & 11.64*LOG(273.15/TABS) + 0.02265*(273.15 - TABS)) + ELSE + !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) + E1=SVP1*EXP(SVP2*(TABS-SVPT0)/(TABS-SVP3)) + ENDIF + QSFC_lnd(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + QSFC_lnd(I)=0.5*(QSFC_lnd(I) + QSFC(I)) + ENDIF + IF (icy(i).and.(QSFC_ice(I)>1..or.QSFC_ice(I)<0.)) then + !print *,'bad QSFC_ice(I)',itimestep,iter,i,QSFC_ice(I),TSKin_ice(I) + IF (TSKin_ice(I) .LT. 273.15) THEN + !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) + E1=SVP1*EXP(4648*(1./273.15 - 1./TSKin_ice(I)) - & + & 11.64*LOG(273.15/TSKin_ice(I)) + 0.02265*(273.15 - TSKin_ice(I))) + ELSE + !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) + E1=SVP1*EXP(SVP2*(TSKin_ice(I)-SVPT0)/(TSKin_ice(i)-SVP3)) + ENDIF + QSFC_ice(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity + ENDIF + + IF (wet(i)) QSFCMR_wat(I)=QSFC_wat(I)/(1.-QSFC_wat(I)) + IF (dry(i)) QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) + IF (icy(i)) QSFCMR_ice(I)=QSFC_ice(I)/(1.-QSFC_ice(I)) + + ENDIF + endif ! flag_iter + ENDDO + IF (debug_code >= 1) THEN write(0,*)"ITIMESTEP=",ITIMESTEP," iter=",iter DO I=its,ite @@ -687,26 +799,38 @@ SUBROUTINE SFCLAY1D_mynn( & DO I=its,ite ! PSFC ( in cmb) is used later in saturation checks PSFC(I)=PSFCPA(I)/1000. - ! DEFINE SKIN TEMPERATURES FOR LAND/WATER/ICE - TSK_lnd(I) = 0.5 * (tsurf_lnd(i)+tskin_lnd(i)) - TSK_ice(I) = 0.5 * (tsurf_ice(i)+tskin_ice(i)) - TSK_wat(I) = 0.5 * (tsurf_wat(i)+tskin_wat(i)) QVSH(I)=QV1D(I)/(1.+QV1D(I)) !CONVERT TO SPEC HUM (kg/kg) THCON(I)=(100000./PSFCPA(I))**ROVCP - ENDDO - - DO I=its,ite - ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: - THSK_lnd(I) = TSK_lnd(I)*THCON(I) !(K) - THSK_ice(I) = TSK_ice(I)*THCON(I) !(K) - THSK_wat(I) = TSK_wat(I)*THCON(I) !(K) - ENDDO - - DO I=its,ite - ! CONVERT SKIN POTENTIAL TEMPERATURES TO VIRTUAL POTENTIAL TEMPERATURE: - THVSK_lnd(I) = THSK_lnd(I)*(1.+EP1*QVSH(I)) !(K) - THVSK_ice(I) = THSK_ice(I)*(1.+EP1*QVSH(I)) !(K) - THVSK_wat(I) = THSK_wat(I)*(1.+EP1*QVSH(I)) !(K) + if( flag_iter(i) ) then + ! DEFINE SKIN TEMPERATURES FOR LAND/WATER/ICE + if(dry(i)) then + TSK_lnd(I) = tskin_lnd(i) + !TSK_lnd(I) = 0.5 * (tsurf_lnd(i)+tskin_lnd(i)) + ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: + THSK_lnd(I) = TSK_lnd(I)*THCON(I) !(K) + THVSK_lnd(I) = THSK_lnd(I)*(1.+EP1*qsfc_lnd(I)) + if(THVSK_lnd(I) < 170. .or. THVSK_lnd(I) > 360.) & + print *,'THVSK_lnd(I)',itimestep,i,THVSK_lnd(I),THSK_lnd(i),tsurf_lnd(i),tskin_lnd(i),qsfc_lnd(i) + endif + if(icy(i)) then + TSK_ice(I) = tskin_ice(i) + !TSK_ice(I) = 0.5 * (tsurf_ice(i)+tskin_ice(i)) + ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: + THSK_ice(I) = TSK_ice(I)*THCON(I) !(K) + THVSK_ice(I) = THSK_ice(I)*(1.+EP1*qsfc_ice(I)) !(K) + if(THVSK_ice(I) < 170. .or. THVSK_ice(I) > 360.) & + print *,'THVSK_ice(I)',itimestep,i,THVSK_ice(I),THSK_ice(i),tsurf_ice(i),tskin_ice(i),qsfc_ice(i) + endif + if(wet(i)) then + TSK_wat(I) = tskin_wat(i) + !TSK_wat(I) = 0.5 * (tsurf_wat(i)+tskin_wat(i)) + ! CONVERT SKIN TEMPERATURES TO POTENTIAL TEMPERATURE: + THSK_wat(I) = TSK_wat(I)*THCON(I) !(K) + THVSK_wat(I) = THSK_wat(I)*(1.+EP1*QVSH(I)) !(K) + if(THVSK_wat(I) < 170. .or. THVSK_wat(I) > 360.) & + print *,'THVSK_wat(I)',i,THVSK_wat(I),THSK_wat(i),tsurf_wat(i),tskin_wat(i),qsfc_wat(i) + endif + endif ! flag_iter ENDDO DO I=its,ite @@ -728,6 +852,7 @@ SUBROUTINE SFCLAY1D_mynn( & GOVRTH(I)=G/TH1D(I) ENDDO + !tgs - should QFX and HFX be separate for land, ice and water? DO I=its,ite QFX(i)=QFLX(i)*RHO1D(I) HFX(i)=HFLX(i)*RHO1D(I)*cp @@ -747,56 +872,6 @@ SUBROUTINE SFCLAY1D_mynn( & ENDIF DO I=its,ite - - IF (ITIMESTEP == 1) THEN - IF (wet(i)) THEN - IF (TSK_wat(I) .LT. 273.15) THEN - !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) - E1=SVP1*EXP(4648*(1./273.15 - 1./TSK_wat(I)) - & - & 11.64*LOG(273.15/TSK_wat(I)) + 0.02265*(273.15 - TSK_wat(I))) - ELSE - !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) - E1=SVP1*EXP(SVP2*(TSK_wat(I)-SVPT0)/(TSK_wat(i)-SVP3)) - ENDIF - QSFC_wat(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity - QSFCMR_wat(I)=EP2*E1/(PSFC(I)-E1) !mixing ratio - ENDIF - IF (dry(i)) THEN - TABS = 0.5*(TSK_lnd(I) + T1D(I)) - IF (TABS .LT. 273.15) THEN - !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) - E1=SVP1*EXP(4648*(1./273.15 - 1./TABS) - & - & 11.64*LOG(273.15/TABS) + 0.02265*(273.15 - TABS)) - ELSE - !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) - E1=SVP1*EXP(SVP2*(TABS-SVPT0)/(TABS-SVP3)) - ENDIF - QSFC_lnd(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity - QSFC_lnd(I)=0.5*(QSFC_lnd(I) + QSFC(I)) - QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) !mixing ratio - ENDIF - IF (icy(i)) THEN - IF (TSK_ice(I) .LT. 273.15) THEN - !SATURATION VAPOR PRESSURE WRT ICE (SVP1=.6112; 10*mb) - E1=SVP1*EXP(4648*(1./273.15 - 1./TSK_ice(I)) - & - & 11.64*LOG(273.15/TSK_ice(I)) + 0.02265*(273.15 - TSK_ice(I))) - ELSE - !SATURATION VAPOR PRESSURE WRT WATER (Bolton 1980) - E1=SVP1*EXP(SVP2*(TSK_ice(I)-SVPT0)/(TSK_ice(i)-SVP3)) - ENDIF - QSFC_ice(I)=EP2*E1/(PSFC(I)-ep_3*E1) !specific humidity - QSFCMR_ice(I)=EP2*E1/(PSFC(I)-E1) !mixing ratio - ENDIF - - ELSE - - ! Use what comes out of the LSM, NST, and CICE - IF (wet(i)) QSFCMR_wat(I)=QSFC_wat(I)/(1.-QSFC_wat(I)) - IF (dry(i)) QSFCMR_lnd(I)=QSFC_lnd(I)/(1.-QSFC_lnd(I)) - IF (icy(i)) QSFCMR_ice(I)=QSFC_ice(I)/(1.-QSFC_ice(I)) - - ENDIF - ! QGH CHANGED TO USE LOWEST-LEVEL AIR TEMP ! Q2SAT = QGH IN LSM IF (T1D(I) .LT. 273.15) THEN @@ -832,6 +907,7 @@ SUBROUTINE SFCLAY1D_mynn( & ENDIF DO I=its,ite + if( flag_iter(i) ) then ! DH* 20200401 - note. A weird bug in Intel 18 on hera prevents using the ! normal -O2 optimization in REPRO and PROD mode for this file. Not reproducible ! by every user, the bug manifests itself in the resulting wind speed WSPD(I) @@ -848,6 +924,9 @@ SUBROUTINE SFCLAY1D_mynn( & ! subgrid-scale velocity (VSGD) following Beljaars (1995, QJRMS) ! and Mahrt and Sun (1995, MWR), respectively !------------------------------------------------------- + !tgs - the line below could be used when hflx_wat,qflx_wat are moved from + ! Interstitial to Sfcprop + !fluxc = max(hflx_wat(i) + ep1*THVSK_wat(I)*qflx_wat(i),0.) fluxc = max(hfx(i)/RHO1D(i)/cp & & + ep1*THVSK_wat(I)*qfx(i)/RHO1D(i),0.) !WSTAR(I) = vconvc*(g/TSK(i)*pblh(i)*fluxc)**onethird @@ -880,6 +959,9 @@ SUBROUTINE SFCLAY1D_mynn( & ! subgrid-scale velocity (VSGD) following Beljaars (1995, QJRMS) ! and Mahrt and Sun (1995, MWR), respectively !------------------------------------------------------- + !tgs - the line below could be used when hflx_lnd,qflx_wat are moved from + ! Interstitial to Sfcprop + !fluxc = max(hflx_lnd(i) + ep1*THVSK_lnd(I)*qflx_lnd(i),0.) fluxc = max(hfx(i)/RHO1D(i)/cp & & + ep1*THVSK_lnd(I)*qfx(i)/RHO1D(i),0.) ! WSTAR(I) = vconvc*(g/TSK(i)*pblh(i)*fluxc)**onethird @@ -920,6 +1002,9 @@ SUBROUTINE SFCLAY1D_mynn( & ! subgrid-scale velocity (VSGD) following Beljaars (1995, QJRMS) ! and Mahrt and Sun (1995, MWR), respectively !------------------------------------------------------- + !tgs - the line below could be used when hflx_ice,qflx_ice are moved from + ! Interstitial to Sfcprop + !fluxc = max(hflx_ice(i) + ep1*THVSK_ice(I)*qflx_ice(i)/RHO1D(i),0.) fluxc = max(hfx(i)/RHO1D(i)/cp & & + ep1*THVSK_ice(I)*qfx(i)/RHO1D(i),0.) ! WSTAR(I) = vconvc*(g/TSK(i)*pblh(i)*fluxc)**onethird @@ -965,6 +1050,7 @@ SUBROUTINE SFCLAY1D_mynn( & ! IF(MOL(I).LT.0.)BR(I)=MIN(BR(I),0.0) !ENDIF + endif ! flag_iter ENDDO 1006 format(A,F7.3,A,f9.4,A,f9.5,A,f9.4) @@ -977,6 +1063,7 @@ SUBROUTINE SFCLAY1D_mynn( & !-------------------------------------------------------------------- DO I=its,ite + if( flag_iter(i) ) then !COMPUTE KINEMATIC VISCOSITY (m2/s) Andreas (1989) CRREL Rep. 89-11 !valid between -173 and 277 degrees C. @@ -1153,6 +1240,15 @@ SUBROUTINE SFCLAY1D_mynn( & UST_lnd(I),KARMAN,1.0,0,spp_pbl,rstoch1D(i)) ENDIF ENDIF + IF (ZNTstoch_lnd(i) < 1E-8 .OR. Zt_lnd(i) < 1E-10) THEN + write(0,*)"===(land) capture bad input in mynn sfc layer, i=:",i + write(0,*)" ZNT=", ZNTstoch_lnd(i)," ZT=",Zt_lnd(i) + write(0,*)" tsk=", tskin_lnd(i)," restar=",restar,& + " tsurf=", tsurf_lnd(i)," qsfc=", qsfc_lnd(i)," znt=", znt_lnd(i),& + " ust=", ust_lnd(i)," snowh=", snowh_lnd(i),"psfcpa=",PSFCPA(i), & + " dz=",dz8w1d(i)," qflx=",qflx_lnd(i)," hflx=",hflx_lnd(i)," hpbl=",pblh(i) + ENDIF + GZ1OZ0_lnd(I)= LOG((ZA(I)+ZNTstoch_lnd(I))/ZNTstoch_lnd(I)) GZ1OZt_lnd(I)= LOG((ZA(I)+ZNTstoch_lnd(i))/ZT_lnd(i)) @@ -1194,6 +1290,7 @@ SUBROUTINE SFCLAY1D_mynn( & ENDIF !end ice point !Capture a representative ZNT + !tgs - should this be changed for fractional grid or fractional sea ice? IF (dry(i)) THEN ZNT(i)=ZNTstoch_lnd(I) ELSEIF (wet(i)) THEN @@ -1616,6 +1713,7 @@ SUBROUTINE SFCLAY1D_mynn( & ! Compute u* without vconv for use in HFX calc when isftcflx > 0 WSPDI(I)=MAX(SQRT(U1D(I)*U1D(I)+V1D(I)*V1D(I)), wmin) + !tgs - should USTM be separater for dry, icy, wet? USTM(I)=0.5*USTM(I)+0.5*KARMAN*WSPDI(I)/PSIX_wat(I) ! for possible future changes in sea-ice fraction from 0 to >0: @@ -1638,6 +1736,7 @@ SUBROUTINE SFCLAY1D_mynn( & stress_lnd(i)=ust_lnd(i)**2 !set ustm = ust over land. + !tgs - should USTM be separater for dry, icy, wet? USTM(I)=UST_lnd(I) ENDIF ! end water points @@ -1651,9 +1750,11 @@ SUBROUTINE SFCLAY1D_mynn( & stress_ice(i)=ust_ice(i)**2 !Set ustm = ust over ice. + !tgs - should USTM be separate for for dry, icy, wet? USTM(I)=UST_ice(I) ! for possible future changes in sea-ice fraction from 1 to <1: + !tgs - sea ice can be <1 now if (.not. wet(i)) ust_wat(i)=ust_ice(i) ENDIF ! end ice points @@ -1662,6 +1763,7 @@ SUBROUTINE SFCLAY1D_mynn( & !----AND COMPUTE THE MOISTURE SCALE (or q*) !---------------------------------------------------- + !tgs - should we have MOL and qstar separate for dry, icy and wet? IF (wet(I)) THEN DTG=THV1D(I)-THVSK_wat(I) OLDTST=MOL(I) @@ -1695,6 +1797,7 @@ SUBROUTINE SFCLAY1D_mynn( & qstar(I)=KARMAN*DQG/PSIQ_ice(I)/PRT ENDIF + endif ! flag_iter ENDDO ! end i-loop IF (debug_code == 2) THEN @@ -1722,6 +1825,7 @@ SUBROUTINE SFCLAY1D_mynn( & ! COMPUTE SURFACE HEAT AND MOISTURE FLUXES !---------------------------------------------------------- DO I=its,ite + if( flag_iter(i) ) then IF (ISFFLX .LT. 1) THEN @@ -1750,6 +1854,7 @@ SUBROUTINE SFCLAY1D_mynn( & ! CALCULATE THE EXCHANGE COEFFICIENTS FOR HEAT (FLHC) ! AND MOISTURE (FLQC) !------------------------------------------ + !tgs - should FLQC, FLHC be separate for dry, icy and wet? FLQC(I)=RHO1D(I)*MAVAIL(I)*UST_lnd(I)*KARMAN/PSIQ_lnd(i) FLHC(I)=RHO1D(I)*CPM(I)*UST_lnd(I)*KARMAN/PSIT_lnd(I) @@ -1757,8 +1862,8 @@ SUBROUTINE SFCLAY1D_mynn( & !---------------------------------- ! COMPUTE SURFACE MOISTURE FLUX: !---------------------------------- - !QFX(I)=FLQC(I)*(QSFCMR_lnd(I)-QV1D(I)) - QFX(I)=FLQC(I)*(QSFC_lnd(I)-QV1D(I)) + QFX(I)=FLQC(I)*(QSFCMR_lnd(I)-QV1D(I)) + !QFX(I)=FLQC(I)*(QSFC_lnd(I)-QV1D(I)) QFX(I)=MAX(QFX(I),-0.02) !allows small neg QFX LH(i)=XLV*QFX(i) ! BWG, 2020-06-17: Mod next 2 lines for fractional @@ -1778,6 +1883,8 @@ SUBROUTINE SFCLAY1D_mynn( & !TRANSFER COEFF FOR SOME LSMs: !CHS(I)=UST(I)*KARMAN/(ALOG(KARMAN*UST(I)*ZA(I) & ! /XKA+ZA(I)/ZL)-PSIH(I)) + + !tgs - should QSFC, CHS, CHS2 and CQS2 be separate for dry, icy and wet? CHS(I)=UST_lnd(I)*KARMAN/PSIT_lnd(I) !THESE ARE USED FOR 2-M DIAGNOSTICS ONLY @@ -1799,8 +1906,8 @@ SUBROUTINE SFCLAY1D_mynn( & !---------------------------------- ! COMPUTE SURFACE MOISTURE FLUX: !---------------------------------- - !QFX(I)=FLQC(I)*(QSFCMR_wat(I)-QV1D(I)) - QFX(I)=FLQC(I)*(QSFC_wat(I)-QV1D(I)) + QFX(I)=FLQC(I)*(QSFCMR_wat(I)-QV1D(I)) + !QFX(I)=FLQC(I)*(QSFC_wat(I)-QV1D(I)) QFX(I)=MAX(QFX(I),-0.02) !allows small neg QFX LH(I)=XLV*QFX(I) ! BWG, 2020-06-17: Mod next 2 lines for fractional @@ -1846,8 +1953,8 @@ SUBROUTINE SFCLAY1D_mynn( & !---------------------------------- ! COMPUTE SURFACE MOISTURE FLUX: !---------------------------------- - !QFX(I)=FLQC(I)*(QSFCMR_ice(I)-QV1D(I)) - QFX(I)=FLQC(I)*(QSFC_ice(I)-QV1D(I)) + QFX(I)=FLQC(I)*(QSFCMR_ice(I)-QV1D(I)) + !QFX(I)=FLQC(I)*(QSFC_ice(I)-QV1D(I)) QFX(I)=MAX(QFX(I),-0.02) !allows small neg QFX LH(I)=XLF*QFX(I) ! BWG, 2020-06-17: Mod next 2 lines for fractional @@ -1905,10 +2012,12 @@ SUBROUTINE SFCLAY1D_mynn( & ENDIF ENDIF !end ISFFLX option + endif ! flag_iter ENDDO ! end i-loop IF (compute_diag) then DO I=its,ite + if( flag_iter(i) ) then !----------------------------------------------------- !COMPUTE DIAGNOSTICS !----------------------------------------------------- @@ -2013,6 +2122,7 @@ SUBROUTINE SFCLAY1D_mynn( & Q2(I)= MAX(Q2(I), MIN(QSFC_ice(I), QV1D(I))) Q2(I)= MIN(Q2(I), 1.05*QV1D(I)) ENDIF + endif ! flag_iter ENDDO ENDIF ! end compute_diag diff --git a/physics/sfc_drv_ruc.F90 b/physics/sfc_drv_ruc.F90 index dbcfb566d..ecea7a670 100644 --- a/physics/sfc_drv_ruc.F90 +++ b/physics/sfc_drv_ruc.F90 @@ -323,7 +323,7 @@ end subroutine lsm_ruc_finalize subroutine lsm_ruc_run & ! inputs & ( iter, me, master, delt, kdt, im, nlev, lsm_ruc, lsm, & & imp_physics, imp_physics_gfdl, imp_physics_thompson, & - & do_mynnsfclay, lsoil_ruc, lsoil, rdlai, zs, & + & do_mynnsfclay, lsoil_ruc, lsoil, rdlai, xlat_d, xlon_d, zs,& & t1, q1, qc, stype, vtype, sigmaf, laixy, & & dlwflx, dswsfc, tg3, coszen, land, icy, use_lake, & & rainnc, rainc, ice, snow, graupel, & @@ -372,6 +372,7 @@ subroutine lsm_ruc_run & ! inputs integer, intent(in) :: im, nlev, iter, lsoil_ruc, lsoil, kdt, isot, ivegsrc integer, intent(in) :: lsm_ruc, lsm integer, intent(in) :: imp_physics, imp_physics_gfdl, imp_physics_thompson + real (kind=kind_phys), dimension(:), intent(in) :: xlat_d, xlon_d real (kind=kind_phys), dimension(:), intent(in) :: & & t1, sigmaf, laixy, dlwflx, dswsfc, tg3, & @@ -527,12 +528,20 @@ subroutine lsm_ruc_run & ! inputs logical :: flag(im), flag_ice(im), flag_ice_uncoupled(im) logical :: rdlai2d, myj, frpcpn logical :: debug_print + + !-- diagnostic point + real (kind=kind_phys) :: testptlat, testptlon ! ! Initialize CCPP error handling variables errmsg = '' errflg = 0 ipr = 10 + + !-- + testptlat = 74.12 !29.5 + testptlon = 164.0 !283.0 + !-- debug_print=.false. @@ -833,6 +842,26 @@ subroutine lsm_ruc_run & ! inputs rainncv(i,j) = rhoh2o * rainnc(i) ! total time-step explicit precip graupelncv(i,j) = rhoh2o * graupel(i) snowncv(i,j) = rhoh2o * snow(i) + if (debug_print) then + !-- diagnostics for a test point with known lat/lon + if (abs(xlat_d(i)-testptlat).lt.2.5 .and. & + abs(xlon_d(i)-testptlon).lt.6.5)then + if(weasd_lnd(i) > 0.) & + print 100,'(ruc_lsm_drv) i=',i, & + ' lat,lon=',xlat_d(i),xlon_d(i), & + 'rainc',rainc(i),'rainnc',rainnc(i), & + 'graupel',graupel(i),'qc',qc(i),'sfcqv_lnd',sfcqv_lnd(i),& + 'dlwflx',dlwflx(i),'dswsfc',dswsfc(i), & + 'sncovr1_lnd',sncovr1_lnd(i),'sfalb_lnd_bck',sfalb_lnd_bck(i),& + 'prsl1',prsl1(i),'t1',t1(i), & + !'snow',snow(i), 'snowncv',snowncv(i,j), & + 'srflag',srflag(i),'weasd_lnd',weasd_lnd(i), & + 'tsurf_lnd',tsurf_lnd(i),'tslb(i,1)',tslb(i,1) + endif + endif + 100 format (";;; ",a,i4,a,2f9.2/(4(a10,'='es9.2))) + !-- + ! ice precipitation is not used ! precipfr(i,j) = rainncv(i,j) * ffrozp(i,j) @@ -1245,6 +1274,25 @@ subroutine lsm_ruc_run & ! inputs if (flag_ice_uncoupled(i)) then ! at least some ice in the grid cell !-- ice point + if (debug_print) then + if (abs(xlat_d(i)-testptlat).lt.2.5 .and. & + abs(xlon_d(i)-testptlon).lt.6.5)then + if(weasd_lnd(i) > 0.) & + print 101,'(ruc_lsm_drv ice) i=',i, & + ' lat,lon=',xlat_d(i),xlon_d(i),'flag_ice',flag_ice(i),& + !'rainc',rainc(i),'rainnc',rainnc(i), & + 'sfcqv_ice',sfcqv_ice(i),& + !'dlwflx',dlwflx(i),'dswsfc',dswsfc(i), & + 'sncovr1_ice',sncovr1_ice(i),'sfalb_ice',sfalb_ice(i),& + 'sfcqc_ice',sfcqc_ice(i),'tsnow_ice',tsnow_ice(i), & + 'prsl1',prsl1(i),'t1',t1(i), & + !'snow',snow(i), 'snowncv',snowncv(i,j), & + 'srflag',srflag(i),'weasd_ice',weasd_ice(i), & + 'tsurf_ice',tsurf_ice(i),'tslb(i,1)',tslb(i,1) + endif + endif + 101 format (";;; ",a,i4,a,2f9.2/(4(a10,'='es9.2))) + sncovr_ice(i,j) = sncovr1_ice(i) !-- alb_ice* is computed in setalb called from rrtmg_sw_pre. snoalb1d_ice(i,j) = 0.75 !alb_ice_snow(i) !0.75 is RAP value for max snow alb on ice diff --git a/physics/sfc_drv_ruc.meta b/physics/sfc_drv_ruc.meta index 8333746ec..e37e1ea36 100644 --- a/physics/sfc_drv_ruc.meta +++ b/physics/sfc_drv_ruc.meta @@ -729,6 +729,24 @@ type = logical intent = in optional = F +[xlat_d] + standard_name = latitude_in_degree + long_name = latitude in degree north + units = degree_north + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in + optional = F +[xlon_d] + standard_name = longitude_in_degree + long_name = longitude in degree east + units = degree_east + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in + optional = F [zs] standard_name = depth_of_soil_layers long_name = depth of soil levels for land surface model