diff --git a/Makefile b/Makefile index cd1fec6b90..a3ee03db5e 100644 --- a/Makefile +++ b/Makefile @@ -584,6 +584,7 @@ em_real : wrf ln -sf ../../run/ishmael-qi-qc.bin . ; \ ln -sf ../../run/ishmael-qi-qr.bin . ; \ ln -sf ../../run/BROADBAND_CLOUD_GODDARD.bin . ; \ + ln -sf ../../run/STOCHPERT.TBL . ; \ if [ $(RWORDSIZE) -eq 8 ] ; then \ ln -sf ../../run/ETAMPNEW_DATA_DBL ETAMPNEW_DATA ; \ ln -sf ../../run/ETAMPNEW_DATA.expanded_rain_DBL ETAMPNEW_DATA.expanded_rain ; \ @@ -659,6 +660,7 @@ em_real : wrf ln -sf ../../run/ishmael-qi-qc.bin . ; \ ln -sf ../../run/ishmael-qi-qr.bin . ; \ ln -sf ../../run/BROADBAND_CLOUD_GODDARD.bin . ; \ + ln -sf ../../run/STOCHPERT.TBL . ; \ if [ $(RWORDSIZE) -eq 8 ] ; then \ ln -sf ../../run/ETAMPNEW_DATA_DBL ETAMPNEW_DATA ; \ ln -sf ../../run/ETAMPNEW_DATA.expanded_rain_DBL ETAMPNEW_DATA.expanded_rain ; \ diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index 114d35877b..1a981d42bc 100644 --- a/Registry/Registry.EM_COMMON +++ b/Registry/Registry.EM_COMMON @@ -2547,6 +2547,7 @@ rconfig integer alevsiz_cu namelist,physics 1 1 rconfig integer aercu_opt namelist,physics 1 0 - "aercu_opt" "aerosol input option for multiscale KF" "" rconfig real aercu_fct namelist,physics 1 1.0 - "aercu_fct" "aerosol multiplication factor" "" rconfig integer aercu_used derived 1 0 - "aercu_used" "derived nml for packaging" "" +rconfig logical couple_farms namelist,physics 1 .false. - "couple_farms" "coupling FARMS radiation to land surface model" "" #BSINGH - added shallowcu_forced_ra, numBins, thBinSize, rBinSize, minDeepFreq, minShallowFreq, shcu_aerosols_opt for CuP scheme diff --git a/Registry/registry.dimspec b/Registry/registry.dimspec index 1df97c4f25..041bb2fefa 100644 --- a/Registry/registry.dimspec +++ b/Registry/registry.dimspec @@ -10,6 +10,7 @@ ifdef EM_CORE=1 ifdef DA_CORE=0 dimspec stoclev 2 namelist=num_stoch_levels z num_stoch_levels +dimspec pertn3d 4 namelist=num_pert_3d z num_pert_3d dimspec j 3 standard_domain y south_north dimspec k 2 standard_domain z bottom_top endif diff --git a/Registry/registry.stoch b/Registry/registry.stoch index 75c161d7b3..4a75680764 100644 --- a/Registry/registry.stoch +++ b/Registry/registry.stoch @@ -83,6 +83,82 @@ state real ALPH_RAND3 - misc 1 - - "A state real ALPH_RAND4 - misc 1 - - "ALPH_RAND4" "autoregressive coeff. for generic rand. pert." "" state logical did_stoch - misc 1 - r "DID_STOCH" "Logical to tell us that we already did the initialization for dom 1" "" + +# Variables for multi-pert table input +state real gridpt_stddev_mult3d {pertn3d} misc 1 - r "pert3d_std" "gridpoint standard deviation of random perturbations in mult3d" "" +state real stddev_cutoff_mult3d {pertn3d} misc 1 - r "pert3d_cut" "cutoff tails of pdf above this threshold standard deviation" "" +state real lengthscale_mult3d {pertn3d} misc 1 - r "pert3d_len" "Correlation length scale in meters for mult3d" "m" +state real timescale_mult3d {pertn3d} misc 1 - r "pert3d_tim" "Decorrelation time scale in s for mult3d" "s" +state integer mult3d_vertstruc {pertn3d} misc 1 - r "pert3d_ivs" "vertical structure for mult3d: 0=constant, 1=random phase" "" +state integer iseed_mult3d {pertn3d} misc 1 - r "pert3d_isd" "RANDOM SEED FOR mult3d " "" +state integer ISEEDARR_mult3d k{pertn3d} misc 1 - r "ISEEDARR_MULT3D" "Array to hold seed for restart, MULT3D_PERT" "" "" +state integer stepsp - misc 1 - r "stepsp" "Update perturbation every STEPSP time steps" + +# Namelist variables for multi-pert option +rconfig integer multi_perturb namelist,stoch max_domains 0 - "stochastic forcing option: 0=none, 1=multi-perturbation option" +rconfig logical pert_farms namelist,stoch max_domains .false. - "adding perturbations to FARMS scheme" +rconfig real pert_farms_albedo namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_farms_aod namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_farms_angexp namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_farms_aerasy namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_farms_qv namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_farms_qc namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_farms_qs namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig logical pert_deng namelist,stoch max_domains .false. - "adding perturbations to Deng scheme" +rconfig real pert_deng_qv namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_deng_qc namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_deng_t namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_deng_w namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig logical pert_mynn namelist,stoch max_domains .false. - "adding perturbations to MYNN scheme" +rconfig real pert_mynn_qv namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_mynn_qc namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_mynn_t namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_mynn_qke namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig logical pert_noah namelist,stoch max_domains .false. - "adding perturbations to Noah scheme" +rconfig real pert_noah_qv namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_noah_t namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_noah_smois namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_noah_tslb namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig logical pert_thom namelist,stoch max_domains .false. - "adding perturbations to Thompson scheme" +rconfig real pert_thom_qv namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_thom_qc namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_thom_qi namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_thom_qs namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_thom_ni namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig logical pert_cld3 namelist,stoch max_domains .false. - "adding perturbations to CLD3 scheme" +rconfig real pert_cld3_qv namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real pert_cld3_t namelist,stoch max_domains 0.0 - "turn on/off the perturbation" +rconfig real spdt namelist,stoch max_domains -1.0 - "Mins to update perts. If spdt<=0 => every time step." + +# Perturbation arrays for multi-pert option +state real SPFORCC3d i{pertn3d}j misc 1 XY r "SPFORCC3d" "real spect. coeff. of random perturbation field" "" "" +state real SPFORCS3d i{pertn3d}j misc 1 XY r "SPFORCS3d" "imag. spect. coeff. of random perturbation field" "" "" +state real SP_AMP3d i{pertn3d}j misc 1 - r "SP_AMP3d" "amplitude of random perturbation field" "" "" +state real ALPH_RAND3d {pertn3d} misc 1 - - "ALPH_RAND3d" "autoregressive coeff. for generic rand. pert." "" +state real VERTSTRUCC3d ikj{pertn3d} dyn_em 1 - r "VERTSTRUCC3d" "vertical structure for stoch. pert. forcing " "" +state real VERTSTRUCS3d ikj{pertn3d} dyn_em 1 - r "VERTSTRUCS3d" "vertical structure for stoch. pert. forcing " "" +state real VERTAMPT3d k{pertn3d} misc 1 - r "VERTAMPT3d" "vert. amplitude of stoch. temperature perturb." "" "" + +state real - i{stoclev}jf pert3d 1 - - +state real palbedo i{stoclev}jf pert3d 1 - h "PALBEDO" "" "" +state real paod i{stoclev}jf pert3d 1 - h "PAOD" "" "" +state real pangstrom i{stoclev}jf pert3d 1 - h "PANGSTROM" "" "" +state real passymfac i{stoclev}jf pert3d 1 - h "PASSYMFAC" "" "" +state real pqvapor i{stoclev}jf pert3d 1 - h "PQVAPOR" "" "" +state real pqcloud i{stoclev}jf pert3d 1 - h "PQCLOUD" "" "" +state real pqice i{stoclev}jf pert3d 1 - h "PQICE" "" "" +state real pqsnow i{stoclev}jf pert3d 1 - h "PQSNOW" "" "" +state real pni i{stoclev}jf pert3d 1 - h "PNI" "" "" +state real pth i{stoclev}jf pert3d 1 - h "PTH" "" "" +state real ptke i{stoclev}jf pert3d 1 - h "PTKE" "" "" +state real psmois i{stoclev}jf pert3d 1 - h "PSMOIS" "" "" +state real ptsoil i{stoclev}jf pert3d 1 - h "PTSOIL" "" "" +state real pw i{stoclev}jf pert3d 1 - h "PW" "" "" +state real p15 i{stoclev}jf pert3d 1 - h "P15" "" "" + +# Namelist parameters for multi-pert option +rconfig integer num_pert_3d namelist,stoch 1 15 - "num_pert_3d" "number of 3d random fields in STOCHPERT.TBL plue one" "" + # Namelist parameters for random number streams rconfig integer nens namelist,stoch 1 1 - "random number seed for ensemble members " "" "" @@ -188,3 +264,6 @@ package skebs_perturb skebs_on==1 - state:ru_tendf_stoch,rv_tendf_ package random_perturb rand_perturb_on==1 - state:rand_pert,SPFORCS,SPFORCC,SP_AMP,VERTSTRUCC,VERTSTRUCS,VERTAMPT,RAND_REAL,RAND_IMAG,RAND_REAL_xxx,RAND_REAL_yyy,RAND_IMAG_xxx,RAND_IMAG_yyy package stoch_param_perturb spp_on==1 - state:pattern_spp_conv,field_conv,SPFORCS2,SPFORCC2,SP_AMP2,pattern_spp_pbl,field_pbl,SPFORCS3,SPFORCC3,SP_AMP3,pattern_spp_lsm,field_sf,SPFORCS4,SPFORCC4,SP_AMP4,VERTSTRUCC,VERTSTRUCS,VERTAMPT,RAND_REAL,RAND_IMAG,RAND_REAL_xxx,RAND_REAL_yyy,RAND_IMAG_xxx,RAND_IMAG_yyy + +package multi_perturb multi_perturb==1 - state:SPFORCS3d,SPFORCC3d,SP_AMP3d,VERTSTRUCC3d,VERTSTRUCS3d,VERTAMPT3d,RAND_REAL,RAND_IMAG,RAND_REAL_xxx,RAND_REAL_yyy,RAND_IMAG_xxx,RAND_IMAG_yyy,stepsp;pert3d:palbedo,paod,pangstrom,passymfac,pqvapor,pqcloud,pqice,pqsnow,pni,pth,ptke,psmois,ptsoil,pw + diff --git a/clean b/clean index f31ad2bfcc..12378bde49 100755 --- a/clean +++ b/clean @@ -54,7 +54,7 @@ if ( "$arg" == '-a' || "$arg" == '-aa' ) then ( cd test ; rm -f */*.exe */ETAMPNEW_DATA* */GENPARM.TBL */LANDUSE.TBL */README.namelist */README.physics_files \ */RRTM_DATA */SOILPARM.TBL */VEGPARM.TBL */MPTABLE.TBL */URBPARM.TBL */URBPARM_LCZ.TBL */grib2map.tbl \ */CAM_ABS_DATA */CAM_AEROPT_DATA \ - */CCN_ACTIVATE.BIN \ + */CCN_ACTIVATE.BIN */STOCHPERT.TBL \ */CAMtr_volume_mixing_ratio.RCP4.5 */CAMtr_volume_mixing_ratio.RCP6 */CAMtr_volume_mixing_ratio.RCP8.5 \ */CAMtr_volume_mixing_ratio.A1B */CAMtr_volume_mixing_ratio.A2 */CAMtr_volume_mixing_ratio \ */CLM_*DATA */RRTMG_LW_DATA */RRTMG_SW_DATA \ diff --git a/dyn_em/module_first_rk_step_part1.F b/dyn_em/module_first_rk_step_part1.F index cdc8b6f876..d2ae68cddd 100644 --- a/dyn_em/module_first_rk_step_part1.F +++ b/dyn_em/module_first_rk_step_part1.F @@ -320,7 +320,30 @@ SUBROUTINE first_rk_step_part1 ( grid , config_flags & & ,swdown2=grid%swdown2, swddni2=grid%swddni2 & ! FARMS coupling & ,swddif2=grid%swddif2, swddir2=grid%swddir2 & ! FARMS coupling & ,swdownc2=grid%swdownc2, swddnic2=grid%swddnic2 & ! FARMS coupling + & ,couple_farms=config_flags%couple_farms & #endif +! WRF-Solar EPS: FARMS + & ,multi_perturb=config_flags% multi_perturb & + & ,pert_farms=config_flags%pert_farms & + & ,perts_albedo=grid%pert3d(:,:,:,P_PALBEDO) & + & ,perts_aod=grid%pert3d(:,:,:,P_PAOD) & + & ,perts_angstrom=grid%pert3d(:,:,:,P_PANGSTROM) & + & ,perts_assymfac=grid%pert3d(:,:,:,P_PASSYMFAC) & + & ,perts_qvapor=grid%pert3d(:,:,:,P_PQVAPOR) & + & ,perts_qcloud=grid%pert3d(:,:,:,P_PQCLOUD) & + & ,perts_qsnow=grid%pert3d(:,:,:,P_PQSNOW) & + & ,pert_farms_albedo=config_flags%pert_farms_albedo & + & ,pert_farms_aod=config_flags%pert_farms_aod & + & ,pert_farms_angexp=config_flags%pert_farms_angexp & + & ,pert_farms_aerasy=config_flags%pert_farms_aerasy & + & ,pert_farms_qv=config_flags%pert_farms_qv & + & ,pert_farms_qc=config_flags%pert_farms_qc & + & ,pert_farms_qs=config_flags%pert_farms_qs & +! WRF-Solar EPS: cld3 + & ,pert_cld3=config_flags%pert_cld3 & + & ,perts_th=grid%pert3d(:,:,:,P_PTH) & + & ,pert_cld3_qv=config_flags%pert_cld3_qv & + & ,pert_cld3_t=config_flags%pert_cld3_t & !BSINGH - For WRFCuP scheme & ,CU_PHYSICS=config_flags%cu_physics & !CuP, wig 5-Oct-2006 & ,SHALLOWCU_FORCED_RA=config_flags%shallowcu_forced_ra & !CuP, wig @@ -968,6 +991,17 @@ SUBROUTINE first_rk_step_part1 ( grid , config_flags & & ,spp_lsm=config_flags%spp_lsm,pattern_spp_lsm=grid%pattern_spp_lsm & !SPP & ,field_sf=grid%field_sf & !SPP & ,spp_pbl=config_flags%spp_pbl,pattern_spp_pbl=grid%pattern_spp_pbl & !SPP + ! WRF-Solar EPS: Noah LSM + & ,multi_perturb=config_flags% multi_perturb & + & ,pert_noah=config_flags%pert_noah & + & ,perts_qvapor=grid%pert3d(:,:,:,P_PQVAPOR) & + & ,perts_th=grid%pert3d(:,:,:,P_PTH) & + & ,perts_smois=grid%pert3d(:,:,:,P_PSMOIS) & + & ,perts_tsoil=grid%pert3d(:,:,:,P_PTSOIL) & + & ,pert_noah_qv=config_flags%pert_noah_qv & + & ,pert_noah_t=config_flags%pert_noah_t & + & ,pert_noah_smois=config_flags%pert_noah_smois & + & ,pert_noah_tslb=config_flags%pert_noah_tslb & & ) #ifdef WRF_HYDRO @@ -1146,6 +1180,17 @@ SUBROUTINE first_rk_step_part1 ( grid , config_flags & ! For Wind Turbine Drag Parameterizations & ,phb=grid%phb & & ,XLAT_U=grid%xlat_u,XLONG_U=grid%xlong_u & + ! WRF-Solar EPS: MYNN + & ,multi_perturb=config_flags%multi_perturb & + & ,pert_mynn=config_flags%pert_mynn & + & ,perts_qvapor=grid%pert3d(:,:,:,P_PQVAPOR) & + & ,perts_qcloud=grid%pert3d(:,:,:,P_PQCLOUD) & + & ,perts_th=grid%pert3d(:,:,:,P_PTH) & + & ,perts_tke=grid%pert3d(:,:,:,P_PTKE) & + & ,pert_mynn_qv=config_flags%pert_mynn_qv & + & ,pert_mynn_qc=config_flags%pert_mynn_qc & + & ,pert_mynn_t=config_flags%pert_mynn_t & + & ,pert_mynn_qke=config_flags%pert_mynn_qke & !Variables required for camuwpbl scheme & ,Z_AT_W=grid%z_at_w,CLDFRA_OLD_MP=grid%cldfra_old_mp & & ,CLDFRA=grid%cldfra & @@ -1507,6 +1552,17 @@ SUBROUTINE first_rk_step_part1 ( grid , config_flags & & ,qke=grid%qke & & ,PBLHAVG=grid%PBLHAVG, TKEAVG=grid%TKEAVG & & ,BL_PBL_PHYSICS=config_flags%bl_pbl_physics & + ! WRF-Solar EPS + & ,multi_perturb=config_flags%multi_perturb & + & ,pert_deng=config_flags%pert_deng & + & ,perts_qvapor=grid%pert3d(:,:,:,P_PQVAPOR) & + & ,perts_qcloud=grid%pert3d(:,:,:,P_PQCLOUD) & + & ,perts_th=grid%pert3d(:,:,:,P_PTH) & + & ,perts_w=grid%pert3d(:,:,:,P_PW) & + & ,pert_deng_qv=config_flags%pert_deng_qv & + & ,pert_deng_qc=config_flags%pert_deng_qc & + & ,pert_deng_t=config_flags%pert_deng_t & + & ,pert_deng_w=config_flags%pert_deng_w & & ) #if (WRF_CHEM == 1) diff --git a/dyn_em/module_first_rk_step_part2.F b/dyn_em/module_first_rk_step_part2.F index 518592858f..8f092ce794 100644 --- a/dyn_em/module_first_rk_step_part2.F +++ b/dyn_em/module_first_rk_step_part2.F @@ -60,7 +60,7 @@ SUBROUTINE first_rk_step_part2 ( grid , config_flags & USE module_physics_addtendc, ONLY : update_phy_ten USE module_sfs_driver !JDM - USE module_stoch, ONLY : update_stoch_ten, perturb_physics_tend,RAND_PERT_UPDATE + USE module_stoch, ONLY : update_stoch_ten, perturb_physics_tend, RAND_PERT_UPDATE, contiguize_2d IMPLICIT NONE @@ -138,11 +138,15 @@ SUBROUTINE first_rk_step_part2 ( grid , config_flags & INTEGER num_road_layers INTEGER iswater INTEGER rk_step + INTEGER n + LOGICAL :: stepsp_test #if ( WRF_DFI_RADAR == 1 ) INTEGER i_start,i_end,j_start,j_end,i,j,k #endif + REAL, DIMENSION(ims:ime,jms:jme) :: SPFORCS3d_loc, SPFORCC3d_loc, SP_AMP3d_loc + ! initialize all tendencies to zero in order to update physics ! tendencies first (separate from dry dynamics). @@ -254,6 +258,64 @@ SUBROUTINE first_rk_step_part2 ( grid , config_flags & grid%stddev_cutoff_rand_pert,grid%gridpt_stddev_rand_pert, & grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT ) ENDIF !rand_perturb_on + + IF ( grid%stepsp > 0 ) THEN + stepsp_test = ( MOD(grid%itimestep, grid%stepsp) == 0 ) + ELSE + stepsp_test = .FALSE. + END IF + If_multi_perturb: if ((config_flags%multi_perturb==1).and.(grid%id == 1) .and. & + (stepsp_test .or. grid%itimestep == 1)) then + Loop_multi_perturb: DO n = 2, config_flags%num_pert_3d + CALL contiguize_2d ( .TRUE. , grid%SPFORCS3d, SPFORCS3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .TRUE. , grid%SPFORCC3d, SPFORCC3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .TRUE. , grid%SP_AMP3d, SP_AMP3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL RAND_PERT_UPDATE(grid,'T', & + SPFORCS3d_loc, SPFORCC3d_loc, SP_AMP3d_loc, & + grid%ALPH_RAND3d(n), & + ips, ipe, jps, jpe, kps, kpe, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + k_start, k_end, & + imsx,imex,jmsx,jmex,kmsx,kmex, & + ipsx,ipex,jpsx,jpex,kpsx,kpex, & + imsy,imey,jmsy,jmey,kmsy,kmey, & + ipsy,ipey,jpsy,jpey,kpsy,kpey, & + grid%num_stoch_levels,grid%num_stoch_levels, & + grid%num_stoch_levels,grid%num_stoch_levels, & + config_flags%restart, grid%iseedarr_mult3d(:,n), & + config_flags%seed_dim, & + grid%DX,grid%DY,grid%mult3d_vertstruc(n), & + grid%PERT3D(:,:,:,n), & + grid%stddev_cutoff_mult3d(n), & + grid%gridpt_stddev_mult3d(n), & + grid%VERTSTRUCC3d(:,:,:,n), & + grid%VERTSTRUCS3d(:,:,:,n), & + grid%VERTAMPT3d(:,n) ) + CALL contiguize_2d ( .FALSE., grid%SPFORCS3d, SPFORCS3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .FALSE., grid%SPFORCC3d, SPFORCC3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .FALSE., grid%SP_AMP3d, SP_AMP3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + END DO Loop_multi_perturb + ENDIF If_multi_perturb + if ((grid%spp_conv==1).and.(grid%id .EQ. 1 )) then CALL RAND_PERT_UPDATE(grid,'T', & grid%SPFORCS2,grid%SPFORCC2, & diff --git a/dyn_em/module_stoch.F b/dyn_em/module_stoch.F index 1c3ba29ef9..5fd3c49567 100644 --- a/dyn_em/module_stoch.F +++ b/dyn_em/module_stoch.F @@ -108,8 +108,10 @@ SUBROUTINE INITIALIZE_STOCH (grid, config_flags, & ipsy, ipey, jpsy, jpey, kpsy, kpey ) + USE module_dm USE module_configure USE module_domain, ONLY : domain + USE module_wrf_error #ifdef DM_PARALLEL USE module_dm, ONLY : local_communicator, mytask, ntasks, ntasks_x, ntasks_y, local_communicator_periodic, & wrf_dm_maxval, wrf_err_message, local_communicator_x, local_communicator_y, data_order_xzy @@ -130,7 +132,15 @@ SUBROUTINE INITIALIZE_STOCH (grid, config_flags, & ipsy,ipey,jpsy,jpey,kpsy,kpey LOGICAL :: first_trip_for_this_domain - INTEGER :: K + INTEGER :: K, n, nfield, ierr, iseed, vertstruc, kvar + real :: std, lengthscale, timescale, std_cutoff + character (len = 10) :: varname + LOGICAL , EXTERNAL :: wrf_dm_on_monitor + INTEGER :: stochpert_unit + INTEGER , PARAMETER :: OPEN_OK = 0 + CHARACTER (len = 1024) :: message + logical, parameter :: DEBUG_MULTI_PERT = .true. + REAL, DIMENSION(ims:ime,jms:jme) :: SPFORCS3d_loc, SPFORCC3d_loc, SP_AMP3d_loc IF ( first_trip_for_this_domain ) THEN @@ -139,7 +149,8 @@ SUBROUTINE INITIALIZE_STOCH (grid, config_flags, & IF ((( grid%id == 1) .AND. (.NOT. grid%did_stoch)) .AND. & (( grid%skebs_on== 1) .OR.( grid%sppt_on== 1) .OR. ( grid%rand_perturb_on== 1) .OR. & - ( grid%spp_conv== 1) .OR. ( grid%spp_pbl== 1) .OR. ( grid%spp_lsm== 1)) ) THEN + ( grid%spp_conv== 1) .OR. ( grid%spp_pbl== 1) .OR. ( grid%spp_lsm== 1)) .or. & + (config_flags%multi_perturb == 1)) THEN grid%did_stoch = .TRUE. @@ -260,6 +271,183 @@ SUBROUTINE INITIALIZE_STOCH (grid, config_flags, & ENDIF !rand_perturb_on ENDIF + ! Initialize MULTI_PERTURB + If_multi_perturb: IF (config_flags%multi_perturb == 1) then + ! Set frequency to update perturbations: spdt is in min and dt is in s + grid%stepsp = nint (config_flags%spdt * 60.0 / grid%dt) + grid%stepsp = max (grid%stepsp, 1) + + ! Initialize perturbations + stochpert_unit = 97 + IF ( wrf_dm_on_monitor() ) THEN + OPEN(stochpert_unit, FILE='STOCHPERT.TBL',FORM='FORMATTED',STATUS='OLD',IOSTAT=ierr) + IF ( ierr .NE. OPEN_OK ) THEN + WRITE(message,FMT='(A)') & + 'module_stoch.F: INITIALIZE_STOCH: open failure for STOCHPERT.TBL' + CALL wrf_error_fatal ( message ) + END IF + REWIND(stochpert_unit) + ENDIF + + if (DEBUG_MULTI_PERT) print *, 'num_pert3d = ', num_pert3d + if (DEBUG_MULTI_PERT) print *, 'num_pert_3d = ', config_flags%num_pert_3d + ! Reads stoch table + if ( wrf_dm_on_monitor() ) then + READ (stochpert_unit,*) ! Skip + READ (stochpert_unit,*) ! the + READ (stochpert_unit,*) ! header + end if + DO n = 2, config_flags%num_pert_3d + IF ( wrf_dm_on_monitor() ) THEN + read (stochpert_unit, *) nfield, varname, std, lengthscale, timescale, std_cutoff, & + iseed, vertstruc + select case (trim(varname)) + case ('ALBEDO') + kvar = P_PALBEDO + + case ('AOD') + kvar = P_PAOD + + case ('ANGSTROM') + kvar = P_PANGSTROM + + case ('ASSYMFAC') + kvar = P_PASSYMFAC + + case ('QVAPOR') + kvar = P_PQVAPOR + + case ('QCLOUD') + kvar = P_PQCLOUD + + case ('QICE') + kvar = P_PQICE + + case ('QSNOW') + kvar = P_PQSNOW + + case ('NI') + kvar = P_PNI + + case ('TH') + kvar = P_PTH + + case ('TKE') + kvar = P_PTKE + + case ('SMOIS') + kvar = P_PSMOIS + + case ('TSOIL') + kvar = P_PTSOIL + + case ('W') + kvar = P_PW + + case default + WRITE(message,FMT='(A)') & + 'module_stoch.F: Invalid entry in STOCHPERT.TBL' + CALL wrf_error_fatal ( message ) + + end select + + grid%gridpt_stddev_mult3d(kvar) = std + grid%lengthscale_mult3d(kvar) = lengthscale + grid%timescale_mult3d(kvar) = timescale + grid%stddev_cutoff_mult3d(kvar) = std_cutoff + grid%ISEED_MULT3D(kvar) = iseed + grid%mult3d_vertstruc(kvar) = vertstruc + + if (DEBUG_MULTI_PERT) print *, kvar, varname, grid%gridpt_stddev_mult3d(kvar), & + grid%lengthscale_mult3d(kvar), grid%timescale_mult3d(kvar), & + grid%stddev_cutoff_mult3d(kvar), grid%ISEED_MULT3D(kvar), & + grid%mult3d_vertstruc(kvar) + ENDIF + ! Note that num_pert_3d is the dimension of the 1d arrays from the table + ! and num_pert3d is the number of allocated pert3d elements from the package (<= num_pert_3d) + CALL wrf_dm_bcast_bytes (grid%gridpt_stddev_mult3d, config_flags%num_pert_3d * RWORDSIZE ) + CALL wrf_dm_bcast_bytes (grid%lengthscale_mult3d, config_flags%num_pert_3d * RWORDSIZE ) + CALL wrf_dm_bcast_bytes (grid%timescale_mult3d, config_flags%num_pert_3d * RWORDSIZE ) + CALL wrf_dm_bcast_bytes (grid%stddev_cutoff_mult3d, config_flags%num_pert_3d * RWORDSIZE ) + CALL wrf_dm_bcast_bytes (grid%ISEED_MULT3D, config_flags%num_pert_3d * IWORDSIZE ) + CALL wrf_dm_bcast_bytes (grid%mult3d_vertstruc, config_flags%num_pert_3d * IWORDSIZE ) + END DO + + Loop_multi_perturb: DO n = 2, config_flags%num_pert_3d + CALL contiguize_2d ( .TRUE. , grid%SPFORCS3d, SPFORCS3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .TRUE. , grid%SPFORCC3d, SPFORCC3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .TRUE. , grid%SP_AMP3d, SP_AMP3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + if ((.not.config_flags%restart) .or. (.not.config_flags%hrrr_cycling)) then + call rand_seed (config_flags, grid%ISEED_MULT3D(n), grid%iseedarr_mult3d(:,n) , 1, config_flags%seed_dim) + endif + call SETUP_RAND_PERTURB('R', & + grid%mult3d_vertstruc(n),config_flags%restart, & + SP_AMP3d_loc,SPFORCC3d_loc,SPFORCS3d_loc, & + grid%ALPH_RAND3d(n), & + grid%VERTSTRUCC3d(:,:,:,n),grid%VERTSTRUCS3d(:,:,:,n),grid%VERTAMPT3d(:,n), & + grid%KMINFORCT,grid%KMAXFORCT, & + grid%LMINFORCT,grid%LMAXFORCT, & + grid%KMAXFORCTH,grid%LMAXFORCTH, & + grid%stepsp * grid%time_step,grid%DX,grid%DY, & + grid%gridpt_stddev_mult3d(n), & + grid%lengthscale_mult3d(n), & + grid%timescale_mult3d(n), & + grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, & + grid%REXPONENT_PSI, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + its, ite, jts, jte, kts, kte ) + +! if (.not.config_flags%restart) then ! spin up +! do k = 1,10 +! CALL RAND_PERT_UPDATE(grid,'R', & +! SPFORCS3d_loc,SPFORCC3d_loc,SP_AMP3d_loc, & +! grid%ALPH_RAND3d(n), & +! ips, ipe, jps, jpe, kps, kpe, & +! ids, ide, jds, jde, kds, kde, & +! ims, ime, jms, jme, kms, kme, & +! kts, kte, & +! imsx,imex,jmsx,jmex,kmsx,kmex, & +! ipsx,ipex,jpsx,jpex,kpsx,kpex, & +! imsy,imey,jmsy,jmey,kmsy,kmey, & +! ipsy,ipey,jpsy,jpey,kpsy,kpey, & +! grid%num_stoch_levels,grid%num_stoch_levels, & +! grid%num_stoch_levels,grid%num_stoch_levels, & +! config_flags%restart, grid%iseedarr_mult3d(:,n), & +! config_flags%seed_dim, & +! grid%DX,grid%DY,grid%mult3d_vertstruc(n), & +! grid%PERT3D(:,:,:,n), & +! grid%stddev_cutoff_mult3d(n), & +! grid%gridpt_stddev_mult3d(n), & +! grid%VERTSTRUCC3d(:,:,:,n),grid%VERTSTRUCS3d(:,:,:,n),grid%VERTAMPT3d(:,n) ) +! enddo +! end if + CALL contiguize_2d ( .FALSE., grid%SPFORCS3d, SPFORCS3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .FALSE., grid%SPFORCC3d, SPFORCC3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + CALL contiguize_2d ( .FALSE., grid%SP_AMP3d, SP_AMP3d_loc, n, & + ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, & + ids, ide, jds, jde, 1, config_flags%num_pert_3d, & + ims, ime, jms, jme, 1, config_flags%num_pert_3d ) + END DO Loop_multi_perturb + ENDIF If_multi_perturb + IF ( wrf_dm_on_monitor() ) CLOSE (stochpert_unit) + + ! Initialize Stochastic Parameter Perturbations to convection scheme IF (grid%spp_conv==1) then if (.not.config_flags%restart) then ! set random number seed (else iseedarray is read in from restart files) @@ -907,6 +1095,7 @@ end subroutine perturb_physics_tend ! This subroutine evolves the spectral pattern and transforms it back to gridpoint space. +!pajm SUBROUTINE RAND_PERT_UPDATE (grid, variable_in, & SPFORCS,SPFORCC,SP_AMP,ALPH_RAND, & ips, ipe, jps, jpe, kps, kpe, & @@ -926,6 +1115,7 @@ SUBROUTINE RAND_PERT_UPDATE (grid, variable_in, & USE module_domain, ONLY : domain +!pajm Do we need the following line USE module_state_description, ONLY : num_pert3d #ifdef DM_PARALLEL USE module_dm, ONLY : local_communicator, mytask, ntasks, ntasks_x, ntasks_y, local_communicator_periodic, & wrf_dm_maxval, wrf_err_message, local_communicator_x, local_communicator_y, data_order_xzy @@ -1357,5 +1547,41 @@ SUBROUTINE rand_seed (config_flags, iseed1, iseedarr, seed_start, seed_dim ) end if end SUBROUTINE rand_seed + +! ------------------------------------------------------------------ + + SUBROUTINE contiguize_2d ( in_out, d3, d2, n , & + ips, ipe, jps, jpe, kps, kpe, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme ) + IMPLICIT NONE + + LOGICAL, INTENT(IN) :: in_out ! d3->d2 = T; d2->d3 = F + INTEGER, INTENT(IN) :: n + INTEGER, INTENT(IN) :: ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + ips, ipe, jps, jpe, kps, kpe + + REAL, INTENT(INOUT), DIMENSION(ims:ime, jms:jme) :: d2 + REAL, INTENT(INOUT), DIMENSION(ims:ime,kms:kme,jms:jme) :: d3 + + INTEGER :: i, j + + IF ( in_out ) THEN + DO j = jms, jme + DO i = ims, ime + d2(i,j) = d3(i,n,j) + END DO + END DO + ELSE + DO j = jms, jme + DO i = ims, ime + d3(i,n,j) = d2(i,j) + END DO + END DO + END IF + + END SUBROUTINE contiguize_2d + ! ------------------------------------------------------------------ end module module_stoch diff --git a/dyn_em/solve_em.F b/dyn_em/solve_em.F index 13aa32fbd1..9045bcb54f 100644 --- a/dyn_em/solve_em.F +++ b/dyn_em/solve_em.F @@ -3893,7 +3893,20 @@ SUBROUTINE solve_em ( grid , config_flags & & ,WACT=grid%WACT,CCN1_GS=grid%CCN1_GS,CCN2_GS=grid%CCN2_GS,CCN3_GS=grid%CCN3_GS & & ,CCN4_GS=grid%CCN4_GS,CCN5_GS=grid%CCN5_GS,CCN6_GS=grid%CCN6_GS & & ,CCN7_GS=grid%CCN7_GS,NR_CU=grid%NR_CU,QR_CU=grid%QR_CU,NS_CU=grid%NS_CU & - & ,QS_CU=grid%QS_CU,CU_UAF=grid%CU_UAF,mskf_refl_10cm=grid%mskf_refl_10cm) + & ,QS_CU=grid%QS_CU,CU_UAF=grid%CU_UAF,mskf_refl_10cm=grid%mskf_refl_10cm & +! WRF-Solar EPS + & ,multi_perturb=config_flags%multi_perturb & + & ,pert_thom=config_flags%pert_thom & + & ,perts_qvapor=grid%pert3d(:,:,:,P_PQVAPOR) & + & ,perts_qcloud=grid%pert3d(:,:,:,P_PQCLOUD) & + & ,perts_qice=grid%pert3d(:,:,:,P_PQICE) & + & ,perts_qsnow=grid%pert3d(:,:,:,P_PQSNOW) & + & ,perts_ni=grid%pert3d(:,:,:,P_PNI) & + & ,pert_thom_qv=config_flags%pert_thom_qv & + & ,pert_thom_qc=config_flags%pert_thom_qc & + & ,pert_thom_qi=config_flags%pert_thom_qi & + & ,pert_thom_qs=config_flags%pert_thom_qs & + & ,pert_thom_ni=config_flags%pert_thom_ni ) BENCH_END(micro_driver_tim) diff --git a/phys/module_microphysics_driver.F b/phys/module_microphysics_driver.F index 5e8c1a0589..dd655929b8 100644 --- a/phys/module_microphysics_driver.F +++ b/phys/module_microphysics_driver.F @@ -2,6 +2,8 @@ ! *** add new modules of schemes here ! MODULE module_microphysics_driver + real, private, parameter :: QX_MIN = 1.E-12 + real, private, parameter :: NI_MIN = 1.E-6 CONTAINS SUBROUTINE microphysics_driver( & @@ -151,6 +153,11 @@ SUBROUTINE microphysics_driver( & ,CCN3_GS,CCN4_GS,CCN5_GS,CCN6_GS,CCN7_GS & ,NR_CU,QR_CU,NS_CU,QS_CU,CU_UAF,mskf_refl_10cm & # endif + ,multi_perturb & + ,pert_thom, perts_qvapor, perts_qcloud, perts_qice & + ,perts_qsnow, perts_ni & + ,pert_thom_qv,pert_thom_qc,pert_thom_qi & + ,pert_thom_qs,pert_thom_ni & ) ! Framework @@ -497,6 +504,14 @@ SUBROUTINE microphysics_driver( & INTENT(IN), OPTIONAL :: & qfx, & !Moisture flux at surface (kg m-2 s-1) rliq !Vertically-integrated reserved cloud condensate(m/s) + +! WRF-Solar EPS + integer, intent (in) :: multi_perturb + logical, intent (in) :: pert_thom + real, intent (in) :: pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, pert_thom_ni + real, dimension(ims:ime, kms:kme, jms:jme ), intent (in), optional :: perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni + real, dimension(:, :, :), allocatable :: qv_tmp, qc_tmp, qi_tmp, qs_tmp, qni_tmp !3D variables required for CAMMGMP scheme REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), & @@ -1001,6 +1016,19 @@ SUBROUTINE microphysics_driver( & #endif ! CASE (THOMPSONAERO) + if (pert_thom .and. multi_perturb == 1) then + allocate (qv_tmp(its:ite, kts:kte, jts:jte)) + allocate (qc_tmp(its:ite, kts:kte, jts:jte)) + allocate (qi_tmp(its:ite, kts:kte, jts:jte)) + allocate (qs_tmp(its:ite, kts:kte, jts:jte)) + allocate (qni_tmp(its:ite, kts:kte, jts:jte)) + + call Add_multi_perturb_mp_perturbations (perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni, pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, & + pert_thom_ni, qv_curr, qc_curr, qi_curr, qs_curr, qni_curr, qv_tmp, qc_tmp, qi_tmp, & + qs_tmp, qni_tmp, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + end if + CALL wrf_debug ( 100 , 'microphysics_driver: calling thompson' ) IF ( PRESENT( QV_CURR ) .AND. PRESENT ( QC_CURR ) .AND. & PRESENT( QR_CURR ) .AND. PRESENT ( QI_CURR ) .AND. & @@ -1064,6 +1092,19 @@ SUBROUTINE microphysics_driver( & 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) + + if (pert_thom .and. multi_perturb == 1) then + call Remove_multi_perturb_mp_perturbations (perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni, pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, & + pert_thom_ni, qv_curr, qc_curr, qi_curr, qs_curr, qni_curr, qv_tmp, qc_tmp, qi_tmp, & + qs_tmp, qni_tmp, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + deallocate (qv_tmp) + deallocate (qc_tmp) + deallocate (qi_tmp) + deallocate (qs_tmp) + deallocate (qni_tmp) + end if + ELSE CALL wrf_error_fatal ( 'arguments not present for calling thompson_et_al' ) ENDIF @@ -1083,6 +1124,19 @@ SUBROUTINE microphysics_driver( & qi_b4mp(its:ite,kts:kte,jts:jte) = qi_curr(its:ite,kts:kte,jts:jte) qs_b4mp(its:ite,kts:kte,jts:jte) = qs_curr(its:ite,kts:kte,jts:jte) #endif + if (pert_thom .and. multi_perturb == 1) then + allocate (qv_tmp(its:ite, kts:kte, jts:jte)) + allocate (qc_tmp(its:ite, kts:kte, jts:jte)) + allocate (qi_tmp(its:ite, kts:kte, jts:jte)) + allocate (qs_tmp(its:ite, kts:kte, jts:jte)) + allocate (qni_tmp(its:ite, kts:kte, jts:jte)) + + call Add_multi_perturb_mp_perturbations (perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni, pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, & + pert_thom_ni, qv_curr, qc_curr, qi_curr, qs_curr, qni_curr, qv_tmp, qc_tmp, qi_tmp, & + qs_tmp, qni_tmp, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + end if + CALL mp_gt_driver( & QV=qv_curr, & QC=qc_curr, & @@ -1124,6 +1178,19 @@ SUBROUTINE microphysics_driver( & 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) + + if (pert_thom .and. multi_perturb == 1) then + call Remove_multi_perturb_mp_perturbations (perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni, pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, & + pert_thom_ni, qv_curr, qc_curr, qi_curr, qs_curr, qni_curr, qv_tmp, qc_tmp, qi_tmp, & + qs_tmp, qni_tmp, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + deallocate (qv_tmp) + deallocate (qc_tmp) + deallocate (qi_tmp) + deallocate (qs_tmp) + deallocate (qni_tmp) + end if + ELSE CALL wrf_error_fatal ( 'arguments not present for calling thompson_et_al' ) ENDIF @@ -2893,4 +2960,71 @@ SUBROUTINE microphysics_driver( & END SUBROUTINE microphysics_driver + subroutine Add_multi_perturb_mp_perturbations (perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni, pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, & + pert_thom_ni, qv_curr, qc_curr, qi_curr, qs_curr, qni_curr, qv_tmp, qc_tmp, qi_tmp, & + qs_tmp, qni_tmp, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + real, intent(in) :: pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, pert_thom_ni + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: qv_curr, qc_curr, qi_curr, qs_curr, qni_curr + real, dimension (its:ite, kts:kte, jts:jte), intent (out) :: qv_tmp, qc_tmp, qi_tmp, qs_tmp, qni_tmp + + integer :: i, j, k + + + do j = jts, jte + do k = kts, kte + do i = its, ite + qv_tmp(i, k, j) = qv_curr(i, k, j) + qv_curr(i, k, j) = max (QX_MIN, (1.0 + perts_qvapor(i, k, j) * pert_thom_qv) * qv_curr(i, k, j)) + qc_tmp(i, k, j) = qc_curr(i, k, j) + qc_curr(i, k, j) = max (QX_MIN, (1.0 + perts_qcloud(i, k, j) * pert_thom_qc) * qc_curr(i, k, j)) + qi_tmp(i, k, j) = qi_curr(i, k, j) + qi_curr(i, k, j) = max (QX_MIN, (1.0 + perts_qice(i, k, j) * pert_thom_qi) * qi_curr(i, k, j)) + qs_tmp(i, k, j) = qs_curr(i, k, j) + qs_curr(i, k, j) = max (QX_MIN, (1.0 + perts_qsnow(i, k, j) * pert_thom_qs) * qs_curr(i, k, j)) + qni_tmp(i, k, j) = qni_curr(i, k, j) + qni_curr(i, k, j) = max (NI_MIN, (1.0 + perts_ni(i, k, j) * pert_thom_ni) * qni_curr(i, k, j)) + end do + end do + end do + + end subroutine Add_multi_perturb_mp_perturbations + + subroutine Remove_multi_perturb_mp_perturbations (perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni, pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, & + pert_thom_ni, qv_curr, qc_curr, qi_curr, qs_curr, qni_curr, qv_tmp, qc_tmp, qi_tmp, & + qs_tmp, qni_tmp, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + real, intent(in) :: pert_thom_qv, pert_thom_qc, pert_thom_qi, pert_thom_qs, pert_thom_ni + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, perts_qcloud, perts_qice, & + perts_qsnow, perts_ni + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: qv_curr, qc_curr, qi_curr, qs_curr, qni_curr + real, dimension (its:ite, kts:kte, jts:jte), intent (in) :: qv_tmp, qc_tmp, qi_tmp, qs_tmp, qni_tmp + + integer :: i, j, k + + + do j = jts, jte + do k = kts, kte + do i = its, ite + qv_curr(i, k, j) = max (QX_MIN, qv_curr(i, k, j) - perts_qvapor(i, k, j) * pert_thom_qv * qv_tmp(i, k, j)) + qc_curr(i, k, j) = max (QX_MIN, qc_curr(i, k, j) - perts_qcloud(i, k, j) * pert_thom_qc * qc_tmp(i, k, j)) + qi_curr(i, k, j) = max (QX_MIN, qi_curr(i, k, j) - perts_qice(i, k, j) * pert_thom_qi * qi_tmp(i, k, j)) + qs_curr(i, k, j) = max (QX_MIN, qs_curr(i, k, j) - perts_qsnow(i, k, j) * pert_thom_qs * qs_tmp(i, k, j)) + qni_curr(i, k, j) = max (NI_MIN, qni_curr(i, k, j) - perts_ni(i, k, j) * pert_thom_ni * qni_tmp(i, k, j)) + end do + end do + end do + + end subroutine Remove_multi_perturb_mp_perturbations + END MODULE module_microphysics_driver diff --git a/phys/module_pbl_driver.F b/phys/module_pbl_driver.F index 7d59fb3598..0f4bec1219 100644 --- a/phys/module_pbl_driver.F +++ b/phys/module_pbl_driver.F @@ -2,6 +2,9 @@ ! MODULE module_pbl_driver + real, private, parameter :: QCLOUD_MIN = 0.0 + real, private, parameter :: QVAPOR_MIN = 0.0 + real, private, parameter :: QKE_MIN = 1.e-4 CONTAINS !------------------------------------------------------------------ @@ -124,6 +127,14 @@ SUBROUTINE pbl_driver( & ,frac_up,rc_mf & ! Wind Turbine Parameterizations ,phb,xlat_u,xlong_u,xlat_v,xlong_v,id & +! WRF-Solar EPS + ,multi_perturb, pert_mynn & + ,perts_qvapor & + ,perts_qcloud & + ,perts_th & + ,perts_tke & + ,pert_mynn_qv, pert_mynn_qc, pert_mynn_t & + ,pert_mynn_qke & ! variables required for camuwpbl scheme , z_at_w,cldfra_old_mp,cldfra, rthratenlw & , tauresx2d,tauresy2d & @@ -471,8 +482,15 @@ SUBROUTINE pbl_driver( & u_phy, & v_phy, & dz8w, & - z, & - th_phy + z + REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT) :: th_phy + +! WRF-Solar EPS + integer, intent (in) :: multi_perturb + LOGICAL, intent (in) :: pert_mynn + real, intent (in) :: pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_qcloud, perts_th, perts_tke !1D variables required for CAMUWPBL scheme REAL , DIMENSION( kms:kme ) , & @@ -771,6 +789,7 @@ SUBROUTINE pbl_driver( & REAL, OPTIONAL, DIMENSION( ims:ime , jms:jme ), & !mchen INTENT(IN ) :: CTOPO, & CTOPO2 + real, dimension (:, :, :), allocatable :: qke_tmp ! Variables and Diagnostic for QNSE and EDKF JP INTEGER, INTENT(IN) :: mfshconv @@ -1729,6 +1748,15 @@ SUBROUTINE pbl_driver( & initflag=0 ENDIF + if (pert_mynn .and. multi_perturb == 1) then + allocate (qke_tmp(its:ite, kts:kte, jts:jte)) + + call Add_multi_perturb_pbl_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_tke, pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke, & + th_phy, qke, qke_adv, qv_curr, qc_curr, bl_mynn_tkeadvect, qke_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + end if + CALL mynn_bl_driver(& &initflag=initflag,restart=restart,cycling=cycling, & &grav_settling=grav_settling, & @@ -1786,6 +1814,15 @@ SUBROUTINE pbl_driver( & ,IMS=ims,IME=ime,JMS=jms,JME=jme,KMS=kms,KME=kme & ,ITS=its,ITE=ite,JTS=jts,JTE=jte,KTS=kts,KTE=kte & ) + + if (pert_mynn .and. multi_perturb == 1) then + call Remove_multi_perturb_pbl_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_tke, pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke, & + th_phy, qke, qke_adv, qv_curr, qc_curr, bl_mynn_tkeadvect, qke_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + + deallocate (qke_tmp) + end if ELSE WRITE ( message , FMT = '(A,20(L1,1X))' ) & 'present: '// & @@ -2256,6 +2293,109 @@ SUBROUTINE pbl_driver( & END SUBROUTINE pbl_driver + subroutine Add_multi_perturb_pbl_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_tke, pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke, & + th_phy, qke, qke_adv, qv_curr, qc_curr, bl_mynn_tkeadvect, qke_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + logical, optional, intent(in) :: bl_mynn_tkeadvect + real, intent(in) :: pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_qcloud, perts_th, perts_tke + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: th_phy, qke, qv_curr, qc_curr + real, optional, dimension (ims:ime, kms:kme, jms:jme), intent(inout) :: qke_adv + real, dimension (its:ite, kts:kte, jts:jte), intent(out) :: qke_tmp + + integer :: i, j, k + + + do j = jts, jte + do k = kts, kte + do i = its, ite + qc_curr(i, k, j) = max (QCLOUD_MIN, (1.0 + perts_qcloud(i, k, j) * pert_mynn_qc) * qc_curr(i, k, j)) + qv_curr(i, k, j) = max (QVAPOR_MIN, (1.0 + perts_qvapor(i, k, j) * pert_mynn_qv) * qv_curr(i, k, j)) + th_phy(i, k, j) = (1.0 + perts_th(i, k, j) * pert_mynn_t) * th_phy(i, k, j) + end do + end do + end do + + if (bl_mynn_tkeadvect) then + do j = jts, jte + do k = kts, kte + do i = its, ite + qke_tmp(i, k, j) = qke_adv(i, k, j) + qke_adv(i, k, j) = max (QKE_MIN, (1.0 + perts_tke(i, k, j) * pert_mynn_qke) * qke_adv(i, k, j)) + end do + end do + end do + else + do j = jts, jte + do k = kts, kte + do i = its, ite + qke_tmp(i, k, j) = qke(i, k, j) + qke(i, k, j) = max (QKE_MIN, (1.0 + perts_tke(i, k, j) * pert_mynn_qke) * qke(i, k, j)) + end do + end do + end do + end if + + end subroutine Add_multi_perturb_pbl_perturbations + + subroutine Remove_multi_perturb_pbl_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_tke, pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke, & + th_phy, qke, qke_adv, qv_curr, qc_curr, bl_mynn_tkeadvect, qke_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + logical, optional, intent(in) :: bl_mynn_tkeadvect + real, intent(in) :: pert_mynn_qv, pert_mynn_qc, pert_mynn_t, pert_mynn_qke + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_qcloud, perts_th, perts_tke + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: th_phy, qke, qv_curr, qc_curr + real, optional, dimension (ims:ime, kms:kme, jms:jme), intent(inout) :: qke_adv + real, dimension (its:ite, kts:kte, jts:jte), intent(in) :: qke_tmp + + integer :: i, j, k + + + do j = jts, jte + do k = kts, kte + do i = its, ite + qc_curr(i, k, j) = max (QCLOUD_MIN, qc_curr(i, k, j) / (1.0 + perts_qcloud(i, k, j) * pert_mynn_qc)) + qv_curr(i, k, j) = max (QVAPOR_MIN, qv_curr(i, k, j) / (1.0 + perts_qvapor(i, k, j) * pert_mynn_qv)) + th_phy(i, k, j) = th_phy(i, k, j) / (1.0 + perts_th(i, k, j) * pert_mynn_t) + end do + end do + end do + + if (bl_mynn_tkeadvect) then + do j = jts, jte + do k = kts, kte + do i = its, ite + qke_adv(i, k, j) = max (QKE_MIN, qke_adv(i, k, j) - perts_tke(i, k, j) * pert_mynn_qke * qke_tmp(i, k, j)) + qke(i, k, j) = qke_adv(i, k, j) + end do + end do + end do + else + do j = jts, jte + do k = kts, kte + do i = its, ite + qke(i, k, j) = max (QKE_MIN, qke(i, k, j) - perts_tke(i, k, j) * pert_mynn_qke * qke_tmp(i, k, j)) + end do + end do + end do + end if + + end subroutine Remove_multi_perturb_pbl_perturbations + !============================================================================= SUBROUTINE diff3d(DT,CP,DZ,TH ,QV,QC,T,U,V,RHO & ,EXCH_H,EXCH_M & diff --git a/phys/module_ra_farms.F b/phys/module_ra_farms.F index e54510c096..29d0054f95 100644 --- a/phys/module_ra_farms.F +++ b/phys/module_ra_farms.F @@ -26,7 +26,6 @@ module module_ra_farms real, parameter :: DE_ICE_MIN = 5.0, DE_ICE_MAX = 140.0 real, parameter :: DE_CLOUD_MIN = 5.0, DE_CLOUD_MAX = 120.0 real, parameter :: TAU_MIN = 0.0001, TAU_MAX = 300.0 - real, parameter :: AOD550_VAL = 0.12, ANGEXP_VAL = 1.3, AERSSA_VAL = 0.85, AERASY_VAL = 0.9 real, parameter :: RE_CLOUD_CLIM = 8.E-6, RE_ICE_CLIM = 24.E-6, RE_SNOW_CLIM = 24.E-6 contains @@ -182,18 +181,6 @@ subroutine Farms_driver (ims, ime, jms, jme, its, ite, jts, jte, kms, kme, kts, tau_qs = 0.0 end if - ! Aerosols - if (aer_opt == 1) then - angexp2d(i, j) = ANGEXP_VAL - aerssa2d(i, j) = AERSSA_VAL - aerasy2d(i, j) = AERASY_VAL - else if (aer_opt == 0) then - aod5502d(i, j) = 0.0 - angexp2d(i, j) = 0.0 - aerssa2d(i, j) = 0.0 - aerasy2d(i, j) = 0.0 - end if - beta = aod5502d(i, j) * (1000.0/ 550.0) ** (- angexp2d(i, j)) Call Farms (p8w(i, 1, j), albedo(i, j), aerssa2d(i, j), & diff --git a/phys/module_radiation_driver.F b/phys/module_radiation_driver.F index a4ff071b1e..455f19fb26 100644 --- a/phys/module_radiation_driver.F +++ b/phys/module_radiation_driver.F @@ -2,6 +2,8 @@ !WRF:MEDIATION_LAYER:PHYSICS ! MODULE module_radiation_driver + real, private, parameter :: ALBEDO_MIN = 0.0, ALBEDO_MAX = 1.0, ANGEXP_MIN = 0.0, AOD_MIN = 0.0, & + AERASY_MIN = -1.0, AERASY_MAX = 1.0, QVAPOR_MIN = 0.0, QCLOUD_MIN = 0.0, QSNOW_MIN = 0.0 CONTAINS !BOP ! !IROUTINE: radiation_driver - interface to radiation physics options @@ -51,6 +53,19 @@ SUBROUTINE radiation_driver ( & ,CURR_SECS, ADAPT_STEP_FLAG & ,SWDOWN2, SWDDNI2, SWDDIF2, SWDDIR2 & ,SWDOWNC2, SWDDNIC2 & + ,couple_farms & +! WRF-Solar EPS + ,multi_perturb & + ,pert_farms & + ,perts_albedo, perts_aod, perts_angstrom, perts_assymfac & + ,perts_qvapor, perts_qcloud, perts_qsnow & + ,pert_farms_albedo, pert_farms_aod & + ,pert_farms_angexp, pert_farms_aerasy & + ,pert_farms_qv, pert_farms_qc & + ,pert_farms_qs & + ,pert_cld3 & + ,perts_th & + ,pert_cld3_qv, pert_cld3_t & !BSINGH - For WRFCuP scheme (optional args) ,cu_physics,shallowcu_forced_ra & ,cubot,cutop,cldfra_cup & @@ -442,6 +457,13 @@ SUBROUTINE radiation_driver ( & integer, intent(in) :: swint_opt integer, intent(in), OPTIONAL :: solar_opt integer :: solar_opt_local + ! WRF-Solar EPS + integer, intent (in) :: multi_perturb + logical, intent (in) :: pert_farms, pert_cld3, couple_farms + real, intent (in) :: pert_farms_albedo, pert_farms_aod, pert_farms_angexp, pert_farms_aerasy, & + pert_farms_qv, pert_farms_qc, pert_farms_qs, pert_cld3_qv, pert_cld3_t + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_albedo, perts_aod, & + perts_angstrom, perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow, perts_th INTEGER, DIMENSION(num_tiles), INTENT(IN) :: & i_start,i_end,j_start,j_end @@ -628,8 +650,8 @@ SUBROUTINE radiation_driver ( & REAL, DIMENSION( ims:ime, jms:jme ), & INTENT(IN ) :: XLAT, & XLONG, & - ALBEDO, & EMISS + real, dimension (ims:ime, jms:jme), intent(inout) :: albedo ! REAL, DIMENSION( ims:ime, jms:jme ), & INTENT(INOUT) :: GSW, & @@ -907,6 +929,9 @@ SUBROUTINE radiation_driver ( & INTEGER, PARAMETER:: taer_ssa_opt = 3 ! input option for aerosol ssa INTEGER, PARAMETER:: taer_asy_opt = 3 ! input option for aerosol asy +! WRF-Solar EPS + real, dimension(:, :, :), allocatable :: qv_tmp, qc_tmp, qs_tmp + #if ( HWRF == 1 ) CHARACTER(len=255) :: wrf_err_message @@ -1354,8 +1379,13 @@ SUBROUTINE radiation_driver ( & DO k = kts,kte p_1d(k) = p(i,k,j) - t_1d(k) = t(i,k,j) - qv_1d(k) = qv(i,k,j) + if (pert_cld3 .and. multi_perturb == 1) then + t_1d(k) = (1.0 + perts_th(i, k, j) * pert_cld3_t) * t(i, k, j) + qv_1d(k) = max (0.0, (1.0 + perts_qvapor(i, k, j) * pert_cld3_qv) * qv(i, k, j)) + else + t_1d(k) = t(i,k,j) + qv_1d(k) = qv(i,k,j) + end if qc_1d(k) = qc(i,k,j) qi_1d(k) = qi(i,k,j) qs_1d(k) = qs(i,k,j) @@ -2830,13 +2860,55 @@ SUBROUTINE radiation_driver ( & if (swint_opt == 2) then call wrf_debug(100,'SW surface irradiance calculated with FARMS') - if (aer_opt == 1) then - DO j=jts,jte - DO i=its,ite - aod5502d(i, j) = aodtot(i, j) - ENDDO - ENDDO - end if + select case (aer_opt) + case (0) + !$OMP PARALLEL DO & + !$OMP PRIVATE (ij ,i, j, its, ite, jts, jte) + do ij = 1,num_tiles + its = i_start(ij) + ite = i_end(ij) + jts = j_start(ij) + jte = j_end(ij) + DO j=jts,jte + DO i=its,ite + aod5502d(i, j) = 0.0 + angexp2d(i, j) = 0.0 + aerssa2d(i, j) = 0.0 + aerasy2d(i, j) = 0.0 + ENDDO + ENDDO + end do + !$OMP END PARALLEL DO + + case (1) + !$OMP PARALLEL DO & + !$OMP PRIVATE (ij ,i, j, its, ite, jts, jte) + do ij = 1,num_tiles + its = i_start(ij) + ite = i_end(ij) + jts = j_start(ij) + jte = j_end(ij) + DO j=jts,jte + DO i=its,ite + aod5502d(i, j) = aodtot(i, j) + angexp2d(i, j) = aer_angexp_val + aerssa2d(i, j) = aer_ssa_val + aerasy2d(i, j) = aer_asy_val + ENDDO + ENDDO + end do + !$OMP END PARALLEL DO + + case (2) + continue + + case (3) + continue + + case default + CALL wrf_error_fatal('Unkonown aer_opt to FARMS. Only options 0, 1, 2, and 3 are supported.') + + end select !--------------- !$OMP PARALLEL DO & @@ -2846,13 +2918,55 @@ SUBROUTINE radiation_driver ( & ite = i_end(ij) jts = j_start(ij) jte = j_end(ij) + + if (pert_farms .and. multi_perturb == 1) then + allocate (qv_tmp(its:ite, kts:kte, jts:jte)) + allocate (qc_tmp(its:ite, kts:kte, jts:jte)) + allocate (qs_tmp(its:ite, kts:kte, jts:jte)) + + call Add_multi_perturb_swrad_perturbations (perts_albedo, perts_aod, perts_angstrom, & + perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow, pert_farms_albedo, pert_farms_aod, & + pert_farms_angexp, pert_farms_aerasy, pert_farms_qv, pert_farms_qc, pert_farms_qs, & + albedo, aod5502d, angexp2d, aerasy2d, qv, qc, qs, qv_tmp, qc_tmp, qs_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + end if + call farms_driver (ims, ime, jms, jme, its, ite, jts, jte, kms, kme, kts, kte, & p8w, rho, dz8w, albedo, aer_opt, aerssa2d, aerasy2d, aod5502d, angexp2d, & coszen_loc, qv, qi, qs, qc, re_cloud, re_ice, re_snow, & julian, swdown2, swddir2, swddni2, swddif2, swdownc2, swddnic2, & has_reqc, has_reqi, has_reqs, CLDFRA) + + if (pert_farms .and. multi_perturb == 1) then + call Remove_multi_perturb_swrad_perturbations (perts_albedo, perts_aod, perts_angstrom, & + perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow, pert_farms_albedo, pert_farms_aod, & + pert_farms_angexp, pert_farms_aerasy, pert_farms_qv, pert_farms_qc, pert_farms_qs, & + albedo, aod5502d, angexp2d, aerasy2d, qv, qc, qs, qv_tmp, qc_tmp, qs_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + + deallocate (qv_tmp) + deallocate (qc_tmp) + deallocate (qs_tmp) + end if enddo !$OMP END PARALLEL DO + + if (couple_farms) then + !$OMP PARALLEL DO & + !$OMP PRIVATE (ij, i, j, its, ite, jts, jte) + do ij = 1,num_tiles + its = i_start(ij) + ite = i_end(ij) + jts = j_start(ij) + jte = j_end(ij) + do j = jts, jte + do i = its, ite + swdown(i, j) = swdown2(i, j) + end do + end do + end do + !$OMP END PARALLEL DO + end if end if end if @@ -5347,4 +5461,91 @@ END SUBROUTINE gt_aod !+---+-----------------------------------------------------------------+ + subroutine Add_multi_perturb_swrad_perturbations (perts_albedo, perts_aod, perts_angstrom, & + perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow, pert_farms_albedo, pert_farms_aod, & + pert_farms_angexp, pert_farms_aerasy, pert_farms_qv, pert_farms_qc, pert_farms_qs, & + albedo, aod5502d, angexp2d, aerasy2d, qv, qc, qs, qv_tmp, qc_tmp, qs_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + real, intent(in) :: pert_farms_albedo, pert_farms_aod, pert_farms_angexp, pert_farms_aerasy, & + pert_farms_qv, pert_farms_qc, pert_farms_qs + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_albedo, perts_aod, perts_angstrom, & + perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: qv, qc, qs + real, dimension(ims:ime, jms:jme), intent (inout) :: albedo, aod5502d, angexp2d, aerasy2d + real, dimension (its:ite, kts:kte, jts:jte), intent(out) :: qv_tmp, qc_tmp, qs_tmp + + integer :: i, j, k + + + k = 1 + do j = jts, jte + do i = its, ite + albedo(i, j) = min (max (ALBEDO_MIN, (1.0 + perts_albedo(i, k, j) * pert_farms_albedo) * albedo(i, j)), AERASY_MAX) + angexp2d(i, j) = max (ANGEXP_MIN, (1.0 + perts_angstrom(i, k, j) * pert_farms_angexp) * angexp2d(i, j)) + aod5502d(i, j) = max (AOD_MIN, (1.0 + perts_aod(i, k, j) * pert_farms_aod) * aod5502d(i, j)) + aerasy2d(i, j) = min (max (AERASY_MIN, (1.0 + perts_assymfac(i, k, j) * pert_farms_aerasy) * aerasy2d(i, j)), AERASY_MAX) + end do + end do + + do j = jts, jte + do k = kts, kte + do i = its, ite + qv_tmp(i, k, j) = qv(i, k, j) + qv(i, k, j) = max (QVAPOR_MIN, (1.0 + perts_qvapor(i, k, j) * pert_farms_qv) * qv(i, k, j)) + qc_tmp(i, k, j) = qc(i, k, j) + qc(i, k, j) = max (QCLOUD_MIN, (1.0 + perts_qcloud(i, k, j) * pert_farms_qc) * qc(i, k, j)) + qs_tmp(i, k, j) = qs(i, k, j) + qs(i, k, j) = max (QSNOW_MIN, (1.0 + perts_qsnow(i, k, j) * pert_farms_qs) * qs(i, k, j)) + end do + end do + end do + + end subroutine Add_multi_perturb_swrad_perturbations + + subroutine Remove_multi_perturb_swrad_perturbations (perts_albedo, perts_aod, perts_angstrom, & + perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow, pert_farms_albedo, pert_farms_aod, & + pert_farms_angexp, pert_farms_aerasy, pert_farms_qv, pert_farms_qc, pert_farms_qs, & + albedo, aod5502d, angexp2d, aerasy2d, qv, qc, qs, qv_tmp, qc_tmp, qs_tmp, its, ite, jts, jte, & + ims, ime, jms, jme, kms, kme, kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + real, intent(in) :: pert_farms_albedo, pert_farms_aod, pert_farms_angexp, pert_farms_aerasy, & + pert_farms_qv, pert_farms_qc, pert_farms_qs + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_albedo, perts_aod, perts_angstrom, & + perts_assymfac, perts_qvapor, perts_qcloud, perts_qsnow + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: qv, qc, qs + real, dimension(ims:ime, jms:jme), intent (inout) :: albedo, aod5502d, angexp2d, aerasy2d + real, dimension (its:ite, kts:kte, jts:jte), intent(in) :: qv_tmp, qc_tmp, qs_tmp + + integer :: i, j, k + + + k = 1 + do j = jts, jte + do i = its, ite + albedo(i, j) = min (max (ALBEDO_MIN, albedo(i, j) / (1.0 + perts_albedo(i, k, j) * pert_farms_albedo)), ALBEDO_MAX) + angexp2d(i, j) = max (ANGEXP_MIN, angexp2d(i, j) / (1.0 + perts_angstrom(i, k, j) * pert_farms_angexp)) + aod5502d(i, j) = max (AOD_MIN, aod5502d(i, j) / (1.0 + perts_aod(i, k, j) * pert_farms_aod)) + aerasy2d(i, j) = min (max (AERASY_MIN, aerasy2d(i, j) / (1.0 + perts_assymfac(i, k, j) * pert_farms_aerasy)), AERASY_MAX) + end do + end do + + do j = jts, jte + do k = kts, kte + do i = its, ite + qv(i, k, j) = max (QVAPOR_MIN, qv(i, k, j) - perts_qvapor(i, k, j) * pert_farms_qv * qv_tmp(i, k, j)) + qc(i, k, j) = max (QCLOUD_MIN, qc(i, k, j) - perts_qcloud(i, k, j) * pert_farms_qc * qc_tmp(i, k, j)) + qs(i, k, j) = max (QSNOW_MIN, qs(i, k, j) - perts_qsnow(i, k, j) * pert_farms_qs * qs_tmp(i, k, j)) + end do + end do + end do + + end subroutine Remove_multi_perturb_swrad_perturbations + END MODULE module_radiation_driver diff --git a/phys/module_shallowcu_driver.F b/phys/module_shallowcu_driver.F index 1db6d5738a..6b16a4cc0e 100644 --- a/phys/module_shallowcu_driver.F +++ b/phys/module_shallowcu_driver.F @@ -2,6 +2,12 @@ ! MODULE module_shallowcu_driver + + implicit none + + real, private, parameter :: QCLOUD_MIN = 0.0 + real, private, parameter :: QVAPOR_MIN = 0.0 + CONTAINS SUBROUTINE shallowcu_driver( & ! Order dependent args for domain, mem, and tile dims @@ -65,6 +71,14 @@ SUBROUTINE shallowcu_driver( & ,dnw, xtime, xtime1, gmt & ,qke,PBLHAVG, TKEAVG & ,bl_pbl_physics & + ,multi_perturb & + ,pert_deng & + ,perts_qvapor & + ,perts_qcloud & + ,perts_th & + ,perts_w & + ,pert_deng_qv, pert_deng_qc, pert_deng_t & + ,pert_deng_w & ) !---------------------------------------------------------------------- USE module_model_constants @@ -283,11 +297,13 @@ SUBROUTINE shallowcu_driver( & , pi & , u & , v & - , th & , t & , tke_pbl & , rho + REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), & + INTENT(INOUT) :: th + REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN) :: & ! MAVAIL,PBLH,ht @@ -364,7 +380,7 @@ SUBROUTINE shallowcu_driver( & ! for nscv shallow convection ! REAL, DIMENSION( ims:ime, kms:kme, jms:jme ) , & - INTENT(IN ) :: w + INTENT(INOUT) :: w REAL, DIMENSION( ims:ime, jms:jme ) , & INTENT(IN ) :: xland REAL, DIMENSION( ims:ime, jms:jme ) , & @@ -414,6 +430,14 @@ SUBROUTINE shallowcu_driver( & ainckfsa REAL, DIMENSION( ims:ime, kms:kme, jms:jme ) :: tke_scr, kth_scr, bbls_scr + + ! WRF-Solar EPS + integer, intent (in) :: multi_perturb + logical, intent (in) :: pert_deng + real, intent(in) :: pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent(inout) :: perts_qvapor, & + perts_qcloud, perts_th, perts_w + ! ! End PSU-DENG Shallow cu variables ! @@ -604,6 +628,13 @@ SUBROUTINE shallowcu_driver( & CALL wrf_error_fatal ( message ) STOP ENDIF + + if (pert_deng .and. multi_perturb == 1) & + call Add_multi_perturb_shcu_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_w, pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w, & + th, qv_curr, qc_curr, w, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, & + kts, kte) + CALL deng_shcu_driver( & IDS=ids,IDE=ide,JDS=jds,JDE=jde,KDS=kds,KDE=kde & ,IMS=ims,IME=ime,JMS=jms,JME=jme,KMS=kms,KME=kme & @@ -632,9 +663,13 @@ SUBROUTINE shallowcu_driver( & ,cldfra_sh=cldfra_sh,ca_rad=ca_rad, cw_rad=cw_rad, wub=wub & ,RUSHTEN=rushten, RVSHTEN=rvshten, RTHSHTEN=rthshten & ,RQVSHTEN=rqvshten, RQCSHTEN=rqcshten, RQRSHTEN=rqrshten & - ,RDCASHTEN=RDCASHTEN, RQCDCSHTEN=RQCDCSHTEN & - ) + ,RDCASHTEN=RDCASHTEN, RQCDCSHTEN=RQCDCSHTEN) + if (pert_deng .and. multi_perturb == 1) & + call Remove_multi_perturb_shcu_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_w, pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w, & + th, qv_curr, qc_curr, w, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, & + kts, kte) CASE DEFAULT WRITE( message , * ) 'The shallow cumulus option does not exist: shcu_physics = ', shcu_physics @@ -657,4 +692,76 @@ SUBROUTINE shallowcu_driver( & END SUBROUTINE shallowcu_driver + subroutine Add_multi_perturb_shcu_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_w, pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w, & + th, qv_curr, qc_curr, w, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, & + kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + real, intent(in) :: pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_qcloud, perts_th, perts_w + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: th, w, qv_curr, qc_curr + + integer :: i, j, k + + + do j = jts, jte + do k = kts, kte + do i = its, ite + qc_curr(i, k, j) = max ((1.0 + perts_qcloud(i, k, j) * pert_deng_qc) * qc_curr(i, k, j), QCLOUD_MIN) + qv_curr(i, k, j) = max ((1.0 + perts_qvapor(i, k, j) * pert_deng_qv) * qv_curr(i, k, j), QVAPOR_MIN) + th(i, k, j) = (1.0 + perts_th(i, k, j) * pert_deng_t) * th(i, k, j) + end do + end do + end do + + do j = jts, jte + do k = kts + 1, kte + do i = its, ite + w(i, k, j) = (1.0 + perts_w(i, k, j) * pert_deng_t) * w(i, k, j) + end do + end do + end do + + end subroutine Add_multi_perturb_shcu_perturbations + + subroutine Remove_multi_perturb_shcu_perturbations (perts_qvapor, perts_qcloud, & + perts_th, perts_w, pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w, & + th, qv_curr, qc_curr, w, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, & + kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte + real, intent(in) :: pert_deng_qv, pert_deng_qc, pert_deng_t, pert_deng_w + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_qcloud, perts_th, perts_w + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: th, w, qv_curr, qc_curr + + integer :: i, j, k + + + do j = jts, jte + do k = kts, kte + do i = its, ite + qc_curr(i, k, j) = max (qc_curr(i, k, j) / (1.0 + perts_qcloud(i, k, j) * pert_deng_qc), QCLOUD_MIN) + qv_curr(i, k, j) = max (qv_curr(i, k, j) / (1.0 + perts_qvapor(i, k, j) * pert_deng_qv), QVAPOR_MIN) + th(i, k, j) = th(i, k, j) / (1.0 + perts_th(i, k, j) * pert_deng_t) + end do + end do + end do + + do j = jts, jte + do k = kts + 1, kte + do i = its, ite + w(i, k, j) = w(i, k, j) / (1.0 + perts_w(i, k, j) * pert_deng_w) + end do + end do + end do + + end subroutine Remove_multi_perturb_shcu_perturbations + END MODULE module_shallowcu_driver diff --git a/phys/module_shcu_deng.F b/phys/module_shcu_deng.F index 03ec97b2d0..9300dcc306 100644 --- a/phys/module_shcu_deng.F +++ b/phys/module_shcu_deng.F @@ -64,8 +64,10 @@ SUBROUTINE deng_shcu_driver( & INTEGER, DIMENSION( ims:ime , jms:jme ), & INTENT(INOUT) :: ltopb, kdcldtop, kdcldbas REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , & - INTENT(INOUT) :: W0AVG, TKEAVG, QC, & + INTENT(INOUT) :: W0AVG, TKEAVG, & cldareaa, cldareab, cldliqa, cldliqb, wub + REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , & + INTENT(IN ) :: QC REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , & INTENT( OUT) :: ca_rad, cw_rad, cldfra_sh REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), & diff --git a/phys/module_surface_driver.F b/phys/module_surface_driver.F index a3398152f2..57d14a56f5 100644 --- a/phys/module_surface_driver.F +++ b/phys/module_surface_driver.F @@ -1,6 +1,7 @@ !WRF:MEDIATION_LAYER:PHYSICS ! MODULE module_surface_driver + real, private, parameter :: QVAPOR_MIN = 0.0, SMOIS_MIN = 0.0, SMOIS_MAX = 1.0 CONTAINS SUBROUTINE surface_driver( & @@ -314,6 +315,11 @@ SUBROUTINE surface_driver( & & ,spp_lsm,pattern_spp_lsm,field_sf & !SPP & ,spp_pbl,pattern_spp_pbl & !SPP & ,XLAIDYN & + ! WRF-Solar EPS + & ,multi_perturb & + & ,pert_noah, perts_qvapor, perts_th, perts_smois & + & ,perts_tsoil, pert_noah_qv, pert_noah_t & + & ,pert_noah_smois, pert_noah_tslb & & ,irrigation,sf_surf_irr_scheme, irr_daily_amount & !IRRIG & ,irr_start_hour,irr_num_hours,irr_start_julianday & & ,irr_end_julianday,irr_freq,irr_ph,irr_rand_field & @@ -667,6 +673,13 @@ SUBROUTINE surface_driver( & REAL , INTENT(IN ):: U_FRAME REAL , INTENT(IN ):: V_FRAME + ! WRF-Solar EPS + integer, intent(in) :: multi_perturb + logical, intent(in) :: pert_noah + real, intent(in):: pert_noah_qv,pert_noah_t, pert_noah_smois,pert_noah_tslb + real, dimension (ims:ime, kms:kme, jms:jme) ,intent(inout), optional :: perts_qvapor, perts_th, & + perts_smois, perts_tsoil + !added by Wei Yu for WRF_HYDRO real :: HYDRO_dt REAL, DIMENSION( ims:ime , jms:jme ):: sfcheadrt,INFXSRT, soldrain @@ -874,7 +887,7 @@ SUBROUTINE surface_driver( & REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: P_PHY REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: RHO REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: TH_PHY - REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: T_PHY + REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT):: T_PHY REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: U_PHY REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: V_PHY REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ):: Z @@ -1473,6 +1486,8 @@ SUBROUTINE surface_driver( & INTEGER, DIMENSION( ims:ime , jms:jme ), INTENT(INOUT),OPTIONAL :: irr_rand_field INTEGER, INTENT(IN ),OPTIONAL:: sf_surf_irr_scheme,irr_start_hour,irr_num_hours,irr_start_julianday,irr_end_julianday,irr_freq,irr_ph +! WRF-Solar EPS + real, dimension (:, :, :), allocatable :: smois_tmp, tslb_tmp ! !------------------------------------------------------------------ @@ -2845,6 +2860,16 @@ SUBROUTINE surface_driver( & ! ! END FASDAS ! + if (pert_noah .and. multi_perturb == 1) then + allocate (tslb_tmp(i_start(ij):i_end(ij), 1:num_soil_layers, j_start(ij):j_end(ij))) + allocate (smois_tmp(i_start(ij):i_end(ij), 1:num_soil_layers, j_start(ij):j_end(ij))) + + call Add_multi_perturb_lsm_perturbations (perts_qvapor, perts_th, perts_smois, perts_tsoil, & + pert_noah_qv, pert_noah_t, pert_noah_smois, pert_noah_tslb, t_phy, qv_curr, tslb, smois, & + tslb_tmp, smois_tmp, num_soil_layers, i_start(ij), i_end(ij), j_start(ij), j_end(ij), ims, & + ime, jms, jme, kms, kme, kts, kte) + end if + CALL lsm(dz8w,qv_curr,p8w,t_phy,tsk, & hfx,qfx,lh,grdflx,qgh,gsw,swdown,swddir,swddif, & glw,smstav,smstot, & @@ -2937,6 +2962,15 @@ SUBROUTINE surface_driver( & ,RS,XLAIDYN,IRRIGATION_CHANNEL) ENDIF + if (pert_noah .and. multi_perturb == 1) then + call Remove_multi_perturb_lsm_perturbations (perts_qvapor, perts_th, perts_smois, perts_tsoil, & + pert_noah_qv, pert_noah_t, pert_noah_smois, pert_noah_tslb, t_phy, qv_curr, tslb, smois, & + tslb_tmp, smois_tmp, num_soil_layers, i_start(ij), i_end(ij), j_start(ij), j_end(ij), ims, & + ime, jms, jme, kms, kme, kts, kte) + deallocate (tslb_tmp) + deallocate (smois_tmp) + end if + call seaice_noah( SEAICE_ALBEDO_OPT, SEAICE_ALBEDO_DEFAULT, SEAICE_THICKNESS_OPT, & & SEAICE_THICKNESS_DEFAULT, SEAICE_SNOWDEPTH_OPT, & & SEAICE_SNOWDEPTH_MAX, SEAICE_SNOWDEPTH_MIN, & @@ -7192,4 +7226,78 @@ END SUBROUTINE get_local_ice_tsk !======================================================================= !======================================================================= + subroutine Add_multi_perturb_lsm_perturbations (perts_qvapor, perts_th, perts_smois, perts_tsoil, & + pert_noah_qv, pert_noah_t, pert_noah_smois, pert_noah_tslb, t_phy, qv_curr, tslb, smois, & + tslb_tmp, smois_tmp, num_soil_layers, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte, num_soil_layers + real, intent(in) :: pert_noah_qv, pert_noah_t, pert_noah_smois, pert_noah_tslb + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_th, perts_smois, perts_tsoil + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: t_phy, qv_curr + real, dimension(ims:ime, 1:num_soil_layers, jms:jme), intent (inout) :: tslb, smois + real, dimension (its:ite, 1:num_soil_layers, jts:jte), intent(out) :: tslb_tmp, smois_tmp + + integer :: i, j, k + + + k = 1 + do j = jts, jte + do i = its, ite + qv_curr(i, k, j) = max (QVAPOR_MIN, (1.0 + perts_qvapor(i, k, j) * pert_noah_qv) * qv_curr(i, k, j)) + t_phy(i, k, j) = (1.0 + perts_th(i, k, j) * pert_noah_t) * t_phy(i, k, j) + end do + end do + + do j = jts, jte + do k = 1, num_soil_layers + do i = its, ite + smois_tmp(i, k, j) = smois(i, k, j) + smois(i, k, j) = min (SMOIS_MAX, max (SMOIS_MIN, (1.0 + perts_smois(i, k, j) * pert_noah_smois) * smois(i, k, j))) + tslb_tmp(i, k, j) = tslb(i, k, j) + tslb(i, k, j) = (1.0 + perts_tsoil(i, k, j) * pert_noah_tslb) * tslb(i, k, j) + end do + end do + end do + + end subroutine Add_multi_perturb_lsm_perturbations + + subroutine Remove_multi_perturb_lsm_perturbations (perts_qvapor, perts_th, perts_smois, perts_tsoil, & + pert_noah_qv, pert_noah_t, pert_noah_smois, pert_noah_tslb, t_phy, qv_curr, tslb, smois, & + tslb_tmp, smois_tmp, num_soil_layers, its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte) + + implicit none + + integer, intent(in) :: its, ite, jts, jte, ims, ime, jms, jme, kms, kme, kts, kte, num_soil_layers + real, intent(in) :: pert_noah_qv, pert_noah_t, pert_noah_smois, pert_noah_tslb + real, dimension(ims:ime, kms:kme, jms:jme), optional, intent (in) :: perts_qvapor, & + perts_th, perts_smois, perts_tsoil + real, dimension(ims:ime, kms:kme, jms:jme), intent (inout) :: t_phy, qv_curr + real, dimension(ims:ime, 1:num_soil_layers, jms:jme), intent (inout) :: tslb, smois + real, dimension (its:ite, 1:num_soil_layers, jts:jte), intent(in) :: tslb_tmp, smois_tmp + + integer :: i, j, k + + + k = 1 + do j = jts, jte + do i = its, ite + qv_curr(i, k, j) = max (QVAPOR_MIN, qv_curr(i, k, j) / (1.0 + perts_qvapor(i, k, j) * pert_noah_qv)) + t_phy(i, k, j) = t_phy(i, k, j) / (1.0 + perts_th(i, k, j) * pert_noah_t) + end do + end do + + do j = jts, jte + do k = 1, num_soil_layers + do i = its, ite + smois(i, k, j) = min (SMOIS_MAX, max (SMOIS_MIN, smois(i, k, j) - perts_smois(i, k, j) * pert_noah_smois * smois_tmp(i, k, j))) + tslb(i, k, j) = tslb(i, k, j) - perts_tsoil(i, k, j) * pert_noah_tslb * tslb_tmp(i, k, j) + end do + end do + end do + + end subroutine Remove_multi_perturb_lsm_perturbations + END MODULE module_surface_driver diff --git a/run/README.namelist b/run/README.namelist index d819452dab..50e93821ac 100644 --- a/run/README.namelist +++ b/run/README.namelist @@ -632,6 +632,7 @@ Namelist variables for controlling the adaptive time step option: = 1, ! use interpolation = 2, ! Calls the Fast All-Sky Radiation Model for Solar applications (FARMS) ! every model time step. + couple_farms = .false. ! True) uses FARMS SW radiation to drive the LSM, False) Uses the SW radiation from rad_sw_physics cam_abs_freq_s = 21600 ! default CAM clearsky longwave absorption calculation frequency (recommended minimum value to speed scheme up) levsiz = 59 ! for CAM radiation input ozone levels, set automatically @@ -1197,6 +1198,44 @@ Stochastically perturbed parameter scheme (SPP) (spp=1) start time to ensure different random number streams for forecasts starting from different initial times and for different ensemble members. +Multiple perturbations for WRF-Solar EPS (multi_perturb = 1) + multi_perturb = 0 ! 1) WRF-Solar EPS: turns on stochastic perturbations tailored for solar energy applications + spdt = -1.0 ! Frequency to update the stochastic perturbations [minutes]. A negative value indicates for every time step + pert_farms = .false. ! Activates perturbations to the FARMS parameterization + pert_farms_albedo = 0.0 ! 1.0) Perturbs the albedo, 0.0) no perturbations. Similar for other entries below + pert_farms_aod = 0.0 + pert_farms_angexp = 0.0 + pert_farms_aerasy = 0.0 + pert_farms_qv = 0.0 + pert_farms_qc = 0.0 + pert_farms_qs = 0.0 + pert_deng = .false. ! Activates perturbations to Deng's shcu parameterization + pert_deng_qv = 0.0 + pert_deng_qc = 0.0 + pert_deng_t = 0.0 + pert_deng_w = 0.0 + pert_mynn = .false. ! Activates perturbations to the MYNN PBL parameterization + pert_mynn_qv = 0.0 + pert_mynn_qc = 0.0 + pert_mynn_t = 0.0 + pert_mynn_qke = 0.0 + pert_noah = .false. ! Activates perturbations to the Noah LSM + pert_noah_qv = 0.0 + pert_noah_t = 0.0 + pert_noah_smois = 0.0 + pert_noah_tslb = 0.0 + pert_thom = .false. ! Activates perturbations to thompson microphysics + pert_thom_qv = 0.0 + pert_thom_qc = 0.0 + pert_thom_qi = 0.0 + pert_thom_qs = 0.0 + pert_thom_ni = 0.0 + pert_cld3 = .false. ! Activates perturbations to clouds generated with icloud = 3 + pert_cld3_qv = 0.0 + pert_cld3_t = 0.0 + + num_pert_3d = 15 ! Number of entries in STOCHPERT.TBL plus one (No need to modify) + ; Stochastic Perturbations to the boundary conditions?| (perturb_bdy) perturb_bdy = 0 ! No boundary perturbations 1 Use SKEBS pattern for boundary perturbations diff --git a/run/STOCHPERT.TBL b/run/STOCHPERT.TBL new file mode 100644 index 0000000000..d6c0f62429 --- /dev/null +++ b/run/STOCHPERT.TBL @@ -0,0 +1,17 @@ + Change only the magnitude of the values + Name Std Lengthscale Decorrelation Std cutoff Seed 2d pert (0) + [m] time [s] or 3d pert (1) +1 ALBEDO 0.10 100000.0 86400.0 3.0 17 0 +2 AOD 0.25 100000.0 3600.0 3.0 18 0 +3 ANGSTROM 0.10 100000.0 3600.0 3.0 19 0 +4 ASSYMFAC 0.05 100000.0 3600.0 3.0 20 0 +5 QVAPOR 0.05 100000.0 3600.0 3.0 21 1 +6 QCLOUD 0.10 100000.0 3600.0 3.0 22 1 +7 QICE 0.10 100000.0 3600.0 3.0 23 1 +8 QSNOW 0.10 100000.0 3600.0 3.0 24 1 +9 NI 0.05 100000.0 3600.0 3.0 25 1 +10 TH 0.001 100000.0 3600.0 3.0 26 1 +11 TKE 0.05 80000.0 600.0 3.0 27 1 +12 SMOIS 0.10 80000.0 21600.0 3.0 28 1 +13 TSOIL 0.001 80000.0 21600.0 3.0 29 1 +14 W 0.10 80000.0 21600.0 3.0 30 1 diff --git a/share/module_check_a_mundo.F b/share/module_check_a_mundo.F index 8acdd95e8f..1a15cbfdc9 100644 --- a/share/module_check_a_mundo.F +++ b/share/module_check_a_mundo.F @@ -340,6 +340,18 @@ END FUNCTION bep_bem_ngr_u count_fatal_error = count_fatal_error + 1 END IF +!----------------------------------------------------------------------- +! Check that multi_perturb and adptive time setp are not both activated +!----------------------------------------------------------------------- + + DO i = 1, model_config_rec % max_dom + IF ( .NOT. model_config_rec % grid_allowed(i) ) CYCLE + IF ((model_config_rec%multi_perturb(i) == 1) .and. model_config_rec%use_adaptive_time_step) then + wrf_err_message = '--- ERROR: multi_perturb and adpative time step are not compatible.' + CALL wrf_debug ( 0, TRIM( wrf_err_message ) ) + count_fatal_error = count_fatal_error + 1 + END IF + ENDDO !----------------------------------------------------------------------- ! Check that SMS-3DTKE scheme (km_opt=5) Must work with diff_opt=2 @@ -573,6 +585,17 @@ END FUNCTION bep_bem_ngr_u count_fatal_error = count_fatal_error + 1 END IF +!----------------------------------------------------------------------- +! If couple_farms is true, swint_opt must be 2 +!----------------------------------------------------------------------- + IF ( model_config_rec%couple_farms .AND. model_config_rec%swint_opt /= 2 ) THEN + wrf_err_message = '--- ERROR: Options couple_farms = T requires swint_opt = 2' + CALL wrf_message ( wrf_err_message ) + wrf_err_message = '--- ERROR: Change either one in namelist.input and rerun the model' + CALL wrf_debug ( 0, TRIM( wrf_err_message ) ) + count_fatal_error = count_fatal_error + 1 + END IF + !----------------------------------------------------------------------- ! For ARW users, a request for CU=4 (SAS) should be switched to option ! CU = 95. The option CU = 4 is a scaleaware scheme used by NMM.