diff --git a/physics/GFS_MP_generic_post.F90 b/physics/GFS_MP_generic_post.F90 index b7e65bc8b..1a04c74ba 100644 --- a/physics/GFS_MP_generic_post.F90 +++ b/physics/GFS_MP_generic_post.F90 @@ -20,10 +20,11 @@ module GFS_MP_generic_post !> @{ subroutine GFS_MP_generic_post_run( & im, levs, kdt, nrcm, nncl, ntcw, ntrac, imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_nssl, & - imp_physics_mg, imp_physics_fer_hires, cal_pre, cplflx, cplchm, cpllnd, progsigma, con_g, rainmin, dtf, frain, rainc, & - rain1, rann, xlat, xlon, gt0, gq0, prsl, prsi, phii, tsfc, ice, snow, graupel, save_t, save_q, rain0, ice0, snow0,& - graupel0, del, rain, domr_diag, domzr_diag, domip_diag, doms_diag, tprcp, srflag, sr, cnvprcp, totprcp, totice, & - totsnw, totgrp, cnvprcpb, totprcpb, toticeb, totsnwb, totgrpb, rain_cpl, rainc_cpl, snow_cpl, pwat, & + imp_physics_mg, imp_physics_fer_hires, cal_pre, cplflx, cplchm, cpllnd, progsigma, con_g, rhowater, rainmin, dtf, & + frain, rainc, rain1, rann, xlat, xlon, gt0, gq0, prsl, prsi, phii, tsfc, ice, snow, graupel, save_t, save_q, & + rain0, ice0, snow0, graupel0, del, rain, domr_diag, domzr_diag, domip_diag, doms_diag, tprcp, srflag, sr, cnvprcp,& + totprcp, totice, totsnw, totgrp, cnvprcpb, totprcpb, toticeb, totsnwb, totgrpb, rain_cpl, rainc_cpl, snow_cpl, & + pwat, frzr, frzrb, frozr, frozrb, tsnowp, tsnowpb, rhonewsn1, exticeden, & drain_cpl, dsnow_cpl, lsm, lsm_ruc, lsm_noahmp, raincprv, rainncprv, iceprv, snowprv, & graupelprv, draincprv, drainncprv, diceprv, dsnowprv, dgraupelprv, dtp, dfi_radar_max_intervals, & dtend, dtidx, index_of_temperature, index_of_process_mp,ldiag3d, qdiag3d,dqdt_qmicro, lssav, num_dfi_radar, & @@ -37,7 +38,7 @@ subroutine GFS_MP_generic_post_run( integer, intent(in) :: im, levs, kdt, nrcm, nncl, ntcw, ntrac, num_dfi_radar, index_of_process_dfi_radar integer, intent(in) :: imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_mg, imp_physics_fer_hires integer, intent(in) :: imp_physics_nssl - logical, intent(in) :: cal_pre, lssav, ldiag3d, qdiag3d, cplflx, cplchm, cpllnd, progsigma + logical, intent(in) :: cal_pre, lssav, ldiag3d, qdiag3d, cplflx, cplchm, cpllnd, progsigma, exticeden integer, intent(in) :: index_of_temperature,index_of_process_mp integer :: dfi_radar_max_intervals @@ -46,7 +47,7 @@ subroutine GFS_MP_generic_post_run( integer :: ix_dfi_radar(:) real(kind=kind_phys), dimension(:,:), intent(inout) :: gt0 - real(kind=kind_phys), intent(in) :: dtf, frain, con_g, rainmin + real(kind=kind_phys), intent(in) :: dtf, frain, con_g, rainmin, rhowater real(kind=kind_phys), dimension(:), intent(in) :: rain1, xlat, xlon, tsfc real(kind=kind_phys), dimension(:), intent(inout) :: ice, snow, graupel, rainc real(kind=kind_phys), dimension(:), intent(in) :: rain0, ice0, snow0, graupel0 @@ -81,6 +82,13 @@ subroutine GFS_MP_generic_post_run( real(kind=kind_phys), dimension(:), intent(inout) :: diceprv real(kind=kind_phys), dimension(:), intent(inout) :: dsnowprv real(kind=kind_phys), dimension(:), intent(inout) :: dgraupelprv + real(kind=kind_phys), dimension(:), intent(inout) :: frzr + real(kind=kind_phys), dimension(:), intent(inout) :: frzrb + real(kind=kind_phys), dimension(:), intent(inout) :: frozr + real(kind=kind_phys), dimension(:), intent(inout) :: frozrb + real(kind=kind_phys), dimension(:), intent(inout) :: tsnowp + real(kind=kind_phys), dimension(:), intent(inout) :: tsnowpb + real(kind=kind_phys), dimension(:), intent(inout) :: rhonewsn1 real(kind=kind_phys), dimension(:,:), intent(inout) :: dqdt_qmicro real(kind=kind_phys), dimension(:,:), intent(inout) :: prevsq real(kind=kind_phys), intent(in) :: dtp @@ -101,6 +109,9 @@ subroutine GFS_MP_generic_post_run( real(kind=kind_phys) :: crain, csnow, onebg, tem, total_precip, tem1, tem2, ttend real(kind=kind_phys), dimension(im) :: domr, domzr, domip, doms, t850, work1 + real :: snowrat,grauprat,icerat,curat,prcpncfr,prcpcufr + real :: rhonewsnow,rhoprcpice,rhonewgr,rhonewice + ! Initialize CCPP error handling variables errmsg = '' errflg = 0 @@ -111,6 +122,68 @@ subroutine GFS_MP_generic_post_run( rain(i) = rainc(i) + frain * rain1(i) ! time-step convective plus explicit enddo +! compute surface snowfall, graupel/sleet, freezing rain and precip ice density + if (imp_physics == imp_physics_gfdl .or. imp_physics == imp_physics_thompson .or. imp_physics == imp_physics_nssl ) then + do i = 1, im + if (gt0(i,1) .le. 273) then + frzr(i) = frzr(i) + rain0(i) + frzrb(i) = frzrb(i) + rain0(i) + endif + tsnowp(i) = tsnowp(i) + snow0(i) + tsnowpb(i) = tsnowpb(i) + snow0(i) + frozr(i) = frozr(i) + graupel0(i) + frozrb(i) = frozrb(i) + graupel0(i) + enddo +!Compute the variable precip ice density for specific LSM schemes and options + if (exticeden) then + snowrat = 0. + grauprat = 0. + icerat = 0. + prcpncfr = 0. + prcpcufr = 0. + curat = 0. + prcpncfr = 0. + prcpcufr = 0. + rhonewsnow = 0. + rhonewgr = 0. + rhonewice = 0. + rhoprcpice = 0. + do i = 1, im + rhonewsn1(i)= 200. + prcpncfr = rain1(i)*sr(i) + if(sr(i) > 0..and. gt0(i,1) < 273.) then + prcpcufr = max(0.,rainc(i)*sr(i)) + else + if(gt0(i,1) < 273.) then + prcpcufr = max(0.,rainc(i)) + else + prcpcufr = 0. + endif ! gt0(i,1) < 273. + endif ! frzfrac > 0. +! + if((prcpncfr + prcpcufr) > 0.) then +! -- calculate snow, graupel and ice fractions in falling frozen precip + snowrat=min(1.,max(0.,snow0(i)/(prcpncfr + prcpcufr))) + grauprat=min(1.,max(0.,graupel0(i)/(prcpncfr + prcpcufr))) + icerat=min(1.,max(0.,(prcpncfr-snow0(i)-graupel0(i)) & + /(prcpncfr + prcpcufr))) + curat=min(1.,max(0.,(prcpcufr/(prcpncfr + prcpcufr)))) + + rhonewsnow=min(125.,1000.0/max(8.,(17.*tanh((276.65-gt0(i,1))*0.15)))) + rhonewgr=min(500.,rhowater/max(2.,(3.5*tanh((274.15-gt0(i,1))*0.3333)))) + rhonewice=rhonewsnow +!--- compute density of "precip ice" from weighted contribution +! of snow, graupel and ice fractions + + rhoprcpice = min(500.,max(58.8,(rhonewsnow*snowrat + & + rhonewgr*grauprat + rhonewice*icerat + rhonewgr*curat))) +! from now on rhonewsn1 is the density of falling frozen precipitation + rhonewsn1(i)=rhoprcpice + endif + enddo + endif + endif + !> - If requested (e.g. Zhao-Carr MP scheme), call calpreciptype() to calculate dominant !! precipitation type. ! DH* TODO - Fix wrong code in non-CCPP build (GFS_physics_driver) diff --git a/physics/GFS_MP_generic_post.meta b/physics/GFS_MP_generic_post.meta index 5216b7157..fa1cfafe0 100644 --- a/physics/GFS_MP_generic_post.meta +++ b/physics/GFS_MP_generic_post.meta @@ -150,6 +150,14 @@ type = real kind = kind_phys intent = in +[rhowater] + standard_name = fresh_liquid_water_density_at_0c + long_name = density of liquid water + units = kg m-3 + dimensions = () + type = real + kind = kind_phys + intent = in [dtf] standard_name = timestep_for_dynamics long_name = dynamics timestep @@ -278,6 +286,69 @@ type = real kind = kind_phys intent = inout +[frzr] + standard_name = cumulative_lwe_thickness_of_surface_freezing_rain_amount + long_name = accumulated surface freezing rain + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[frzrb] + standard_name = cumulative_lwe_thickness_of_surface_freezing_rain_amount_in_bucket + long_name = accumulated surface freezing rain in bucket + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[frozr] + standard_name = cumulative_lwe_thickness_of_surface_graupel_amount + long_name = accumulated surface graupel + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[frozrb] + standard_name = cumulative_lwe_thickness_of_surface_graupel_amount_in_bucket + long_name = accumulated surface graupel in bucket + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[tsnowp] + standard_name = cumulative_lwe_thickness_of_surface_snow_amount + long_name = accumulated surface snow + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[tsnowpb] + standard_name = cumulative_lwe_thickness_of_surface_snow_amount_in_bucket + long_name = accumulated surface snow in bucket + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = inout +[exticeden] + standard_name = do_external_surface_frozen_precipitation_density + long_name = flag for calculating frozen precip ice density outside of the LSM + units = flag + dimensions = () + type = logical + intent = in [save_t] standard_name = air_temperature_save long_name = air temperature before entering a physics scheme diff --git a/physics/GFS_debug.F90 b/physics/GFS_debug.F90 index 5e6419256..5387e6300 100644 --- a/physics/GFS_debug.F90 +++ b/physics/GFS_debug.F90 @@ -1285,7 +1285,7 @@ subroutine GFS_interstitialtoscreen_run (Model, Statein, Stateout, Sfcprop, Coup call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_ice ', Interstitial%qss_ice ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_land ', Interstitial%qss_land ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%qss_water ', Interstitial%qss_water ) - call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%radar_reset ', Interstitial%radar_reset ) + call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%fullradar_diag ', Interstitial%fullradar_diag ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raddt ', Interstitial%raddt ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raincd ', Interstitial%raincd ) call print_var(mpirank, omprank, blkno, Grid%xlat_d, Grid%xlon_d, 'Interstitial%raincs ', Interstitial%raincs ) diff --git a/physics/lsm_noah.f b/physics/lsm_noah.f index 246f81654..e145fa94b 100644 --- a/physics/lsm_noah.f +++ b/physics/lsm_noah.f @@ -220,7 +220,8 @@ subroutine lsm_noah_run & & lheatstrg, isot, ivegsrc, & & bexppert, xlaipert, vegfpert,pertvegf, & ! sfc perts, mgehne & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & - & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd, & + & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd, rhonewsn1, & + & exticeden, & ! --- in/outs: & weasd, snwdph, tskin, tprcp, srflag, smc, stc, slc, & & canopy, trans, tsurf, zorl, & @@ -252,7 +253,7 @@ subroutine lsm_noah_run & & -1.0_kind_phys, -2.0_kind_phys / ! --- input: - integer, intent(in) :: im, km, isot, ivegsrc + integer, intent(in) :: im, km, isot, ivegsrc real (kind=kind_phys), intent(in) :: grav, cp, hvap, rd, eps, & & epsm1, rvrdm1 real (kind=kind_phys), intent(in) :: pertvegf @@ -265,13 +266,13 @@ subroutine lsm_noah_run & & snoalb, sfalb, zf, & & bexppert, xlaipert, vegfpert, & & albdvis_lnd, albdnir_lnd, albivis_lnd, albinir_lnd, & - & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd + & adjvisbmd, adjnirbmd, adjvisdfd, adjnirdfd, rhonewsn1 real (kind=kind_phys), intent(in) :: delt logical, dimension(:), intent(in) :: flag_iter, flag_guess, land - logical, intent(in) :: lheatstrg + logical, intent(in) :: lheatstrg, exticeden ! --- in/out: real (kind=kind_phys), dimension(:), intent(inout) :: weasd, & @@ -292,7 +293,7 @@ subroutine lsm_noah_run & ! --- locals: real (kind=kind_phys), dimension(im) :: rch, rho, & & q0, qs1, theta1, weasd_old, snwdph_old, & - & tprcp_old, srflag_old, tskin_old, canopy_old + & tprcp_old, srflag_old, tskin_old, canopy_old real (kind=kind_phys), dimension(km) :: et, sldpth, stsoil, & & smsoil, slsoil @@ -309,8 +310,8 @@ subroutine lsm_noah_run & & smcdry, smcref, smcmax, sneqv, snoalb1d, snowh, & & snomlt, sncovr, soilw, soilm, ssoil, tsea, th2, tbot, & & xlai, zlvl, swdn, tem, z0, bexpp, xlaip, vegfp, & - & mv, sv, alphav, betav, vegftmp, cpinv, hvapi, elocp - + & mv, sv, alphav, betav, vegftmp, cpinv, hvapi, elocp, & + & rhonewsn integer :: couple, ice, nsoil, nroot, slope, stype, vtype integer :: i, k, iflag ! @@ -326,7 +327,6 @@ subroutine lsm_noah_run & errflg = 0 !> - Save land-related prognostic fields for guess run. - do i = 1, im if (land(i) .and. flag_guess(i)) then weasd_old(i) = weasd(i) @@ -335,7 +335,6 @@ subroutine lsm_noah_run & canopy_old(i) = canopy(i) tprcp_old(i) = tprcp(i) srflag_old(i) = srflag(i) - do k = 1, km smc_old(i,k) = smc(i,k) stc_old(i,k) = stc(i,k) @@ -361,7 +360,6 @@ subroutine lsm_noah_run & sbsno(i) = zero snowc(i) = zero snohf(i) = zero - !> - Initialize variables wind, q, and rh at level 1. q0(i) = max(q1(i), qmin) !* q1=specific humidity at level 1 (kg/kg) @@ -371,7 +369,6 @@ subroutine lsm_noah_run & qs1(i) = fpvs( t1(i) ) !* qs1=sat. humidity at level 1 (kg/kg) qs1(i) = max(eps*qs1(i) / (prsl1(i)+epsm1*qs1(i)), qmin) q0 (i) = min(qs1(i), q0(i)) - do k = 1, km zsoil(i,k) = zsoil_noah(k) enddo @@ -524,7 +521,8 @@ subroutine lsm_noah_run & !> - Apply perturbation of soil type b parameter and leave area index. bexpp = bexppert(i) ! sfc perts, mgehne xlaip = xlaipert(i) ! sfc perts, mgehne - +!> - New snow depth variables + rhonewsn = rhonewsn1(i) !> - Call Noah LSM gfssflx(). call gfssflx & ! ccppdox: these is sflx in mpbl @@ -533,6 +531,7 @@ subroutine lsm_noah_run & & swdn, solnet, lwdn, sfcems, sfcprs, sfctmp, & & sfcspd, prcp, q2, q2sat, dqsdt2, th2, ivegsrc, & & vtype, stype, slope, shdmin1d, alb, snoalb1d, & + & rhonewsn, exticeden, & & bexpp, xlaip, & ! sfc-perts, mgehne & lheatstrg, & ! --- input/outputs: diff --git a/physics/lsm_noah.meta b/physics/lsm_noah.meta index 2ce7c3e6c..e059a22c6 100644 --- a/physics/lsm_noah.meta +++ b/physics/lsm_noah.meta @@ -486,6 +486,21 @@ type = real kind = kind_phys intent = in +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in +[exticeden] + standard_name = do_external_surface_frozen_precipitation_density + long_name = flag for calculating frozen precip ice density outside of the LSM + units = flag + dimensions = () + type = logical + intent = in [weasd] standard_name = water_equivalent_accumulated_snow_depth_over_land long_name = water equiv of acc snow depth over land diff --git a/physics/lsm_ruc.F90 b/physics/lsm_ruc.F90 index 99b6c2b41..f4c2a8be6 100644 --- a/physics/lsm_ruc.F90 +++ b/physics/lsm_ruc.F90 @@ -323,15 +323,15 @@ 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, & - & imp_physics_nssl, & - & do_mynnsfclay, lsoil_ruc, lsoil, rdlai, xlat_d, xlon_d, zs,& + & imp_physics_nssl, do_mynnsfclay, exticeden, & + & 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, & & prsl1, zf, wind, shdmin, shdmax, & & srflag, sfalb_lnd_bck, snoalb, & & isot, ivegsrc, fice, smcwlt2, smcref2, & - & min_lakeice, min_seaice, oceanfrac, & + & min_lakeice, min_seaice, oceanfrac, rhonewsn1, & ! --- constants & con_cp, con_rd, con_rv, con_g, con_pi, con_hvap, & & con_fvirt, & @@ -397,6 +397,7 @@ subroutine lsm_ruc_run & ! inputs logical, dimension(:), intent(in) :: flag_cice logical, intent(in) :: frac_grid logical, intent(in) :: do_mynnsfclay + logical, intent(in) :: exticeden logical, intent(in) :: rdlai @@ -418,7 +419,7 @@ subroutine lsm_ruc_run & ! inputs ! --- in real (kind=kind_phys), dimension(:), intent(in) :: & - & rainnc, rainc, ice, snow, graupel + & rainnc, rainc, ice, snow, graupel, rhonewsn1 ! --- in/out: ! --- on RUC levels real (kind=kind_phys), dimension(:,:), intent(inout) :: & @@ -494,7 +495,8 @@ subroutine lsm_ruc_run & ! inputs & soilt_lnd, tbot, & & xlai, swdn, z0_lnd, znt_lnd, rhosnfr, infiltr, & & precipfr, snfallac_lnd, acsn, & - & qsfc_lnd, qsg_lnd, qvg_lnd, qcg_lnd, soilt1_lnd, chklowq + & qsfc_lnd, qsg_lnd, qvg_lnd, qcg_lnd, soilt1_lnd, chklowq, & + & rhonewsn ! ice real (kind=kind_phys),dimension (im,1) :: & & albbck_ice, alb_ice, chs_ice, flhc_ice, flqc_ice, & @@ -746,7 +748,7 @@ subroutine lsm_ruc_run & ! inputs acrunoff(i,j) = 0.0 snfallac_lnd(i,j) = 0.0 snfallac_ice(i,j) = 0.0 - rhosnfr(i,j) = 0.0 + rhosnfr(i,j) = -1.e3 precipfr(i,j) = 0.0 endif @@ -845,6 +847,7 @@ 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) + rhonewsn(i,j) = rhonewsn1(i) if (debug_print) then !-- diagnostics for a test point with known lat/lon if (abs(xlat_d(i)-testptlat).lt.2.5 .and. & @@ -1120,12 +1123,12 @@ subroutine lsm_ruc_run & ! inputs & zs, prcp(i,j), sneqv_lnd(i,j), snowh_lnd(i,j), & & sncovr_lnd(i,j), & & ffrozp(i,j), frpcpn, & - & rhosnfr(i,j), precipfr(i,j), & + & rhosnfr(i,j), precipfr(i,j), exticeden, & ! --- inputs: & conflx2(i,1,j), sfcprs(i,1,j), sfctmp(i,1,j), q2(i,1,j), & & qcatm(i,1,j), rho2(i,1,j), semis_bck(i,j), lwdn(i,j), & & swdn(i,j), solnet_lnd(i,j), sfcems_lnd(i,j), chklowq(i,j), & - & chs_lnd(i,j), flqc_lnd(i,j), flhc_lnd(i,j), & + & chs_lnd(i,j), flqc_lnd(i,j), flhc_lnd(i,j), rhonewsn(i,j), & ! --- input/outputs: & wet(i,j), cmc(i,j), shdfac(i,j), alb_lnd(i,j), znt_lnd(i,j), & & z0_lnd(i,j), snoalb1d_lnd(i,j), albbck_lnd(i,j), & @@ -1394,12 +1397,12 @@ subroutine lsm_ruc_run & ! inputs & zs, prcp(i,j), sneqv_ice(i,j), snowh_ice(i,j), & & sncovr_ice(i,j), & & ffrozp(i,j), frpcpn, & - & rhosnfr(i,j), precipfr(i,j), & + & rhosnfr(i,j), precipfr(i,j), exticeden, & ! --- inputs: & conflx2(i,1,j), sfcprs(i,1,j), sfctmp(i,1,j), q2(i,1,j), & & qcatm(i,1,j), rho2(i,1,j), semis_bck(i,j), lwdn(i,j), & & swdn(i,j), solnet_ice(i,j), sfcems_ice(i,j), chklowq(i,j), & - & chs_ice(i,j), flqc_ice(i,j), flhc_ice(i,j), & + & chs_ice(i,j), flqc_ice(i,j), flhc_ice(i,j), rhonewsn(i,j), & ! --- input/outputs: & wet_ice(i,j), cmc(i,j), shdfac(i,j), alb_ice(i,j), & & znt_ice(i,j), z0_ice(i,j), snoalb1d_ice(i,j), & diff --git a/physics/lsm_ruc.meta b/physics/lsm_ruc.meta index 587fda681..0d22f8d4a 100644 --- a/physics/lsm_ruc.meta +++ b/physics/lsm_ruc.meta @@ -634,6 +634,13 @@ dimensions = () type = logical intent = in +[exticeden] + standard_name = do_external_surface_frozen_precipitation_density + long_name = flag for calculating frozen precip ice density outside of the LSM + units = flag + dimensions = () + type = logical + intent = in [lsoil_ruc] standard_name = vertical_dimension_of_soil_internal_to_land_surface_scheme long_name = number of soil layers internal to land surface model @@ -952,6 +959,14 @@ type = real kind = kind_phys intent = in +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [con_cp] standard_name = specific_heat_of_dry_air_at_constant_pressure long_name = specific heat !of dry air at constant pressure @@ -1505,7 +1520,7 @@ kind = kind_phys intent = out [rhosnf] - standard_name = frozen_precipitation_density + standard_name = lsm_internal_surface_frozen_precipitation_density long_name = density of frozen precipitation units = kg m-3 dimensions = (horizontal_loop_extent) diff --git a/physics/module_mp_thompson.F90 b/physics/module_mp_thompson.F90 index 70c48feba..b828c9ab0 100644 --- a/physics/module_mp_thompson.F90 +++ b/physics/module_mp_thompson.F90 @@ -1003,7 +1003,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & ids,ide, jds,jde, kds,kde, & ! domain dims ims,ime, jms,jme, kms,kme, & ! memory dims its,ite, jts,jte, kts,kte, & ! tile dims - reset_dBZ, istep, nsteps, & + fullradar_diag, istep, nsteps, & errmsg, errflg, & ! Extended diagnostics, array pointers ! only associated if ext_diag flag is .true. @@ -1070,7 +1070,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & INTEGER, INTENT(IN) :: decfl ! To support subcycling: current step and maximum number of steps INTEGER, INTENT (IN) :: istep, nsteps - LOGICAL, INTENT (IN) :: reset_dBZ + LOGICAL, INTENT (IN) :: fullradar_diag ! Extended diagnostics, array pointers only associated if ext_diag flag is .true. LOGICAL, INTENT (IN) :: ext_diag LOGICAL, OPTIONAL, INTENT(IN):: aero_ind_fdb @@ -1677,7 +1677,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & if (diagflag .and. do_radar_ref == 1) then ! ! Only set melti to true at the output times - if (reset_dBZ) then + if (fullradar_diag) then melti=.true. else melti=.false. diff --git a/physics/module_sf_noahmplsm.f90 b/physics/module_sf_noahmplsm.f90 index 1da30f156..5146c56e6 100644 --- a/physics/module_sf_noahmplsm.f90 +++ b/physics/module_sf_noahmplsm.f90 @@ -218,6 +218,7 @@ module module_sf_noahmplsm real (kind=kind_phys) :: saim(12) !< monthly stem area index, one-sided real (kind=kind_phys) :: laim(12) !< monthly leaf area index, one-sided real (kind=kind_phys) :: sla !< single-side leaf area per kg [m2/kg] + real (kind=kind_phys) :: prcpiceden !< precipitation ice density [kg/m^3] real (kind=kind_phys) :: dilefc !< coeficient for leaf stress death [1/s] real (kind=kind_phys) :: dilefw !< coeficient for leaf stress death [1/s] real (kind=kind_phys) :: fragr !< fraction of growth respiration !original was 0.3 @@ -1068,13 +1069,14 @@ subroutine atm (parameters,sfcprs ,sfctmp ,q2 , ! fresh snow density bdfall = min(120.,67.92+51.25*exp((sfctmp-tfrz)/2.59)) !mb/an: change to min - if(opt_snf == 4) then + if(opt_snf == 4 .or. opt_snf == 5) then prcp_frozen = prcpsnow + prcpgrpl + prcphail if(prcpnonc > 0. .and. prcp_frozen > 0.) then fpice = min(1.0,prcp_frozen/prcpnonc) fpice = max(0.0,fpice) - bdfall = bdfall*(prcpsnow/prcp_frozen) + rho_grpl*(prcpgrpl/prcp_frozen) + & - rho_hail*(prcphail/prcp_frozen) + if(opt_snf==4) bdfall = bdfall*(prcpsnow/prcp_frozen) + rho_grpl*(prcpgrpl/prcp_frozen) + & + rho_hail*(prcphail/prcp_frozen) + if(opt_snf==5) bdfall = parameters%prcpiceden else fpice = 0.0 endif diff --git a/physics/module_sf_ruclsm.F90 b/physics/module_sf_ruclsm.F90 index 9a6363c08..cf0d6f015 100644 --- a/physics/module_sf_ruclsm.F90 +++ b/physics/module_sf_ruclsm.F90 @@ -54,11 +54,11 @@ SUBROUTINE LSMRUC( & DT,init,lsm_cold_start,KTAU,iter,NSL, & graupelncv,snowncv,rainncv,raincv, & ZS,RAINBL,SNOW,SNOWH,SNOWC,FRZFRAC,frpcpn, & - rhosnf,precipfr, & + rhosnf,precipfr,exticeden, & Z3D,P8W,T3D,QV3D,QC3D,RHO3D,EMISBCK, & GLW,GSWdn,GSW,EMISS,CHKLOWQ, CHS, & - FLQC,FLHC,MAVAIL,CANWAT,VEGFRA,ALB,ZNT, & - Z0,SNOALB,ALBBCK,LAI, & + FLQC,FLHC,rhonewsn_ex,MAVAIL,CANWAT,VEGFRA, & + ALB, ZNT,Z0,SNOALB,ALBBCK,LAI, & landusef, nlcat, & ! mosaic_lu, mosaic_soil, & soilctop, nscat, & QSFC,QSG,QVG,QCG,DEW,SOILT1,TSNAV, & @@ -157,7 +157,7 @@ SUBROUTINE LSMRUC( & ! INTEGER, PARAMETER :: nddzs=2*(nzss-2) REAL, INTENT(IN ) :: DT - LOGICAL, INTENT(IN ) :: myj,frpcpn,init,lsm_cold_start + LOGICAL, INTENT(IN ) :: myj,frpcpn,init,lsm_cold_start,exticeden INTEGER, INTENT(IN ) :: NLCAT, NSCAT ! , mosaic_lu, mosaic_soil INTEGER, INTENT(IN ) :: ktau, iter, nsl, isice, iswater, & ims,ime, jms,jme, kms,kme, & @@ -191,7 +191,8 @@ SUBROUTINE LSMRUC( & INTENT(IN ) :: GRAUPELNCV, & SNOWNCV, & RAINCV, & - RAINNCV + RAINNCV, & + RHONEWSN_ex !externally-calculated srf frz precip density ! REAL, DIMENSION( ims:ime , jms:jme ), & ! INTENT(IN ) :: lakemask ! INTEGER, INTENT(IN ) :: LakeModel @@ -895,8 +896,8 @@ SUBROUTINE LSMRUC( & nzs,nddzs,nroot,meltfactor, & !added meltfactor iland,isoil,ivgtyp(i,j),isltyp(i,j), & PRCPMS, NEWSNMS,SNWE,SNHEI,SNOWFRAC, & - RHOSN,RHONEWSN,RHOSNFALL, & - snowrat,grauprat,icerat,curat, & + exticeden,RHOSN,RHONEWSN_ex(I,J),RHONEWSN, & + RHOSNFALL,snowrat,grauprat,icerat,curat, & PATM,TABS,QVATM,QCATM,RHO, & GLW(I,J),GSWdn(i,j),GSW(I,J), & EMISSL(I,J),EMISBCK(I,J), & @@ -1162,7 +1163,7 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia nzs,nddzs,nroot,meltfactor, & ILAND,ISOIL,IVGTYP,ISLTYP,PRCPMS, & NEWSNMS,SNWE,SNHEI,SNOWFRAC, & - RHOSN,RHONEWSN,RHOSNFALL, & + exticeden,RHOSN,RHONEWSN_ex,RHONEWSN,RHOSNFALL, & snowrat,grauprat,icerat,curat, & PATM,TABS,QVATM,QCATM,rho, & GLW,GSWdn,GSW,EMISS,EMISBCK,QKMS,TKMS,PC, & @@ -1190,8 +1191,8 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia nddzs !nddzs=2*(nzs-2) REAL, INTENT(IN ) :: DELT,CONFLX,meltfactor - REAL, INTENT(IN ) :: C1SN,C2SN - LOGICAL, INTENT(IN ) :: myj, debug_print + REAL, INTENT(IN ) :: C1SN,C2SN,RHONEWSN_ex + LOGICAL, INTENT(IN ) :: myj, debug_print, exticeden !--- 3-D Atmospheric variables REAL , & INTENT(IN ) :: PATM, & @@ -1281,9 +1282,9 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia EETA, & EVAPL, & INFILTR, & - RHOSN, & + RHOSN, & RHONEWSN, & - rhosnfall, & + rhosnfall, & snowrat, & grauprat, & icerat, & @@ -1494,19 +1495,22 @@ SUBROUTINE SFCTMP (debug_print, delt,ktau,conflx,i,j, & !--- input varia !--- 27 Feb 2014 - empirical formulations from John M. Brown ! rhonewsn=min(250.,rhowater/max(4.179,(13.*tanh((274.15-Tabs)*0.3333)))) !--- 13 Mar 2018 - formulation from Trevor Elcott + if (exticeden) then + rhonewsn = rhonewsn_ex + else rhonewsn=min(125.,1000.0/max(8.,(17.*tanh((276.65-Tabs)*0.15)))) rhonewgr=min(500.,rhowater/max(2.,(3.5*tanh((274.15-Tabs)*0.3333)))) rhonewice=rhonewsn - !--- compute density of "snowfall" from weighted contribution ! of snow, graupel and ice fractions - rhosnfall = min(500.,max(58.8,(rhonewsn*snowrat + & + rhosnfall = min(500.,max(58.8,(rhonewsn*snowrat + & !13mar18 rhosnfall = min(500.,max(76.9,(rhonewsn*snowrat + & rhonewgr*grauprat + rhonewice*icerat + rhonewgr*curat))) ! from now on rhonewsn is the density of falling frozen precipitation - rhonewsn=rhosnfall + rhonewsn=rhosnfall + end if !*** Define average snow density of the snow pack considering !*** the amount of fresh snow (eq. 9 in Koren et al.(1999) diff --git a/physics/mp_thompson.F90 b/physics/mp_thompson.F90 index 727098a05..e62e8a596 100644 --- a/physics/mp_thompson.F90 +++ b/physics/mp_thompson.F90 @@ -326,8 +326,8 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & dt_inner, & first_time_step, istep, nsteps, & prcp, rain, graupel, ice, snow, sr, & - refl_10cm, reset_dBZ, do_radar_ref, & - aerfld, & + refl_10cm, fullradar_diag, & + do_radar_ref, aerfld, & mpicomm, mpirank, mpiroot, blkno, & ext_diag, diag3d, reset_diag3d, & spp_wts_mp, spp_mp, n_var_spp, & @@ -357,7 +357,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & real(kind_phys), intent(inout) :: ni(:,:) real(kind_phys), intent(inout) :: nr(:,:) ! Aerosols - logical, intent(in) :: is_aerosol_aware, reset_dBZ + logical, intent(in) :: is_aerosol_aware, fullradar_diag logical, intent(in) :: merra2_aerosol_aware real(kind_phys), optional, intent(inout) :: nc(:,:) real(kind_phys), optional, intent(inout) :: nwfa(:,:) @@ -705,7 +705,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, & ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, & its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, & - reset_dBZ=reset_dBZ, istep=istep, nsteps=nsteps, & + fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, & first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, & ! Extended diagnostics ext_diag=ext_diag, & @@ -744,7 +744,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, & ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, & its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, & - reset_dBZ=reset_dBZ, istep=istep, nsteps=nsteps, & + fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, & first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, & ! Extended diagnostics ext_diag=ext_diag, & diff --git a/physics/mp_thompson.meta b/physics/mp_thompson.meta index 1f459bb88..691698281 100644 --- a/physics/mp_thompson.meta +++ b/physics/mp_thompson.meta @@ -610,9 +610,9 @@ type = real kind = kind_phys intent = out -[reset_dBZ] - standard_name = flag_for_resetting_radar_reflectivity_calculation - long_name = flag for resetting radar reflectivity calculation +[fullradar_diag] + standard_name = do_full_radar_reflectivity + long_name = flag for computing full radar reflectivity units = flag dimensions = () type = logical diff --git a/physics/noahmpdrv.F90 b/physics/noahmpdrv.F90 index fed823ead..e223ffbec 100644 --- a/physics/noahmpdrv.F90 +++ b/physics/noahmpdrv.F90 @@ -138,7 +138,7 @@ subroutine noahmpdrv_run & idveg, iopt_crs, iopt_btr, iopt_run, iopt_sfc, iopt_frz, & iopt_inf, iopt_rad, iopt_alb, iopt_snf, iopt_tbot, & iopt_stc, iopt_trs,xlatin, xcoszin, iyrlen, julian, garea, & - rainn_mp, rainc_mp, snow_mp, graupel_mp, ice_mp, & + rainn_mp, rainc_mp, snow_mp, graupel_mp, ice_mp, rhonewsn1,& con_hvap, con_cp, con_jcal, rhoh2o, con_eps, con_epsm1, & con_fvirt, con_rd, con_hfus, thsfc_loc, & @@ -262,6 +262,7 @@ subroutine noahmpdrv_run & real(kind=kind_phys), dimension(:) , intent(in) :: snow_mp ! microphysics snow [mm] real(kind=kind_phys), dimension(:) , intent(in) :: graupel_mp ! microphysics graupel [mm] real(kind=kind_phys), dimension(:) , intent(in) :: ice_mp ! microphysics ice/hail [mm] + real(kind=kind_phys), dimension(:) , intent(in) :: rhonewsn1 ! precipitation ice density (kg/m^3) real(kind=kind_phys) , intent(in) :: con_hvap ! latent heat condensation [J/kg] real(kind=kind_phys) , intent(in) :: con_cp ! specific heat air [J/kg/K] real(kind=kind_phys) , intent(in) :: con_jcal ! joules per calorie (not used) @@ -757,7 +758,7 @@ subroutine noahmpdrv_run & call transfer_mp_parameters(vegetation_category, soil_category, & slope_category, soil_color_category, crop_type,parameters) - + parameters%prcpiceden = rhonewsn1(i) call noahmp_options(idveg ,iopt_crs, iopt_btr , iopt_run, iopt_sfc, & iopt_frz, iopt_inf , iopt_rad, iopt_alb, & iopt_snf, iopt_tbot, iopt_stc, iopt_rsf, & diff --git a/physics/noahmpdrv.meta b/physics/noahmpdrv.meta index 3235b7c90..b8c4a8307 100644 --- a/physics/noahmpdrv.meta +++ b/physics/noahmpdrv.meta @@ -532,6 +532,14 @@ type = real kind = kind_phys intent = in +[rhonewsn1] + standard_name = surface_frozen_precipitation_density + long_name = density of precipitation ice + units = kg m-3 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [con_hvap] standard_name = latent_heat_of_vaporization_of_water_at_0C long_name = latent heat of evaporation/sublimation diff --git a/physics/sflx.f b/physics/sflx.f index a020e217a..df22d128f 100644 --- a/physics/sflx.f +++ b/physics/sflx.f @@ -116,6 +116,7 @@ subroutine gfssflx &! --- input & swdn, swnet, lwdn, sfcems, sfcprs, sfctmp, & & sfcspd, prcp, q2, q2sat, dqsdt2, th2, ivegsrc, & & vegtyp, soiltyp, slopetyp, shdmin, alb, snoalb, & + & rhonewsn, exticeden, & & bexpp, xlaip, & ! sfc-perts, mgehne & lheatstrg, &! --- input/outputs: & tbot, cmc, t1, stc, smc, sh2o, sneqv, ch, cm,z0, &! --- outputs: @@ -310,9 +311,9 @@ subroutine gfssflx &! --- input real (kind=kind_phys), intent(in) :: ffrozp, dt, zlvl, lwdn, & & sldpth(nsoil), swdn, swnet, sfcems, sfcprs, sfctmp, & & sfcspd, prcp, q2, q2sat, dqsdt2, th2, shdmin, alb, snoalb, & - & bexpp, xlaip & !sfc-perts, mgehne + & bexpp, xlaip, rhonewsn & !sfc-perts, mgehne - logical, intent(in) :: lheatstrg + logical, intent(in) :: lheatstrg, exticeden ! --- input/outputs: real (kind=kind_phys), intent(inout) :: tbot, cmc, t1, sneqv, & @@ -564,7 +565,7 @@ subroutine gfssflx &! --- input !! using old and new snow. call snow_new ! --- inputs: ! -! ( sfctmp, sn_new, ! +! ( sfctmp, sn_new, rhonewsn, exticeden, ! ! --- input/outputs: ! ! snowh, sndens ) ! @@ -877,7 +878,11 @@ subroutine gfssflx &! --- input ! smc, ssoil, runoff1, runoff2, runoff3, edir, ec, et, ! ! ett, snomlt, drip, dew, flx1, flx3, esnow ) ! +! run-total accumulated snow based on snowfall and snowmelt in [m] + endif + + !> - Noah LSM post-processing: !> - Calculate sensible heat (h) for return to parent model. @@ -2851,7 +2856,7 @@ end subroutine snopac subroutine snow_new !................................... ! --- inputs: -! & ( sfctmp, sn_new, & +! & ( sfctmp, sn_new, rhonewsn, exticeden, & ! --- input/outputs: ! & snowh, sndens & ! & ) @@ -2900,10 +2905,14 @@ subroutine snow_new ! snowcovered and glacierized basin', 6th nordic hydrological ! conference, vemadolen, sweden, 1980, 172-177pp. - if (tempc <= -15.0) then - dsnew = 0.05 + if(.not. exticeden) then + if (tempc <= -15.0) then + dsnew = 0.05 + else + dsnew = 0.05 + 0.0017*(tempc + 15.0)**1.5 + endif else - dsnew = 0.05 + 0.0017*(tempc + 15.0)**1.5 + dsnew = rhonewsn*0.001 endif ! --- ... adjustment of snow density depending on new snowfall