From aa6ad5b9272fb8a6edc244bc36a2d3cb86e97434 Mon Sep 17 00:00:00 2001 From: Anthony Islas <128631809+islas@users.noreply.github.com> Date: Tue, 10 Feb 2026 11:41:24 -0700 Subject: [PATCH 1/7] Add MMM-physics as a git submodule (#2282) TYPE: no impact KEYWORDS: git, submodule, manage_externals SOURCE: internal DESCRIPTION OF CHANGES: Problem: MMM-physics (under `phys/physics_mmm`) is currently the only external repository tracked with only manage_externals. This makes manage_externals and git two failure points for a proper clone of WRF to succeed. Solution: Add MMM-physics as a git submodule using the original path of `phys/physics_mmm`). To avoid confusion in managing two locations of the submodule (one in `.gitmodules` and the other in `arch/Externals.cfg`) the MMM-physics repo is removed from manage_externals. From a user perspective, no change to the build process is evident. TESTS CONDUCTED: 1. Build proceeds as normal from a fresh clone. --- .gitmodules | 3 +++ arch/Externals.cfg | 8 -------- phys/Makefile | 6 ++++++ phys/physics_mmm | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) create mode 160000 phys/physics_mmm diff --git a/.gitmodules b/.gitmodules index 4f2c7fd5e8..8fb2d8a9d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,9 @@ [submodule ".ci/hpc-workflows"] path = .ci/hpc-workflows url = https://github.com/islas/hpc-workflows +[submodule "phys/physics_mmm"] + path = phys/physics_mmm + url = https://github.com/NCAR/MMM-physics.git [submodule "phys/MYNN-EDMF"] path = phys/MYNN-EDMF url = https://github.com/NCAR/MYNN-EDMF diff --git a/arch/Externals.cfg b/arch/Externals.cfg index 48cd9b11e0..d8dc664cad 100644 --- a/arch/Externals.cfg +++ b/arch/Externals.cfg @@ -1,10 +1,2 @@ -[MMM-physics] -local_path = ./phys/physics_mmm -protocol = git -repo_url = https://github.com/NCAR/MMM-physics.git -tag = 20240626-MPASv8.2 - -required = True - [externals_description] schema_version = 1.0.0 diff --git a/phys/Makefile b/phys/Makefile index 94fc470d4b..ab46dbf68f 100644 --- a/phys/Makefile +++ b/phys/Makefile @@ -277,6 +277,12 @@ submodules : else \ echo No action required for NoahMP submodule ; \ fi + @if [ \( ! -f phys/physics_mmm/README.md \) ] ; then \ + echo Pulling in MMM-physics submodule ; \ + ( cd .. ; git submodule update --init --recursive ) ; \ + else \ + echo No action required for MMM-physics submodule ; \ + fi @if [ \( ! -f module_bl_mynnedmf.F \) -o \( ! -f module_bl_mynnedmf_common.F \) -o \ \( ! -f module_bl_mynnedmf_driver.F \) ] ; then \ echo Pulling in MYNN-EDMF submodule ; \ diff --git a/phys/physics_mmm b/phys/physics_mmm new file mode 160000 index 0000000000..0ea59b1cd6 --- /dev/null +++ b/phys/physics_mmm @@ -0,0 +1 @@ +Subproject commit 0ea59b1cd673006ee7a9a9958c533a6a0e354243 From 3c76c8b70d3ee7b9cc35df765b933cc8dc85629b Mon Sep 17 00:00:00 2001 From: AndersJensen-NOAA <132939212+AndersJensen-NOAA@users.noreply.github.com> Date: Thu, 12 Feb 2026 03:01:07 -0700 Subject: [PATCH 2/7] TEMPO microphysics for WRF (#2270) TYPE: new feature KEYWORDS: Microphysics, Operational models SOURCE: Anders Jensen NOAA/GSL DESCRIPTION OF CHANGES: Problem: Microphysics development of a Thompson-Eidhammer based scheme for operational applications has advanced to a submodule, TEMPO. This new development should be made available to WRF users. Solution: Connect TEMPO to WRF. A cleaned and refactored version of TEMPO is being tested in the UFS community's MPAS. Additionally, a PR, https://github.com/MPAS-Dev/MPAS-Model/pull/1393, to add TEMPO to NCAR's MPAS is in progress. This current PR will allow the community to use this same microphysics across the UFS, MPAS, and WRF. LIST OF MODIFIED FILES: M .gitmodules M main/depends.common M Makefile M clean M phys/Makefile M phys/module_physics_init.F M phys/module_microphysics_driver.F M Registry.EM_COMMON M dyn_em/module_initialize_real.F TESTS CONDUCTED: 1. compiled and ran em_quarter_ss 2. restart test with em_quarter_ss 3. bit-for-bit with different number of processes using em_quarter_ss. 4. Passed regression tests. RELEASE NOTE: TEMPO is the Thompson-Eidhammer Microphysics Parameterization for Operations. TEMPO lives here: https://github.com/NCAR/TEMPO and technical documentation lives here: https://ncar.github.io/TEMPO/. TEMPO specific release notes are here: https://github.com/NCAR/TEMPO/releases/tag/tempo_v3.0.0 TEMPO version 3.0.0 is the current release version. TEMPO is being tested in the ufs-community fork of MPAS for next-generation convection-allowing forecast systems (https://github.com/ufs-community/MPAS-Model). Thus, TEMPO is being continually evaluated for improvement. Additionally, there is a PR in progress to connect TEMPO (v3.0.0) to NCAR's MPAS (https://github.com/MPAS-Dev/MPAS-Model/pull/1393). The version of TEMPO currently in the CCPP (https://github.com/ufs-community/ccpp-physics) will be updated to v3.0.0 soonish. TEMPO is connected to WRF, MPAS, and CCPP as a submodule, and the same v3.0.0 code will be connected to WRF (this PR), MPAS, and CCPP. In WRF, supported namelist options include `tempo_aerosolaware==1` to use the aerosol-aware version, and `tempo_hailaware==1` to use the hail-aware version. Both options are on by default. Key improvements include: - TEMPO is in a submodule that allows for flexibility when connecting TEMPO to dynamical cores - Code modularity was been improved and technical documentation has been added - Bux fix for cloud droplet number concentration during evaporation - Surface emissions of water-friendly aerosols have been reduced based on a sensitivity simulation that aimed to better constrain water-friendly aerosol concentrations over 24-36 hour forecast periods and reduce the accumulation of aerosols in the atmosphere - A few modifications were made to graupel number concentration tendencies (when using the hail-aware option) for processes that cause rain to freeze to increase reflectivity in deep convective storms - Added simple sedimentation tests - Added unit tests - Added a program to build lookup tables with MPI capability - Lookup tables have been unified --- .gitmodules | 3 + Makefile | 8 +++ Registry/Registry.EM_COMMON | 7 +- clean | 4 ++ dyn_em/module_initialize_real.F | 15 ++-- main/depend.common | 26 +++++++ phys/Makefile | 28 +++++++- phys/TEMPO | 1 + phys/module_microphysics_driver.F | 113 +++++++++++++++++++++++++++++- phys/module_physics_init.F | 14 ++++ share/module_check_a_mundo.F | 4 +- 11 files changed, 214 insertions(+), 9 deletions(-) create mode 160000 phys/TEMPO diff --git a/.gitmodules b/.gitmodules index 8fb2d8a9d1..eb9c7a7f4f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,9 @@ [submodule "phys/MYNN-EDMF"] path = phys/MYNN-EDMF url = https://github.com/NCAR/MYNN-EDMF +[submodule "phys/TEMPO"] + path = phys/TEMPO + url = https://github.com/NCAR/TEMPO.git [submodule "phys/MYNN-SFC"] path = phys/MYNN-SFC url = https://github.com/NCAR/MYNN-SFC.git diff --git a/Makefile b/Makefile index bd34368f0b..8373a325fe 100644 --- a/Makefile +++ b/Makefile @@ -138,6 +138,13 @@ wrf : framework_only echo "MYNN-EDMF submodule files populating WRF directories" ; \ echo "------------------------------------------------------------------------------" ; \ fi + @if [ \( ! -f phys/module_mp_tempo_driver.F90 \) -o \( ! -f phys/module_mp_tempo_main.F90 \) -o \ + \( ! -f phys/module_mp_tempo_cfgs.F90 \) -o \( ! -f phys/module_mp_tempo_aerosols.F90 \) -o \ + \( ! -f phys/module_mp_tempo_ml.F90 \) -o \( ! -f phys/module_mp_tempo_diags.F90 \) -o \ + \( ! -f phys/module_mp_tempo_utils.F90 \) -o \( ! -f phys/module_mp_tempo_params.F90 \) ] ; then \ + echo " " ; \ + echo "------------------------------------------------------------------------------" ; \ + echo "Error Error Error TEMPO submodule files not populating WRF directories" ; \ @if [ \( ! -f phys/module_sf_mynnsfc_driver.F \) -o \ \( ! -f phys/module_sf_mynnsfc_land.F \) -o \ \( ! -f phys/module_sf_mynnsfc_water.F \) -o \ @@ -151,6 +158,7 @@ wrf : framework_only exit 31 ; \ else \ echo "------------------------------------------------------------------------------" ; \ + echo "TEMPO submodule files populating WRF directories" ; \ echo "MYNN-SFC submodule files populating WRF directories" ; \ echo "------------------------------------------------------------------------------" ; \ fi diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index 8d2a74fd9f..d978d6ed1c 100644 --- a/Registry/Registry.EM_COMMON +++ b/Registry/Registry.EM_COMMON @@ -2425,7 +2425,8 @@ rconfig integer nssl_3moment namelist,physics 1 0 rconfig integer nssl_density_on namelist,physics 1 -1 rh "NSSL graupel/hail density flag" "" "" rconfig integer nssl_ssat_output namelist,physics 1 0 rh "NSSL ssat output flag" "" "" - +rconfig integer tempo_aerosolaware namelist,physics 1 1 rh "TEMPO aerosol-aware flag" "" "" +rconfig integer tempo_hailaware namelist,physics 1 1 rh "TEMPO hail-aware flag" "" "" rconfig integer CCNTY namelist,physics 1 2 rh "Aerosol background type for NTU microphysics" "" "" @@ -3044,6 +3045,7 @@ package wdm7scheme mp_physics==26 - moist:qv,qc package udmscheme mp_physics==27 - moist:qv,qc,qr,qi,qs,qg,qh;scalar:qnn,qnc,qnr;state:re_cloud,re_ice,re_snow package thompsonaero mp_physics==28 - moist:qv,qc,qr,qi,qs,qg;scalar:qni,qnr,qnc,qnwfa,qnifa,qnbca;state:re_cloud,re_ice,re_snow,qnwfa2d,qnifa2d,taod5503d,taod5502d package thompsongh mp_physics==38 - moist:qv,qc,qr,qi,qs,qg;scalar:qni,qnr,qnc,qng,qvolg,qnwfa,qnifa,qnbca;state:re_cloud,re_ice,re_snow,qnwfa2d,qnifa2d,taod5503d,taod5502d +package tempo mp_physics==88 - moist:qv,qc,qr,qi,qs,qg;scalar:qni,qnr;state:re_cloud,re_ice,re_snow package p3_1category mp_physics==50 - moist:qv,qc,qr,qi;scalar:qni,qnr,qir,qib;state:re_cloud,re_ice,vmi3d,rhopo3d,di3d,refl_10cm,th_old,qv_old package p3_1category_nc mp_physics==51 - moist:qv,qc,qr,qi;scalar:qnc,qni,qnr,qir,qib;state:re_cloud,re_ice,vmi3d,rhopo3d,di3d,refl_10cm,th_old,qv_old package p3_2category mp_physics==52 - moist:qv,qc,qr,qi,qi2;scalar:qnc,qni,qnr,qir,qib,qni2,qir2,qib2;state:re_cloud,re_ice,vmi3d,rhopo3d,di3d,vmi3d_2,rhopo3d_2,di3d_2,refl_10cm,th_old,qv_old @@ -3066,7 +3068,8 @@ package nssl_graupelvol nssl_density_on==1 - scalar:qvol package nssl_hailvol nssl_density_on==2 - scalar:qvolg,qvolh package nssl_ssat_out nssl_ssat_output==1 - state:ssat package nssl_ssati_out nssl_ssat_output==2 - state:ssat,ssati - +package tempo_aerosol tempo_aerosolaware==1 - scalar:qnc,qnwfa,qnifa;state:qnwfa2d,qnifa2d +package tempo_hail tempo_hailaware==1 - scalar:qng,qvolg package radar_refl compute_radar_ref==1 - state:refl_10cm,refd_max endif diff --git a/clean b/clean index bf063ba4d1..06514476df 100755 --- a/clean +++ b/clean @@ -85,6 +85,10 @@ if ( "$arg" == '-a' || "$arg" == '-aa' ) then run/MPTABLE.TBL /bin/rm -f phys/module_bl_mynnedmf.F phys/module_bl_mynnedmf_common.F \ phys/module_bl_mynnedmf_driver.F + /bin/rm -f phys/module_mp_tempo_cfgs.F90 phys/module_mp_tempo_params.F90 \ + phys/module_mp_tempo_utils.F90 phys/module_mp_tempo_diags.F90 \ + phys/module_mp_tempo_ml.F90 phys/module_mp_tempo_driver.F90 \ + phys/module_mp_tempo_aerosols.F90 phys/module_mp_tempo_main.F90 endif endif diff --git a/dyn_em/module_initialize_real.F b/dyn_em/module_initialize_real.F index 30a6d34a2a..275157b4e4 100644 --- a/dyn_em/module_initialize_real.F +++ b/dyn_em/module_initialize_real.F @@ -2332,7 +2332,8 @@ SUBROUTINE init_domain_rk ( grid & aer_init_opt = config_flags%aer_init_opt if_thompsonaero_3d: IF ((config_flags%mp_physics .EQ. THOMPSONAERO & - .OR. config_flags%mp_physics .EQ. RCON_MP_SCHEME) .AND. & + .OR. (config_flags%mp_physics .EQ. TEMPO .AND. config_flags%tempo_aerosolaware .EQ. 1) & + .OR. config_flags%mp_physics .EQ. RCON_MP_SCHEME) .AND. & config_flags%wif_input_opt .GT. 0) THEN select_aer_init_opt_3d: select case (aer_init_opt) @@ -2740,7 +2741,8 @@ SUBROUTINE init_domain_rk ( grid & end select select_aer_init_opt_3d ELSE IF ((config_flags%mp_physics .EQ. THOMPSONAERO & - .OR. config_flags%mp_physics .EQ. RCON_MP_SCHEME) .and. & + .OR. (config_flags%mp_physics .EQ. TEMPO .AND. config_flags%tempo_aerosolaware .EQ. 1) & + .OR. config_flags%mp_physics .EQ. RCON_MP_SCHEME) .and. & config_flags%wif_input_opt .EQ. 0 ) THEN CALL wrf_error_fatal ('wif_input_opt=0 but mp_physics=28 or mp_physics=29' ) END IF if_thompsonaero_3d @@ -4510,7 +4512,8 @@ SUBROUTINE init_domain_rk ( grid & !+---+-----------------------------------------------------------------+ if_thompsonaero_2d: IF ((config_flags%mp_physics .EQ. THOMPSONAERO & - .OR. config_flags%mp_physics .EQ. RCON_MP_SCHEME) .AND. & + .OR. (config_flags%mp_physics .EQ. TEMPO .AND. config_flags%tempo_aerosolaware .EQ. 1) & + .OR. config_flags%mp_physics .EQ. RCON_MP_SCHEME) .AND. & config_flags%wif_input_opt .GT. 0) THEN select_aer_init_opt_2d: select case (aer_init_opt) @@ -4533,7 +4536,11 @@ SUBROUTINE init_domain_rk ( grid & do j = jts, min(jde-1,jte) do i = its, min(ide-1,ite) z1 = (grid%phb(i,2,j)-grid%phb(i,1,j))/g - grid%qnwfa2d(i,j) = grid%w_wif_now(i,1,j) * 0.000196 * (50./z1) + if (config_flags%mp_physics .EQ. TEMPO) then + grid%qnwfa2d(i,j) = grid%w_wif_now(i,1,j) * 0.000196 * (5./z1) + else + grid%qnwfa2d(i,j) = grid%w_wif_now(i,1,j) * 0.000196 * (50./z1) + endif enddo enddo diff --git a/main/depend.common b/main/depend.common index e9a499501c..676f0a3cf0 100644 --- a/main/depend.common +++ b/main/depend.common @@ -1002,6 +1002,28 @@ module_mp_nssl_2mom.o: \ ../frame/module_wrf_error.o \ ../share/module_model_constants.o +module_mp_tempo_ml.o: \ + module_mp_tempo_params.o +module_mp_tempo_utils.o: \ + module_mp_tempo_params.o +module_mp_tempo_aerosols.o: \ + module_mp_tempo_params.o +module_mp_tempo_diags.o: \ + module_mp_tempo_params.o \ + module_mp_tempo_utils.o +module_mp_tempo_driver.o : \ + module_mp_tempo_params.o \ + module_mp_tempo_cfgs.o \ + module_mp_tempo_utils.o \ + module_mp_tempo_main.o \ + module_mp_tempo_ml.o +module_mp_tempo_main.o : \ + module_mp_tempo_params.o \ + module_mp_tempo_cfgs.o \ + module_mp_tempo_utils.o \ + module_mp_tempo_diags.o \ + module_mp_tempo_aerosols.o \ + module_mp_tempo_ml.o module_mp_fast_sbm.o: \ ../frame/module_domain.o \ @@ -1362,6 +1384,8 @@ module_physics_init.o: \ module_fdda_spnudging.o \ module_fddaobs_rtfdda.o \ module_mp_thompson.o \ + module_mp_tempo_cfgs.o \ + module_mp_tempo_driver.o \ module_mp_rcon.o \ module_mp_gsfcgce.o \ module_mp_gsfcgce_4ice_nuwrf.o \ @@ -1409,6 +1433,8 @@ module_microphysics_driver.o: \ module_mp_wsm6r.o \ module_mp_fer_hires.o \ module_mp_thompson.o \ + module_mp_tempo_cfgs.o \ + module_mp_tempo_driver.o \ module_mp_rcon.o \ module_mp_gsfcgce.o \ module_mp_gsfcgce_4ice_nuwrf.o \ diff --git a/phys/Makefile b/phys/Makefile index ab46dbf68f..18ee831ccf 100644 --- a/phys/Makefile +++ b/phys/Makefile @@ -97,6 +97,14 @@ MODULES = \ module_mp_etanew.o \ module_mp_fer_hires.o \ module_mp_thompson.o \ + module_mp_tempo_cfgs.o \ + module_mp_tempo_params.o \ + module_mp_tempo_utils.o \ + module_mp_tempo_diags.o \ + module_mp_tempo_ml.o \ + module_mp_tempo_aerosols.o \ + module_mp_tempo_main.o \ + module_mp_tempo_driver.o \ module_mp_rcon.o \ module_fire_emis.o \ module_mp_SBM_polar_radar.o \ @@ -238,7 +246,7 @@ DIAGNOSTIC_MODULES_EM = \ module_diag_zld.o \ module_diag_trad_fields.o \ module_diag_solar.o - + PHYSMMM_MODULES = \ physics_mmm/sf_sfclayrev.o \ physics_mmm/cu_ntiedtke.o \ @@ -293,6 +301,24 @@ submodules : else \ echo No action required for MYNN-EDMF submodule ; \ fi + @if [ \( ! -f module_mp_tempo_driver.F90 \) -o \( ! -f module_mp_tempo_main.F90 \) -o \ + \( ! -f module_mp_tempo_cfgs.F90 \) -o \( ! -f module_mp_tempo_aerosols.F90 \) -o \ + \( ! -f module_mp_tempo_ml.F90 \) -o \( ! -f modulemp_tempo_diags.F90 \) -o \ + \( ! -f module_mp_tempo_utils.F90 \) -o \( ! -f module_mp_tempo_params.F90 \) ] ; then \ + echo Pulling in TEMPO submodule ; \ + ( cd .. ; git submodule update --init --recursive ) ; \ + ln -sf TEMPO/src/module_mp_tempo_cfgs.F90 module_mp_tempo_cfgs.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_params.F90 module_mp_tempo_params.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_utils.F90 module_mp_tempo_utils.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_diags.F90 module_mp_tempo_diags.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_ml.F90 module_mp_tempo_ml.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_aerosols.F90 module_mp_tempo_aerosols.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_main.F90 module_mp_tempo_main.F90 ; \ + ln -sf TEMPO/src/module_mp_tempo_driver.F90 module_mp_tempo_driver.F90 ; \ + else \ + echo No action required for TEMPO submodule ; \ + fi + @if [ \( ! -f module_sf_mynnsfc_driver.F \) -o \( ! -f module_sf_mynnsfc_common.F \) -o \ \( ! -f module_sf_mynnsfc_land.F \) -o \( ! -f module_sf_mynnsfc_water.F \) -o \ \( ! -f module_sf_mynnsfc_ice.F \) ] ; then \ diff --git a/phys/TEMPO b/phys/TEMPO new file mode 160000 index 0000000000..e41f020bb5 --- /dev/null +++ b/phys/TEMPO @@ -0,0 +1 @@ +Subproject commit e41f020bb5194a48c3306dd99812a067cbbeab32 diff --git a/phys/module_microphysics_driver.F b/phys/module_microphysics_driver.F index 94004191cb..538d806c61 100644 --- a/phys/module_microphysics_driver.F +++ b/phys/module_microphysics_driver.F @@ -174,7 +174,7 @@ SUBROUTINE microphysics_driver( & ,WSM7SCHEME, WDM7SCHEME, UDMSCHEME & ,NUWRF4ICESCHEME & ,MILBRANDT2MOM , CAMMGMPSCHEME,FULL_KHAIN_LYNN, P3_1CATEGORY, P3_1CATEGORY_NC, P3_2CATEGORY, P3_1CAT_3MOM & - ,MORR_TM_AERO, JENSEN_ISHMAEL, SPRINKLER, NTU !,MILBRANDT3MOM + ,MORR_TM_AERO, JENSEN_ISHMAEL, SPRINKLER, NTU, TEMPO !,MILBRANDT3MOM USE module_state_description, ONLY : WSM6RSCHEME #if ( WRFPLUS == 1 ) USE module_state_description, ONLY : LSCONDSCHEME, MKESSLERSCHEME @@ -224,6 +224,9 @@ SUBROUTINE microphysics_driver( & USE module_mp_fer_hires USE module_mp_rcon USE module_mp_thompson + USE module_mp_tempo_cfgs, only : ty_tempo_cfgs + USE module_mp_tempo_driver, only : tempo_run, ty_tempo_driver_diags, & + tempo_aerosol_surface_emissions USE module_mp_full_sbm #if ( BUILD_SBM_FAST == 1 ) USE module_mp_fast_sbm @@ -796,6 +799,9 @@ SUBROUTINE microphysics_driver( & character*256 :: errmsg integer :: errflg + type(ty_tempo_cfgs) :: tempo_cfgs + type(ty_tempo_driver_diags) :: tempo_driver_diags + logical :: config_tempo_aerosolaware, config_tempo_hailaware !--------------------------------------------------------------------- ! check for microphysics type. We need a clean way to ! specify these things! @@ -1381,6 +1387,111 @@ SUBROUTINE microphysics_driver( & ELSE CALL wrf_error_fatal ( 'arguments not present for calling thompson_et_al' ) ENDIF + CASE (TEMPO) + ! add surface emissions + if (present(qnwfa_curr) .and. present(qnwfa2d)) then + call tempo_aerosol_surface_emissions(dt=dt, & + nwfa=qnwfa_curr, nwfa2d=qnwfa2d, & + ims=ims, ime=ime, jms=jms, & + jme=jme, kms=kms, kme=kme, kts=kts) + endif + + CALL wrf_debug ( 100 , 'microphysics_driver: calling tempo' ) + IF ( PRESENT( QV_CURR ) .AND. PRESENT ( QC_CURR ) .AND. & + PRESENT( QR_CURR ) .AND. PRESENT ( QI_CURR ) .AND. & + PRESENT( QS_CURR ) .AND. PRESENT ( QG_CURR ) .AND. & + PRESENT( QNR_CURR) .AND. PRESENT ( QNI_CURR)) THEN + + config_tempo_aerosolaware = .false. + config_tempo_hailaware = .false. + if (config_flags%tempo_aerosolaware == 1) config_tempo_aerosolaware = .true. + if (config_flags%tempo_hailaware == 1) config_tempo_hailaware = .true. + tempo_cfgs%aerosolaware_flag = config_tempo_aerosolaware + tempo_cfgs%hailaware_flag = config_tempo_hailaware + CALL tempo_run( & + tempo_cfgs=tempo_cfgs, & + dt=dt, & + itimestep=itimestep, & + th=th, & + pii=pi_phy, & + p=p, & + w=w, & + dz=dz8w, & + qv=qv_curr, & + qc=qc_curr, & + qr=qr_curr, & + qi=qi_curr, & + qs=qs_curr, & + qg=qg_curr, & + ni=qni_curr, & + nr=qnr_curr, & + nc=qnc_curr, & ! optionally present when tempo_aerosolaware == 1 + nwfa=qnwfa_curr, & ! optionally present when tempo_aerosolaware == 1 + nifa=qnifa_curr, & ! optionally present when tempo_aerosolaware == 1 + ng=qng_curr, & ! optionally present when tempo_hailaware == 1 + qb=qvolg_curr, & ! optionally present when tempo_hailaware == 1 + 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, & + tempo_diags = tempo_driver_diags) + ! map tempo diagnostics to WRF variable names noting that some wrf variables are optional + do j = jts, jte + do i = its, ite + if (present(snowncv)) then + snowncv(i,j) = tempo_driver_diags%ice_liquid_equiv_precip(i,j) + & + tempo_driver_diags%snow_liquid_equiv_precip(i,j) + endif + if (present(snownc)) snownc(i,j) = snownc(i,j) + snowncv(i,j) + + if (present(graupelncv)) then + graupelncv(i,j) = tempo_driver_diags%graupel_liquid_equiv_precip(i,j) + endif + if (present(graupelnc)) graupelnc(i,j) = graupelnc(i,j) + graupelncv(i,j) + + if (present(rainncv)) then + rainncv(i,j) = tempo_driver_diags%rain_precip(i,j) + snowncv(i,j) + graupelncv(i,j) + endif + if (present(rainnc)) rainnc(i,j) = rainnc(i,j) + rainncv(i,j) + ! ratio of frozen precipitation to total is not optional in wrf + sr(i,j) = tempo_driver_diags%frozen_fraction(i,j) + + if (config_flags%nwp_diagnostics == 1) then + if (present(hail_maxk1)) then + if (allocated(tempo_driver_diags%max_hail_diameter_sfc)) then + hail_maxk1(i,j) = tempo_driver_diags%max_hail_diameter_sfc(i,j) + endif + endif + if (present(hail_max2d)) then + if (allocated(tempo_driver_diags%max_hail_diameter_column)) then + hail_max2d(i,j) = tempo_driver_diags%max_hail_diameter_column(i,j) + endif + endif + endif + ! 3d tempo diagnostics + do k = kts, kte + if (do_radar_ref == 1) then + if (present(refl_10cm)) then + if (allocated(tempo_driver_diags%refl10cm)) then + refl_10cm(i,k,j) = tempo_driver_diags%refl10cm(i,k,j) + endif + endif + endif + ! effective radius values are not optional in wrf + if (allocated(tempo_driver_diags%re_cloud)) then + re_cloud(i,k,j) = tempo_driver_diags%re_cloud(i,k,j) + endif + if (allocated(tempo_driver_diags%re_ice)) then + re_ice(i,k,j) = tempo_driver_diags%re_ice(i,k,j) + endif + if (allocated(tempo_driver_diags%re_snow)) then + re_snow(i,k,j) = tempo_driver_diags%re_snow(i,k,j) + endif + enddo + enddo + enddo + ELSE + CALL wrf_error_fatal ( 'arguments not present for calling tempo' ) + ENDIF #if (EM_CORE==1) CASE (NTU) CALL wrf_debug(100, 'microphysics_driver: calling ntu') diff --git a/phys/module_physics_init.F b/phys/module_physics_init.F index fe069c771c..2e9c6640bc 100644 --- a/phys/module_physics_init.F +++ b/phys/module_physics_init.F @@ -1004,6 +1004,7 @@ SUBROUTINE phy_init ( id, config_flags, DT, restart, zfull, zhalf, & (config_flags%ra_sw_physics .eq. goddardswscheme ) ) .and. & (config_flags%mp_physics .eq. THOMPSON .or. & config_flags%mp_physics .eq. THOMPSONAERO .or. & + config_flags%mp_physics .eq. TEMPO .or. & config_flags%mp_physics .eq. RCON_MP_SCHEME .or. & (config_flags%mp_physics .eq. NSSL_2MOM .and. config_flags%nssl_2moment_on == 1) .or. & config_flags%mp_physics .eq. WSM3SCHEME .or. & @@ -1040,6 +1041,7 @@ SUBROUTINE phy_init ( id, config_flags, DT, restart, zfull, zhalf, & IF (( config_flags%mp_physics == THOMPSON .OR. & config_flags%mp_physics == RCON_MP_SCHEME .OR. & config_flags%mp_physics == THOMPSONAERO .OR. & + config_flags%mp_physics == TEMPO .OR. & config_flags%mp_physics == WSM3SCHEME .OR. & config_flags%mp_physics == WSM5SCHEME .OR. & config_flags%mp_physics == WSM6SCHEME .OR. & @@ -4403,6 +4405,8 @@ SUBROUTINE mp_init(RAINNC,SNOWNC,GRAUPELNC,config_flags,restart,warm_rain, USE module_mp_wdm6 USE module_mp_wdm7 USE module_mp_udm + USE module_mp_tempo_cfgs, only : ty_tempo_cfgs + USE module_mp_tempo_driver, only : tempo_init #if (WRFPLUS != 1) & !defined( VAR4D ) USE module_mp_nssl_2mom, only: nssl_2mom_init #endif @@ -4447,6 +4451,8 @@ SUBROUTINE mp_init(RAINNC,SNOWNC,GRAUPELNC,config_flags,restart,warm_rain, INTEGER, INTENT(IN) :: num_sc ! G. Thompson REAL, DIMENSION(ims:ime,kms:kme,jms:jme, num_sc), INTENT(INOUT):: scalar ! G. Thompson + type(ty_tempo_cfgs) :: tempo_cfgs ! for tempo + logical :: config_tempo_aerosolaware, config_tempo_hailaware ! Local INTEGER :: i, j, itf, jtf REAL, DIMENSION(20) :: nssl_params @@ -4575,6 +4581,14 @@ SUBROUTINE mp_init(RAINNC,SNOWNC,GRAUPELNC,config_flags,restart,warm_rain, IMS=ims, IME=ime, JMS=jms, JME=jme, KMS=kms, KME=kme, & ITS=its, ITE=ite, JTS=jts, JTE=jte, KTS=kts, KTE=kte) + CASE (TEMPO) + config_tempo_aerosolaware = .false. + config_tempo_hailaware = .false. + if (config_flags%tempo_aerosolaware == 1) config_tempo_aerosolaware = .true. + if (config_flags%tempo_hailaware == 1) config_tempo_hailaware = .true. + CALL tempo_init(aerosolaware_flag=config_tempo_aerosolaware, & + hailaware_flag=config_tempo_hailaware, tempo_cfgs=tempo_cfgs) + CASE (MORR_TWO_MOMENT) CALL morr_two_moment_init( config_flags%morr_rimed_ice ) #if (EM_CORE==1) diff --git a/share/module_check_a_mundo.F b/share/module_check_a_mundo.F index 03bb74ba96..6ab24c7848 100644 --- a/share/module_check_a_mundo.F +++ b/share/module_check_a_mundo.F @@ -2533,7 +2533,9 @@ END FUNCTION bep_bem_ngr_u ! Set aer_init_opt for Thompson-MP-Aero (mp_physics=28) AND rcon mp (mp_physics=29) !----------------------------------------------------------------------- DO i = 1, model_config_rec % max_dom - IF ( model_config_rec%mp_physics(i) .EQ. THOMPSONAERO .OR. model_config_rec%mp_physics(i) .EQ. RCON_MP_SCHEME ) THEN + IF ( model_config_rec%mp_physics(i) .EQ. THOMPSONAERO .OR. & + (model_config_rec%mp_physics(i) .EQ. TEMPO .AND. model_config_rec%tempo_aerosolaware .EQ. 1) .OR. & + model_config_rec%mp_physics(i) .EQ. RCON_MP_SCHEME ) THEN IF ( model_config_rec%use_aero_icbc ) THEN model_config_rec%aer_init_opt = 1 ELSE IF ( model_config_rec%use_rap_aero_icbc ) THEN From b148c1ef8841a41add1f6f5a7cabf696765aa2d3 Mon Sep 17 00:00:00 2001 From: Anthony Islas <128631809+islas@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:06:03 -0700 Subject: [PATCH 3/7] CMake Better nf-config libdir detection (#2161) TYPE: enhancement KEYWORDS: cmake, netcdf, netcdf-fortran, nf-config SOURCE: internal DESCRIPTION OF CHANGES: Problem: As nf-config does not provide an equivalent --libdir output we must derive the info ourselves. --flibs provided the info previously, but it may be more practical to use the --prefix output and search suspected suffixes instead as --flibs contains other libraries' link info. Solution: Use output of --prefix from nf-config as the primary source of library dir. To handle the cases where --prefix is empty, we still fall back to --flibs and if that proves insufficient then the as a last resort one directory above the include directory can be used as a substitute for the prefix. TESTS CONDUCTED: 1. Tested with netCDF-Fortran v4.6.2, modifying nf-config to emulate fallback if clauses RELEASE NOTE: Better nf-config libdir detection in CMake build --- cmake/modules/FindnetCDF-Fortran.cmake | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/cmake/modules/FindnetCDF-Fortran.cmake b/cmake/modules/FindnetCDF-Fortran.cmake index 1b413f0721..c05d2c0191 100644 --- a/cmake/modules/FindnetCDF-Fortran.cmake +++ b/cmake/modules/FindnetCDF-Fortran.cmake @@ -81,9 +81,19 @@ else() endforeach() - # A bug in previous netcdf-fortran cmake builds, extract from flibs - string( REGEX MATCH "^-L([^ ]*)" netCDF-Fortran_LIBRARY_LINK_LOCATION ${netCDF-Fortran_FLIBS} ) - set( netCDF-Fortran_LIBRARY_DIR ${CMAKE_MATCH_1} ) + # A bug in previous netcdf-fortran cmake builds, extract from prefix, flibs, or include in priority order + if( NOT "${netCDF-Fortran_PREFIX}" STREQUAL "" ) + # fall back to the prefix + set( netCDF-Fortran_LIBRARY_DIR ${netCDF-Fortran_PREFIX} ) + elseif ( NOT "${netCDF-Fortran_FLIBS}" STREQUAL "" ) + # flibs valid + string( REGEX MATCH "^-L([^ ]*)" netCDF-Fortran_LIBRARY_LINK_LOCATION ${netCDF-Fortran_FLIBS} ) + set( netCDF-Fortran_LIBRARY_DIR ${CMAKE_MATCH_1} ) + else() + # fall back EVEN further to include + string( REGEX MATCH "^([^ ]*)/include" netCDF-Fortran_LIBRARY_LINK_LOCATION ${netCDF-Fortran_INCLUDE_DIR} ) + set( netCDF-Fortran_LIBRARY_DIR ${CMAKE_MATCH_1} ) + endif() set( netCDF-Fortran_DEFINITIONS ) set( netCDF-Fortran_LIBRARIES @@ -99,6 +109,9 @@ else() netcdff PATHS ${netCDF-Fortran_LIBRARY_DIR} NO_DEFAULT_PATH + PATH_SUFFIXES + lib/ + lib64/ ) endif() @@ -110,6 +123,7 @@ find_package_handle_standard_args( netCDF-Fortran FOUND_VAR netCDF-Fortran_FOUND REQUIRED_VARS + netCDF-Fortran_LIBRARY netCDF-Fortran_INCLUDE_DIRS netCDF-Fortran_LIBRARIES netCDF-Fortran_VERSION From e462ce7dc73fce581264806889f8d0e2dde82d83 Mon Sep 17 00:00:00 2001 From: Anthony Islas <128631809+islas@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:08:52 -0700 Subject: [PATCH 4/7] CMake DA Core (#2092) TYPE: enhancement KEYWORDS: cmake, da SOURCE: internal DESCRIPTION OF CHANGES: Problem: The current CMake build does not support building the DA core Solution: Allow the selection and building of the DA core. Some minor changes to source code were made to facilitate the compilation without resorting to in situ file rewrites with `sed`. These changes fix compilation errors with `iargc` intrinsic function in gfortran but still allow the original make / cpp preprocessing to work as originally done. A notable difference to the original DA build is that no source code is copied or duplicated into the folders. Instead in the respective folders used for shared source code between cores if a DA build is requested only select files are compiled. Otherwise the full set of files in those directories is used. Additionally, WAVELET, CRTM, and BUFR can be selected as CMake options (not environment variables). All are defaulted to on in this iteration. --- CMakeLists.txt | 52 +++- cmake/target_source_properties.cmake | 7 +- cmake/wrf_case_setup.cmake | 4 + frame/CMakeLists.txt | 46 +-- share/CMakeLists.txt | 74 +++-- tools/CMakeLists.txt | 4 + var/CMakeLists.txt | 67 +++++ var/da/CMakeLists.txt | 275 +++++++++++++++++ var/da/da_util/da_advance_time.f90 | 2 + var/external/bufr/CMakeLists.txt | 283 ++++++++++++++++++ var/external/crtm_2.3.0/CMakeLists.txt | 32 ++ var/external/crtm_2.3.0/libsrc/CMakeLists.txt | 202 +++++++++++++ var/external/wavelet/CMakeLists.txt | 64 ++++ var/gen_be/CMakeLists.txt | 63 ++++ var/gen_be/gen_be_ep2.f90 | 2 + var/gen_be/gen_be_stage0_gsi.f90 | 2 + var/gen_be/gen_be_stage0_wrf.f90 | 3 +- 17 files changed, 1120 insertions(+), 62 deletions(-) create mode 100644 var/CMakeLists.txt create mode 100644 var/da/CMakeLists.txt create mode 100644 var/external/bufr/CMakeLists.txt create mode 100644 var/external/crtm_2.3.0/CMakeLists.txt create mode 100644 var/external/crtm_2.3.0/libsrc/CMakeLists.txt create mode 100644 var/external/wavelet/CMakeLists.txt create mode 100644 var/gen_be/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 737844d489..ad9e8a62ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,12 @@ set( INTIO ON CACHE BOOL "INTIO" ) set( KEEP_INT_AROUND ON CACHE BOOL "KEEP_INT_AROUND" ) set( LIMIT_ARGS ON CACHE BOOL "LIMIT_ARGS" ) +# WRF DA +set( ENABLE_CRTM ON CACHE BOOL "ENABLE_CRTM" ) # todo this is always set unless env var = 0 in make +set( ENABLE_WAVELET ON CACHE BOOL "ENABLE_WAVELET" ) # todo I think this should always be on +set( ENABLE_BUFR ON CACHE BOOL "ENABLE_BUFR" ) # todo I think the config is defaulting this on + + # Toggles, how do we want to best address these options? Environment vars are not # the best set( WRFIO_NCD_NO_LARGE_FILE_SUPPORT OFF CACHE BOOL "WRFIO_NCD_NO_LARGE_FILE_SUPPORT" ) @@ -591,6 +597,12 @@ print_option( INTIO 20 ) print_option( KEEP_INT_AROUND 20 ) print_option( LIMIT_ARGS 20 ) + +print_option( ENABLE_CRTM 20 ) +print_option( ENABLE_WAVELET 20 ) +print_option( ENABLE_BUFR 20 ) + + print_option( FORCE_NETCDF_CLASSIC 20 ) print_option( BUILD_RRTMG_FAST 20 ) print_option( BUILD_RRTMK 20 ) @@ -845,8 +857,18 @@ else() list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS WRFPLUS=0 ) endif() -if ( "${WRF_CORE}" STREQUAL "DA_CORE" OR "${WRF_CORE}" STREQUAL "DA_4D_VAR" ) - list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS DA_CORE=1 ) +if ( "${WRF_CORE}" STREQUAL "DA" OR "${WRF_CORE}" STREQUAL "DA_4D_VAR" ) + if ( ${ENABLE_WAVELET} ) + list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS WAVELET ) + endif() + if ( ${ENABLE_CRTM} ) + list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS CRTM ) + endif() + if ( ${ENABLE_BUFR} ) + list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS BUFR ) + endif() + + list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS DA_CORE=1 -DFFTPACK -DNORESHAPE ) else() list( APPEND PROJECT_COMPILE_DEFINITIONS_OPTIONS DA_CORE=0 ) endif() @@ -964,7 +986,6 @@ add_dependencies( ) # Add directly to core -add_subdirectory( phys ) add_subdirectory( share ) add_subdirectory( frame ) add_subdirectory( inc ) @@ -981,10 +1002,15 @@ if ( ${WRF_CORE} STREQUAL "PLUS" ) add_subdirectory( wrftladj ) endif() -add_subdirectory( dyn_em ) - - -add_subdirectory( main ) +if ( ${WRF_CORE} STREQUAL "DA" OR ${WRF_CORE} STREQUAL "DA_4D_VAR" ) + # We don't create any of the drivers for WRF in DA mode + add_subdirectory( var ) +else() + # DA does not use any of this + add_subdirectory( dyn_em ) + add_subdirectory( phys ) + add_subdirectory( main ) +endif() ################################################################################ # Add subdirectory with case info @@ -1070,6 +1096,12 @@ target_include_directories( $<$:$> $<$:$> + # DA libs + $<$:$> + $<$:$> + $<$:$> + + PRIVATE ${PROJECT_SOURCE_DIR}/dyn_em @@ -1138,6 +1170,12 @@ target_link_libraries( ${PROJECT_NAME}_Core $ $ + + # DA libs + $ + $ + $ + $ ) ################################################################################ diff --git a/cmake/target_source_properties.cmake b/cmake/target_source_properties.cmake index 42f0c02a2d..e88b7afee9 100644 --- a/cmake/target_source_properties.cmake +++ b/cmake/target_source_properties.cmake @@ -103,13 +103,16 @@ function( apply_target_source_properties ) ) if ( "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "NOTFOUND" ) # use target + if ( ${FUNC_PROP_DEBUG} ) + message( STATUS "DEBUG [${SOURCE}] : Property ${PROPERTY}' not found, using target value '${TARGET_PROPERTY_${PROPERTY}}'" ) + endif() set( SOURCE_PROPERTY_${PROPERTY} ${TARGET_PROPERTY_${PROPERTY}} ) endif() # Now apply these as prop if ( NOT "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "" ) if ( ${FUNC_PROP_DEBUG} ) - message( STATUS "DEBUG : Adding '${SOURCE_PROPERTY_${PROPERTY}}' as SOURCE_PROPERTY_${PROPERTY}") + message( STATUS "DEBUG [${SOURCE}] : Adding '${SOURCE_PROPERTY_${PROPERTY}}' as SOURCE_PROPERTY_${PROPERTY}") endif() list( APPEND SOURCE_PROPERTY_ALL ${SOURCE_PROPERTY_${PROPERTY}} ) endif() @@ -131,7 +134,7 @@ function( apply_target_source_properties ) endif() if ( ${FUNC_PROP_DEBUG} ) - message( STATUS "DEBUG : ${FUNC_PROP_AS_PROPERTY} being set to '${SOURCE_PROPERTY_ORIG} ${SOURCE_PROPERTY_ALL}'") + message( STATUS "DEBUG [${SOURCE}] : ${FUNC_PROP_AS_PROPERTY} being set to '${SOURCE_PROPERTY_ORIG} ${SOURCE_PROPERTY_ALL}'") endif() set_source_files_properties( diff --git a/cmake/wrf_case_setup.cmake b/cmake/wrf_case_setup.cmake index c92b1b6a30..0da84b6b8f 100644 --- a/cmake/wrf_case_setup.cmake +++ b/cmake/wrf_case_setup.cmake @@ -15,6 +15,10 @@ macro( wrf_setup_targets ) set( WRF_SETUP_CMD create_symlink ) endif() + if ( NOT EXISTS ${WRF_SETUP_DEST_PATH} ) + file( MAKE_DIRECTORY ${WRF_SETUP_DEST_PATH} ) + endif() + foreach ( WRF_SETUP_TARGET ${WRF_SETUP_TARGETS} ) diff --git a/frame/CMakeLists.txt b/frame/CMakeLists.txt index a678cdf1d4..f9927d07f4 100644 --- a/frame/CMakeLists.txt +++ b/frame/CMakeLists.txt @@ -99,12 +99,28 @@ if ( ${USE_RSL_LITE} ) ) endif() +set( + NON_DA_SOURCES + module_cpl.F + module_cpl_oasis3.F + clog.c + libmassv.F + + module_clear_halos.F + module_comm_nesting_dm.F + module_integrate.F + module_sm.F + ) + +if ( ${WRF_CORE} STREQUAL "DA" OR ${WRF_CORE} STREQUAL "DA_4D_VAR" ) + set( NON_DA_SOURCES "" ) +endif() + target_sources( ${PROJECT_NAME}_Core PRIVATE + # Common sources used in all cores module_internal_header_util.F - - module_configure.F module_driver_constants.F module_domain_type.F @@ -113,44 +129,36 @@ target_sources( module_wrf_error.F module_machine.F module_timing.F - # module_dm.F ${MODULE_DM} - module_cpl.F - module_cpl_oasis3.F - ${nl_dyn_source} # GENERATED - clog.c + collect_on_comm.c hires_timer.c - libmassv.F - module_clear_halos.F + module_comm_dm.F module_comm_dm_0.F module_comm_dm_1.F module_comm_dm_2.F module_comm_dm_3.F module_comm_dm_4.F - module_comm_nesting_dm.F - - - - module_integrate.F - + module_io.F module_io_quilt.F module_nesting.F - module_quilt_outbuf_ops.F - module_sm.F + module_tiles.F - - pack_utils.c wrf_debug.F wrf_num_bytes_between.c wrf_shutdown.F + + pack_utils.c + module_quilt_outbuf_ops.F + + ${NON_DA_SOURCES} ) # Disable optimizations on these files always diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 229efae1e5..8f8bb413ff 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -11,49 +11,66 @@ target_include_directories( # Now define base share # ######################################################################################################################## +set( + NON_DA_SOURCES + module_llxy.F + module_soil_pre.F + module_compute_geop.F + module_chem_share.F + module_check_a_mundo.F + module_HLaw.F + module_ctrans_aqchem.F + module_random.F + module_interp_nmm.F + module_interp_store.F + module_string_tools.F + module_MPP.F + module_optional_input.F + dfi.F + solve_interface.F + mediation_interp_domain.F + mediation_force_domain.F + mediation_feedback_domain.F + wrf_tsin.F + track_driver.F + track_input.F + module_trajectory.F + bobrand.c + wrf_timeseries.F + track_driver.F + wrf_fddaobs_in.F + mediation_nest_move.F + setfeenv.c + ) + +if ( ${WRF_CORE} STREQUAL "DA" OR ${WRF_CORE} STREQUAL "DA_4D_VAR" ) + set( NON_DA_SOURCES "" ) +endif() + target_sources( ${PROJECT_NAME}_Core PRIVATE - + # Common sources used in all cores module_model_constants.F - module_llxy.F - module_soil_pre.F + module_date_time.F module_bc.F module_bc_time_utilities.F module_get_file_names.F - module_compute_geop.F - module_chem_share.F - module_check_a_mundo.F - module_HLaw.F - module_ctrans_aqchem.F - module_random.F - module_interp_nmm.F - module_interp_store.F - module_string_tools.F - module_MPP.F module_io_wrf.F - module_io_domain.F - module_optional_input.F - input_wrf.F output_wrf.F wrf_bdyout.F wrf_bdyin.F - dfi.F + mediation_integrate.F mediation_wrfmain.F - solve_interface.F - mediation_interp_domain.F - mediation_force_domain.F - mediation_feedback_domain.F - start_domain.F init_modules.F set_timekeeping.F @@ -61,17 +78,8 @@ target_sources( sint.F wrf_ext_write_field.F wrf_ext_read_field.F - - wrf_tsin.F landread.c - track_driver.F - track_input.F - module_trajectory.F - bobrand.c - wrf_timeseries.F - track_driver.F - wrf_fddaobs_in.F - mediation_nest_move.F - setfeenv.c + + ${NON_DA_SOURCES} ) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 92dd562378..bcbf65c443 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -147,6 +147,10 @@ add_custom_command( ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/inc COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/frame + # WRF DA shenanigans that date back so far back changing to some better layout may have unintended + # consequences with external workflows. There is no harm in always doing this so that's why this is here + COMMAND + grep "^rconfig" ${PROJECT_SOURCE_DIR}/Registry/Registry.EM_COMMON > ${CMAKE_BINARY_DIR}/Registry/Registry.rconfig 2>&1 COMMAND ${CMAKE_BINARY_DIR}/tools/registry ${REGISTRY_DEFS} -DNEW_BDYS ${REGISTRY_FILE} > ${CMAKE_BINARY_DIR}/registry.log 2>&1 #!TODO Just have the registry code actually check for failure or better yet rewrite the diff --git a/var/CMakeLists.txt b/var/CMakeLists.txt new file mode 100644 index 0000000000..3a8a0b222d --- /dev/null +++ b/var/CMakeLists.txt @@ -0,0 +1,67 @@ + +if ( ${ENABLE_CRTM} ) + add_subdirectory( external/crtm_2.3.0 ) +endif() + +if ( ${ENABLE_BUFR} ) + add_subdirectory( external/bufr ) +endif() + +if ( ${ENABLE_WAVELET} ) + add_subdirectory( external/wavelet ) +endif() + +wrf_m4_preproc_fortran( + TARGET_NAME da_generic_boilerplate + OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/preproc/ + EXTENSION ".inc" + SOURCES da/da_par_util/da_generic_boilerplate.m4 + TARGET_SCOPE ${PROJECT_NAME}_Core + FLAGS ${M4_FLAGS} + ) + + +add_dependencies( ${PROJECT_NAME}_Core da_generic_boilerplate ) +target_include_directories( + ${PROJECT_NAME}_Core + PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}/preproc/ + ) + +# To somewhat mirror the DA build (and for "neatness") I won't put cmake files +# in each source folder and instead build at this level + +target_sources( + ${PROJECT_NAME}_Core + PRIVATE + # blas and lapack + external/blas/da_blas.f90 + external/lapack/da_lapack.f90 + + # da gen_be aero mod + gen_be/aero_mod.f90 + ) + + +target_include_directories( + ${PROJECT_NAME}_Core + PRIVATE + # blas and lapack + external/blas + external/lapack + ) + +# Disable float to double precision on these files always +set_source_files_properties( + # blas and lapack + external/blas/da_blas.f90 + external/lapack/da_lapack.f90 + TARGET_DIRECTORY ${PROJECT_NAME}_Core + PROPERTIES + COMPILE_OPTIONS_Fortran_PRECISION "" # set to nothing to void + ) + +# Add da/da* and gen_be executables dir +add_subdirectory( da ) +add_subdirectory( gen_be ) + diff --git a/var/da/CMakeLists.txt b/var/da/CMakeLists.txt new file mode 100644 index 0000000000..cf714ca3e7 --- /dev/null +++ b/var/da/CMakeLists.txt @@ -0,0 +1,275 @@ + +# To somewhat mirror the DA build (and for "neatness") I won't put cmake files +# in each source folder and instead build at this level + +target_sources( + ${PROJECT_NAME}_Core + PRIVATE + da_4dvar/da_4dvar.f90 + da_airep/da_airep.f90 + da_airsr/da_airsr.f90 + da_bogus/da_bogus.f90 + da_buoy/da_buoy.f90 + da_chem_sfc/da_chem_sfc.f90 + # This is not in the original da lib, but I don't see how that + # isn't correct as many modules in this require it + da_control/da_control.f90 + + + da_define_structures/da_define_structures.f90 + da_dynamics/da_dynamics.f90 + da_ffts/da_ffts.f90 + da_ffts/module_ffts.f90 + da_geoamv/da_geoamv.f90 + da_gpseph/da_gpseph.f90 + da_gpspw/da_gpspw.f90 + da_gpsref/da_gpsref.f90 + da_grid_definitions/da_grid_definitions.f90 + da_interpolation/da_interpolation.f90 + da_lightning/da_lightning.f90 + da_main/copyfile.c + da_main/da_wrfvar_io.f90 + da_main/da_wrfvar_top.f90 + da_metar/da_metar.f90 + da_minimisation/da_minimisation.f90 + da_mtgirs/da_mtgirs.f90 + da_obs_io/da_join_iv_for_multi_inc.c + da_obs_io/da_obs_io.f90 + da_obs/da_obs.f90 + da_par_util/da_par_util.f90 + da_par_util/da_par_util1.f90 + da_physics/da_physics.f90 + da_physics/f_qv_from_rh.f90 + da_pilot/da_pilot.f90 + da_polaramv/da_polaramv.f90 + da_profiler/da_profiler.f90 + da_pseudo/da_pseudo.f90 + da_qscat/da_qscat.f90 + da_radar/da_radar.f90 + da_radiance/amsr2time_.c + da_radiance/da_crtm.f90 + da_radiance/da_radiance.f90 + da_radiance/da_radiance1.f90 + da_radiance/da_rttov.f90 + da_radiance/gsi_constants.f90 + da_radiance/gsi_kinds.f90 + da_radiance/gsi_thinning.f90 + da_radiance/mod_clddet_geoir.f90 + da_radiance/module_radiance.f90 + da_rain/da_rain.f90 + da_recursive_filter/da_mat_cv3.f90 + da_recursive_filter/da_recursive_filter.f90 + da_recursive_filter/da_rf_cv3.f90 + da_recursive_filter/da_rfz_cv3.f90 + da_reporting/da_reporting.f90 + da_satem/da_satem.f90 + da_setup_structures/da_setup_structures.f90 + da_ships/da_ships.f90 + da_sound/da_sound.f90 + da_spectral/da_spectral.f90 + da_spectral/da_be_spectral.f90 + da_ssmi/da_ssmi.f90 + da_ssmi/module_ssmi.f90 + da_statistics/da_statistics.f90 + da_synop/da_synop.f90 + da_tamdar/da_tamdar.f90 + da_test/da_test.f90 + da_tools/da_rsl_interfaces.f90 + da_tools/da_tools_serial.f90 + da_tools/da_tools.f90 + da_tools/da_wrf_interfaces.f90 + da_tools/gamma1.f90 + da_tracing/da_memory.c + da_tracing/da_tracing.f90 + da_transfer_model/da_transfer_model.f90 + da_update_bc/da_netcdf_interface.f90 + da_varbc_tamdar/da_varbc_tamdar.f90 + da_varbc/da_varbc.f90 + da_vtox_transforms/da_vtox_transforms.f90 + da_wavelet/da_wavelet.f90 + # For da_bias_* + da_biascorr_airmass/rad_bias.f90 + + # for gen_be + da_gen_be/da_gen_be.f90 + da_etkf/da_etkf.f90 + + ) + + +target_include_directories( + ${PROJECT_NAME}_Core + PRIVATE + da_4dvar + da_airep + da_airsr + da_bogus + da_buoy + da_chem_sfc + da_define_structures + da_dynamics + da_etkf + da_ffts + da_gen_be + da_geoamv + da_gpseph + da_gpspw + da_gpsref + da_grid_definitions + da_interpolation + da_lightning + da_main + da_metar + da_minimisation + da_mtgirs + da_obs + da_obs_io + da_par_util + da_physics + da_pilot + da_polaramv + da_profiler + da_pseudo + da_qscat + da_radar + da_radiance + da_rain + da_recursive_filter + da_reporting + da_satem + da_setup_structures + da_ships + da_sound + da_spectral + da_ssmi + da_statistics + da_synop + da_tamdar + da_test + da_tools + da_tracing + da_transfer_model + da_update_bc + da_varbc + da_varbc_tamdar + da_vtox_transforms + da_wavelet + ) + +# DA util executables +set( DA_EXECUTABLES ) +add_executable( da_tune_obs_hollingsworth1 da_util/da_tune_obs_hollingsworth1.f90 ) +list( APPEND DA_EXECUTABLES da_tune_obs_hollingsworth1 ) + + +add_executable( da_tune_obs_hollingsworth2 da_util/da_tune_obs_hollingsworth2.f90 ) +list( APPEND DA_EXECUTABLES da_tune_obs_hollingsworth2 ) + + +add_executable( da_tune_obs_desroziers da_util/da_tune_obs_desroziers.f90 ) +list( APPEND DA_EXECUTABLES da_tune_obs_desroziers ) + + +add_executable( da_update_bc + da_update_bc/da_update_bc.f90 + da_update_bc/da_module_couple_uv.f90 + ) +target_include_directories( da_update_bc PRIVATE da_update_bc ) +list( APPEND DA_EXECUTABLES da_update_bc ) + + +add_executable( da_update_bc_ad + da_update_bc/da_update_bc_ad.f90 + da_update_bc/da_module_couple_uv.f90 + da_update_bc/da_module_couple_uv_ad.f90 + ) +target_include_directories( da_update_bc_ad PRIVATE da_update_bc ) +list( APPEND DA_EXECUTABLES da_update_bc_ad ) + + +add_executable( da_advance_time da_util/da_advance_time.f90 ) +list( APPEND DA_EXECUTABLES da_advance_time ) + + +add_executable( da_verif_obs + da_verif_obs/da_verif_obs.f90 + da_verif_obs/da_verif_obs_control.f90 + da_verif_obs/da_verif_obs_init.f90 + da_verif_obs/da_verif_tools.f90 + ) +list( APPEND DA_EXECUTABLES da_verif_obs ) + + + +add_executable( da_verif_grid + da_verif_grid/da_verif_grid.f90 + da_verif_grid/da_verif_grid_control.f90 + ) +list( APPEND DA_EXECUTABLES da_verif_grid ) + + + +add_executable( da_bias_airmass + da_biascorr_airmass/da_bias_airmass.f90 + da_biascorr_airmass/pythag.f90 + da_biascorr_airmass/tqli.f90 + da_biascorr_airmass/tred2.f90 + da_biascorr_airmass/regress_one.f90 + ) +list( APPEND DA_EXECUTABLES da_bias_airmass ) + + + +add_executable( da_bias_sele da_biascorr_airmass/da_bias_sele.f90 ) +list( APPEND DA_EXECUTABLES da_bias_sele ) + + +add_executable( da_bias_scan da_biascorr_airmass/da_bias_scan.f90 ) +list( APPEND DA_EXECUTABLES da_bias_scan ) + + +add_executable( da_bias_verif da_biascorr_airmass/da_bias_verif.f90 ) +list( APPEND DA_EXECUTABLES da_bias_verif ) + + +add_executable( da_rad_diags da_monitor/da_rad_diags.f90 ) +list( APPEND DA_EXECUTABLES da_rad_diags ) + +# Now finally da_wrfvar +add_executable( da_wrfvar da_main/da_wrfvar_main.f90 ) +list( APPEND DA_EXECUTABLES da_wrfvar ) + +foreach( DA_EXEC ${DA_EXECUTABLES} ) + target_link_libraries( + ${DA_EXEC} + PRIVATE + ${PROJECT_NAME}_Core + $<$:$> + $<$:$> + ) + target_link_options ( ${DA_EXEC} PRIVATE ${WRF_LINK_FLAGS} ) + target_compile_definitions( ${DA_EXEC} PRIVATE ${PROJECT_COMPILE_DEFINITIONS} ) + target_compile_options ( ${DA_EXEC} PRIVATE ${PROJECT_COMPILE_OPTIONS} ) + + set_target_properties( + ${DA_EXEC} + PROPERTIES + # Just dump everything in here + Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/modules/${DA_EXEC}/ + ) + +endforeach() + +install( + TARGETS ${DA_EXECUTABLES} + EXPORT ${EXPORT_NAME}Targets + RUNTIME DESTINATION bin/ + ARCHIVE DESTINATION lib/ + LIBRARY DESTINATION lib/ + ) + +wrf_setup_targets( + TARGETS ${DA_EXECUTABLES} + DEST_PATH ${CMAKE_INSTALL_PREFIX}/run + USE_SYMLINKS + ) diff --git a/var/da/da_util/da_advance_time.f90 b/var/da/da_util/da_advance_time.f90 index 71b69c0000..379d93d43f 100644 --- a/var/da/da_util/da_advance_time.f90 +++ b/var/da/da_util/da_advance_time.f90 @@ -31,7 +31,9 @@ program da_advance_time ! integer function iargc() ! end function iargc ! end interface +#ifndef __GFORTRAN__ integer, external :: iargc +#endif integer :: ccyy, mm, dd, hh, nn, ss, dday, dh, dn, ds, gday, gsec diff --git a/var/external/bufr/CMakeLists.txt b/var/external/bufr/CMakeLists.txt new file mode 100644 index 0000000000..9aeec38482 --- /dev/null +++ b/var/external/bufr/CMakeLists.txt @@ -0,0 +1,283 @@ +# WRF CMake Build +get_filename_component( FOLDER_COMPILE_TARGET ${CMAKE_CURRENT_SOURCE_DIR} NAME ) + +add_library( + ${FOLDER_COMPILE_TARGET} + STATIC + adn30.f + atrcpt.f + bfrini.f + blocks.f + bort_exit.c + bort.f + bort2.f + bvers.f + cadn30.f + capit.f + ccbfl.c + chekstab.f + chrtrn.f + chrtrna.f + cktaba.f + closbf.f + closmg.f + cmpia.c + cmpmsg.f + cmsgini.f + cnved4.f + cobfl.c + conwin.f + copybf.f + copymg.f + copysb.f + cpbfdx.f + cpdxmm.f + cpymem.f + cpyupd.f + crbmg.c + cread.c + cwbmg.c + datebf.f + datelen.f + digit.f + drfini.f + drstpl.f + dumpbf.f + dxdump.f + dxinit.f + dxmini.f + elemdx.f + errwrt.f + getabdb.f + getbmiss.f + getlens.f + getntbe.f + gets1loc.f + gettagpr.f + gettbh.f + getvalnb.f + getwin.f + i4dy.f + ibfms.f + icbfms.f + ichkstr.f + icmpdx.f + icopysb.f + icvidx.c + idn30.f + idxmsg.f + ifbget.f + ifxy.f + igetdate.f + igetfxy.f + igetntbi.f + igetntbl.f + igetsc.f + igettdi.f + inctab.f + invcon.f + invmrg.f + invtag.f + invwin.f + iok2cpy.f + ipkm.f + ipks.f + ireadmg.f + ireadmm.f + ireadns.f + ireadsb.f + irev.for + ishrdx.f + isize.f + istdesc.f + iupb.f + iupbs01.f + iupbs3.f + iupm.f + iupvs01.f + jstchr.f + jstnum.f + lcmgdf.f + lmsg.f + lstjpb.f + makestab.f + maxout.f + mesgbc.f + mesgbf.f + minimg.f + mrginv.f + msgfull.f + msgini.f + msgupd.f + msgwrt.f + mtinfo.f + mvb.f + nemock.f + nemtab.f + nemtba.f + nemtbax.f + nemtbb.f + nemtbd.f + nenubd.f + nevn.f + newwin.f + nmsub.f + nmwrd.f + numbck.f + nummtb.c + numtab.f + numtbd.f + nvnwin.f + nwords.f + nxtwin.f + openbf.f + openbt.f + openmb.f + openmg.f + pad.f + padmsg.f + parstr.f + parusr.f + parutg.f + pkb.f + pkbs1.f + pkc.f + pkftbv.f + pktdd.f + pkvs01.f + posapx.f + rbytes.c + rcstpl.f + rdbfdx.f + rdcmps.f + rdmemm.f + rdmems.f + rdmgsb.f + rdmsgb.f + rdmsgw.f + rdmtbb.f + rdmtbd.f + rdtree.f + rdusdx.f + readdx.f + readerme.f + readlc.f + readmg.f + readmm.f + readmt.f + readns.f + reads3.f + readsb.f + restd.c + rewnbf.f + rjust.f + rsvfvm.f + rtrcpt.f + seqsdx.f + setblock.f + setbmiss.f + sntbbe.f + sntbde.f + status.f + stbfdx.f + stdmsg.f + stndrd.f + stntbi.f + stntbia.f + strcln.f + strcpt.f + string.f + strnum.f + strsuc.f + stseq.c + tabent.f + tabsub.f + trybump.f + ufbcnt.f + ufbcpy.f + ufbcup.f + ufbdmp.f + ufbevn.f + ufbget.f + ufbin3.f + ufbint.f + ufbinx.f + ufbmem.f + ufbmex.f + ufbmms.f + ufbmns.f + ufbovr.f + ufbpos.f + ufbqcd.f + ufbqcp.f + ufbrep.f + ufbrms.f + ufbrp.f + ufbrw.f + ufbseq.f + ufbsp.f + ufbstp.f + ufbtab.f + ufbtam.f + ufdump.f + upb.f + upbb.f + upc.f + upds3.f + upftbv.f + ups.f + uptdd.f + usrtpl.f + valx.f + wrcmps.f + wrdesc.c + wrdlen.for + wrdxtb.f + writcp.f + writdx.f + writlc.f + writsa.f + writsb.f + wrtree.f + wtstat.f + ) + +set_target_properties( + ${FOLDER_COMPILE_TARGET} + PROPERTIES + Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${FOLDER_COMPILE_TARGET} + EXPORT_PROPERTIES Fortran_MODULE_DIRECTORY + Fortran_FORMAT FIXED + ) + + +target_compile_options( + ${FOLDER_COMPILE_TARGET} + PRIVATE + ${PROJECT_COMPILE_OPTIONS_OPTIMIZATION} + ${PROJECT_COMPILE_OPTIONS_Fortran_LINE_LENGTH} + ${PROJECT_COMPILE_OPTIONS_SUPPRESS_WARNINGS} + ${PROJECT_COMPILE_OPTIONS_SUPPRESS_ERRORS} + ) + +target_compile_definitions( + ${FOLDER_COMPILE_TARGET} + PRIVATE + UNDERSCORE + ) + +set_source_files_properties( + irev.for + wrdlen.for + TARGET_DIRECTORY ${FOLDER_COMPILE_TARGET} + PROPERTIES + COMPILE_DEFINITIONS ${CMAKE_C_BYTE_ORDER} # Use C byte order to mirror make build + ) + +install( + TARGETS ${FOLDER_COMPILE_TARGET} + EXPORT ${EXPORT_NAME}Targets + RUNTIME DESTINATION bin/ + ARCHIVE DESTINATION lib/ + LIBRARY DESTINATION lib/ + ) diff --git a/var/external/crtm_2.3.0/CMakeLists.txt b/var/external/crtm_2.3.0/CMakeLists.txt new file mode 100644 index 0000000000..2c74db7b99 --- /dev/null +++ b/var/external/crtm_2.3.0/CMakeLists.txt @@ -0,0 +1,32 @@ +# WRF CMake Build +# get_filename_component( FOLDER_COMPILE_TARGET ${CMAKE_CURRENT_SOURCE_DIR} NAME) +set( FOLDER_COMPILE_TARGET CRTM ) + +add_library( + ${FOLDER_COMPILE_TARGET} + STATIC + ) + +set_target_properties( + ${FOLDER_COMPILE_TARGET} + PROPERTIES + Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${FOLDER_COMPILE_TARGET} + EXPORT_PROPERTIES Fortran_MODULE_DIRECTORY + Fortran_FORMAT FREE + ) + +target_compile_options( + ${FOLDER_COMPILE_TARGET} + PRIVATE + ${WRF_FCOPTIM} # No other source langauges so this is fine + ) + +add_subdirectory( libsrc ) + +install( + TARGETS ${FOLDER_COMPILE_TARGET} + EXPORT ${EXPORT_NAME}Targets + RUNTIME DESTINATION bin/ + ARCHIVE DESTINATION lib/ + LIBRARY DESTINATION lib/ + ) diff --git a/var/external/crtm_2.3.0/libsrc/CMakeLists.txt b/var/external/crtm_2.3.0/libsrc/CMakeLists.txt new file mode 100644 index 0000000000..4be7a34b93 --- /dev/null +++ b/var/external/crtm_2.3.0/libsrc/CMakeLists.txt @@ -0,0 +1,202 @@ +target_include_directories( ${FOLDER_COMPILE_TARGET} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + +target_sources( + ${FOLDER_COMPILE_TARGET} + PRIVATE + # The list of files that need preprocessing + CRTM_Module.fpp + + # The list of regular source files + Type_Kinds.f90 + File_Utility.f90 + Message_Handler.f90 + Date_Utility.f90 + DateTime_Utility.f90 + Timing_Utility.f90 + Compare_Float_Numbers.f90 + Endian_Utility.f90 + Binary_File_Utility.f90 + Sort_Utility.f90 + Search_Utility.f90 + String_Utility.f90 + Fundamental_Constants.f90 + Hyperbolic_Step.f90 + Spectral_Units_Conversion.f90 + UnitTest_Define.f90 + SensorInfo_Parameters.f90 + Subset_Define.f90 + SpcCoeff_Define.f90 + ACCoeff_Define.f90 + NLTECoeff_Define.f90 + SpcCoeff_Binary_IO.f90 + ACCoeff_Binary_IO.f90 + NLTECoeff_Binary_IO.f90 + CloudCoeff_Define.f90 + CloudCoeff_Binary_IO.f90 + AerosolCoeff_Define.f90 + AerosolCoeff_Binary_IO.f90 + CRTM_Options_Define.f90 + CRTM_AOD_Module.f90 + IRwaterCoeff_Define.f90 + SEcategory_Define.f90 + LSEatlas_Define.f90 + MWwaterCoeff_Define.f90 + FitCoeff_Define.f90 + MWwaterLUT_Define.f90 + NESDIS_AMSRE_SICEEM_Module.f90 + NESDIS_AMSRE_SNOWEM_Module.f90 + NESDIS_AMSU_SICEEM_Module.f90 + NESDIS_AMSU_SnowEM_Module.f90 + NESDIS_MHS_SICEEM_Module.f90 + NESDIS_MHS_SnowEM_Module.f90 + NESDIS_LandEM_Module.f90 + NESDIS_SEAICE_PHYEM_MODULE.f90 + NESDIS_SnowEM_Parameters.f90 + NESDIS_SSMI_Module.f90 + NESDIS_SSMI_SIceEM_Module.f90 + NESDIS_SSMI_SnowEM_Module.f90 + NESDIS_SSMIS_SeaIceEM_Module.f90 + NESDIS_SSMIS_SnowEM_Module.f90 + NESDIS_SnowEM_ATMS_Parameters.f90 + NESDIS_ATMS_SnowEM_Module.f90 + NESDIS_ATMS_SeaICE_LIB.f90 + NESDIS_ATMS_SeaICE_Module.f90 + CRTM_Utility.f90 + CRTM_Interpolation.f90 + CRTM_SpcCoeff.f90 + CRTM_TauCoeff.f90 + TauCoeff_Define.f90 + CRTM_AerosolCoeff.f90 + CRTM_CloudCoeff.f90 + CRTM_IRlandCoeff.f90 + CRTM_IRwaterCoeff.f90 + CRTM_IRsnowCoeff.f90 + CRTM_IRiceCoeff.f90 + CRTM_VISlandCoeff.f90 + CRTM_VISwaterCoeff.f90 + CRTM_VISsnowCoeff.f90 + CRTM_VISiceCoeff.f90 + CRTM_MWwaterCoeff.f90 + CRTM_Atmosphere_Define.f90 + CRTM_Cloud_Define.f90 + CRTM_Aerosol_Define.f90 + CRTM_Surface_Define.f90 + CRTM_SensorData_Define.f90 + CRTM_SensorInfo.f90 + CRTM_ChannelInfo_Define.f90 + CRTM_Geometry_Define.f90 + CRTM_GeometryInfo_Define.f90 + CRTM_GeometryInfo.f90 + CRTM_Atmosphere.f90 + iAtm_Define.f90 + CRTM_CloudCover_Define.f90 + CRTM_Model_Profiles.f90 + CRTM_AerosolScatter.f90 + ASvar_Define.f90 + CRTM_CloudScatter.f90 + CSvar_Define.f90 + CRTM_MoleculeScatter.f90 + CRTM_SfcOptics_Define.f90 + CRTM_SfcOptics.f90 + CRTM_IR_Land_SfcOptics.f90 + CRTM_IR_Water_SfcOptics.f90 + CRTM_IR_Snow_SfcOptics.f90 + CRTM_IR_Ice_SfcOptics.f90 + CRTM_MW_Land_SfcOptics.f90 + CRTM_MW_Water_SfcOptics.f90 + CRTM_MW_Snow_SfcOptics.f90 + CRTM_MW_Ice_SfcOptics.f90 + CRTM_VIS_Land_SfcOptics.f90 + CRTM_VIS_Water_SfcOptics.f90 + CRTM_VIS_Snow_SfcOptics.f90 + CRTM_VIS_Ice_SfcOptics.f90 + CRTM_SEcategory.f90 + CRTM_LowFrequency_MWSSEM.f90 + CRTM_Fastem1.f90 + CRTM_FastemX.f90 + Reflection_Correction_Module.f90 + Azimuth_Emissivity_Module.f90 + Azimuth_Emissivity_F6_Module.f90 + Small_Scale_Correction_Module.f90 + Large_Scale_Correction_Module.f90 + Foam_Utility_Module.f90 + Slope_Variance.f90 + Guillou.f90 + Ellison.f90 + Liu.f90 + Fresnel.f90 + CRTM_IRSSEM.f90 + CRTM_AtmOptics.f90 + CRTM_AtmOptics_Define.f90 + AOvar_Define.f90 + CRTM_Planck_Functions.f90 + RTV_Define.f90 + SOI_Module.f90 + ADA_Module.f90 + Emission_Module.f90 + CRTM_RTSolution_Define.f90 + Common_RTSolution.f90 + CRTM_RTSolution.f90 + CRTM_AntennaCorrection.f90 + CRTM_AncillaryInput_Define.f90 + SSU_Input_Define.f90 + Zeeman_Input_Define.f90 + CRTM_Parameters.f90 + CRTM_LifeCycle.f90 + CRTM_Forward_Module.f90 + CRTM_Tangent_Linear_Module.f90 + CRTM_Adjoint_Module.f90 + CRTM_K_Matrix_Module.f90 + CRTM_AtmAbsorption.f90 + CRTM_Predictor.f90 + CRTM_Predictor_Define.f90 + ODAS_AtmAbsorption.f90 + ODAS_Predictor.f90 + ODAS_Predictor_Define.f90 + ODAS_Binary_IO.f90 + ODAS_Define.f90 + ODAS_TauCoeff.f90 + ODPS_AtmAbsorption.f90 + ODPS_Predictor.f90 + ODPS_Predictor_Define.f90 + PAFV_Define.f90 + ODPS_Binary_IO.f90 + ODPS_Define.f90 + ODPS_TauCoeff.f90 + CRTM_GeometryInfo.f90 + ODSSU_AtmAbsorption.f90 + ODSSU_Define.f90 + ODSSU_Binary_IO.f90 + ODSSU_TauCoeff.f90 + Profile_Utility_Parameters.f90 + ODPS_CoordinateMapping.f90 + ODZeeman_TauCoeff.f90 + ODZeeman_AtmAbsorption.f90 + ODZeeman_Predictor.f90 + Zeeman_Utility.f90 + CRTM_NLTECorrection.f90 + NLTE_Parameters.f90 + NLTE_Predictor_Define.f90 + NLTE_Predictor_IO.f90 + ) +if ( ${CMAKE_Fortran_COMPILER_ID} STREQUAL "PGI" ) + set_source_files_properties( + Sort_Utility.f90 + TARGET_DIRECTORY ${FOLDER_COMPILE_TARGET} + PROPERTIES + COMPILE_OPTIONS -tp=px + ) +endif() + +# if ( ${CMAKE_Fortran_COMPILER_ID} STREQUAL "Cray" ) +# set_source_files_properties( +# Sort_Utility.f90 +# TARGET_DIRECTORY ${FOLDER_COMPILE_TARGET} +# PROPERTIES +# COMPILE_FLAGS -01 # TODO - find a better way to control these flags +# ) +# endif() diff --git a/var/external/wavelet/CMakeLists.txt b/var/external/wavelet/CMakeLists.txt new file mode 100644 index 0000000000..62a88d9076 --- /dev/null +++ b/var/external/wavelet/CMakeLists.txt @@ -0,0 +1,64 @@ +# WRF CMake Build +get_filename_component( FOLDER_COMPILE_TARGET ${CMAKE_CURRENT_SOURCE_DIR} NAME ) + +add_library( + ${FOLDER_COMPILE_TARGET} # C library + STATIC + awaprogs/chap05/cd.c + dwtai.c + dwtai_w.c + dwtai2.c + dwtai2_w.c + DWTAPartition.c + idwtai.c + idwtai_w.c + idwtai2.c + idwtai2_w.c + l2norm.c + PrintFilter.c + awaprogs/chap05/qf.c + qf_w.c + qftest.c + qftest_w.c + TestFilter.c + awaprogs/chap09/xp.c + ) + + +add_library( + ${FOLDER_COMPILE_TARGET}f # Fortran library + STATIC + dwta_partition.F90 + print_filter.F90 + test_filter.F90 + ) + + +target_include_directories( + ${FOLDER_COMPILE_TARGET} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/awaprogs/chap02 + ${CMAKE_CURRENT_SOURCE_DIR}/awaprogs/chap05 + ) + +# This is new in the cmake build +target_compile_options( + ${FOLDER_COMPILE_TARGET} + PRIVATE + ${PROJECT_COMPILE_OPTIONS_OPTIMIZATION} + ) + +target_compile_definitions( + ${FOLDER_COMPILE_TARGET} + PRIVATE + ${PROJECT_COMPILE_DEFINITIONS_CONFCHECK} + ) + +install( + TARGETS ${FOLDER_COMPILE_TARGET} ${FOLDER_COMPILE_TARGET}f + EXPORT ${EXPORT_NAME}Targets + RUNTIME DESTINATION bin/ + ARCHIVE DESTINATION lib/ + LIBRARY DESTINATION lib/ + ) diff --git a/var/gen_be/CMakeLists.txt b/var/gen_be/CMakeLists.txt new file mode 100644 index 0000000000..d232f06170 --- /dev/null +++ b/var/gen_be/CMakeLists.txt @@ -0,0 +1,63 @@ +set( + GEN_BE_EXECUTABLES + gen_be_stage0_wrf + gen_be_stage0_gsi + gen_be_ep1 + gen_be_ep2 + gen_be_stage1 + gen_be_vertloc + gen_be_addmean + gen_be_stage1_gsi + gen_be_stage1_1dvar + gen_be_stage2 + gen_be_stage2_gsi + gen_mbe_stage2 + gen_be_stage2_1dvar + gen_be_stage2a + gen_be_stage3 + gen_be_stage4_global + gen_be_stage4_regional + gen_be_cov2d + gen_be_cov3d + gen_be_cov3d3d_bin3d_contrib + gen_be_cov3d3d_contrib + gen_be_cov2d3d_contrib + gen_be_cov3d2d_contrib + gen_be_diags + gen_be_diags_read + gen_be_hist + gen_be_ensrf + gen_be_etkf + gen_be_ensmean + ) + +foreach( GEN_BE ${GEN_BE_EXECUTABLES} ) + add_executable( ${GEN_BE} ${GEN_BE}.f90 ) + target_link_libraries( + ${GEN_BE} + PRIVATE + ${PROJECT_NAME}_Core + $<$:$> + $<$:$> + ) + target_link_options ( ${GEN_BE} PRIVATE ${WRF_LINK_FLAGS} ) + target_compile_definitions( ${GEN_BE} PRIVATE ${PROJECT_COMPILE_DEFINITIONS} ) + target_compile_options ( ${GEN_BE} PRIVATE ${PROJECT_COMPILE_OPTIONS} ) + +endforeach() + + +install( + TARGETS ${GEN_BE_EXECUTABLES} + EXPORT ${EXPORT_NAME}Targets + RUNTIME DESTINATION bin/ + ARCHIVE DESTINATION lib/ + LIBRARY DESTINATION lib/ + ) + +wrf_setup_targets( + TARGETS ${GEN_BE_EXECUTABLES} + DEST_PATH ${CMAKE_INSTALL_PREFIX}/run + USE_SYMLINKS + ) + diff --git a/var/gen_be/gen_be_ep2.f90 b/var/gen_be/gen_be_ep2.f90 index d9e15238a4..71f56f1db7 100644 --- a/var/gen_be/gen_be_ep2.f90 +++ b/var/gen_be/gen_be_ep2.f90 @@ -32,7 +32,9 @@ program gen_be_ep2 character (len=3) :: ce ! Member index -> character. character (len=filename_len) :: moist_string +#ifndef __GFORTRAN__ integer, external :: iargc +#endif integer :: numarg integer :: ne ! Ensemble size. integer :: i, j, k, member ! Loop counters. diff --git a/var/gen_be/gen_be_stage0_gsi.f90 b/var/gen_be/gen_be_stage0_gsi.f90 index 6ba5f3ee36..cdba2fe4b5 100644 --- a/var/gen_be/gen_be_stage0_gsi.f90 +++ b/var/gen_be/gen_be_stage0_gsi.f90 @@ -34,7 +34,9 @@ program gen_be_stage0_gsi character (len=3) :: cne ! Ensemble size. character (len=3) :: ce ! Member index -> character. +#ifndef __GFORTRAN__ integer, external :: iargc +#endif integer :: numarg integer :: ne ! Ensemble size. integer :: i, j, k, member ! Loop counters. diff --git a/var/gen_be/gen_be_stage0_wrf.f90 b/var/gen_be/gen_be_stage0_wrf.f90 index 616ef6c92e..83ddfc503b 100644 --- a/var/gen_be/gen_be_stage0_wrf.f90 +++ b/var/gen_be/gen_be_stage0_wrf.f90 @@ -39,8 +39,9 @@ program gen_be_stage0_wrf character (len=3) :: ce ! Member index -> character. character (len=3) :: ccv_options ! Control variable input - +#ifndef __GFORTRAN__ integer, external :: iargc +#endif integer :: numarg integer :: ne ! Ensemble size. integer :: cv_options ! Control variable option From f2c697e69506c72e594c336ba2a68b3feebd6161 Mon Sep 17 00:00:00 2001 From: Soren Rasmussen Date: Thu, 12 Feb 2026 11:18:36 -0700 Subject: [PATCH 5/7] Adding WRF-Hydro PRs (#2263) TYPE: bugfix, enhancement KEYWORDS: syncing WRF-Hydro/hydro, gage-assisted diversion, bugfixes SOURCE: internal hydro team + contributor - Soren Rasmussen, NSF NCAR - Ryan Cabell, NSF NCAR - Andrew Song, Inner Mongolia Meteorological Service / China Meteorological Administration (Wrote PR#829) DESCRIPTION OF CHANGES: This PR updates the hydro directory to the [NCAR/wrf_hydro_nwm_public](https://github.com/NCAR/wrf_hydro_nwm_public) repository. It includes the following PRs - NCAR/wrf_hydro_nwm_public#756 - NCAR/wrf_hydro_nwm_public#811 - NCAR/wrf_hydro_nwm_public#816 - NCAR/wrf_hydro_nwm_public#823 - NCAR/wrf_hydro_nwm_public#829 - NCAR/wrf_hydro_nwm_public#827 - NCAR/wrf_hydro_nwm_public#855 - NCAR/wrf_hydro_nwm_public#856 - NCAR/wrf_hydro_nwm_public#861 - NCAR/wrf_hydro_nwm_public#862 LIST OF MODIFIED FILES: ``` $ git diff --name-status develop M hydro/CMakeLists.txt M hydro/CPL/WRF_cpl/CMakeLists.txt M hydro/Data_Rec/module_namelist.F90 M hydro/Data_Rec/module_namelist_inc.F90 M hydro/HYDRO_drv/module_HYDRO_drv.F90 M hydro/Makefile M hydro/OrchestratorLayer/config.F90 M hydro/Routing/CMakeLists.txt A hydro/Routing/Diversions/CMakeLists.txt A hydro/Routing/Diversions/Makefile A hydro/Routing/Diversions/module_diversions.F90 A hydro/Routing/Diversions/module_diversions_timeslice.F90 M hydro/Routing/Makefile M hydro/Routing/module_channel_routing.F90 M hydro/arc/Makefile.mpp D hydro/arc/Makefile.seq M hydro/arc/macros.mpp.cray_fortran M hydro/arc/macros.mpp.gfort M hydro/arc/macros.mpp.ifort D hydro/arc/macros.mpp.ifort.luna D hydro/arc/macros.mpp.ifort.summit_has D hydro/arc/macros.mpp.ifort.theia M hydro/arc/macros.mpp.linux D hydro/arc/macros.seq.IBM.xlf90_r D hydro/arc/macros.seq.gfort D hydro/arc/macros.seq.ifort D hydro/arc/macros.seq.linux D hydro/arc/macros.theia.debug D hydro/arc/macros.yellowstone D hydro/arc/macros.yellowstone.debug M hydro/configure M hydro/nudging/CMakeLists.txt A hydro/nudging/io/CMakeLists.txt R098 hydro/nudging/module_nudging_io.F90 hydro/nudging/io/module_nudging_io.F90 M hydro/utils/CMakeLists.txt A hydro/utils/fortglob/CMakeLists.txt A hydro/utils/fortglob/Makefile A hydro/utils/fortglob/fortglob.F90 A hydro/utils/fortglob/libfortglob.c A hydro/utils/fortglob/libfortglob.h ``` TESTS CONDUCTED: **NOTE THAT THE PR IS IN DRAFT UNTIL TESTING IS COMPLETE**. Current building and running 1. [WRF-Hydro Front Range, CO testcase](https://wrf-hydro.readthedocs.io/en/latest/appendices.html#a2-coupled-wrf-wrf-hydro-test-case-user-guide) 2. Testing multiple configurations of Make and CMake build systems RELEASE NOTE: Hydro bug fixes plus modifications to add initial support for gage-assisted diversions in channel routing, which requires a new optional Diversion netCDF parameter file. This adds a C compiler dependency --------- Co-authored-by: Ryan Cabell Co-authored-by: Andrew Song --- hydro/CMakeLists.txt | 216 +++++++++++++++--- hydro/CPL/WRF_cpl/CMakeLists.txt | 2 +- hydro/Data_Rec/module_namelist.F90 | 6 +- hydro/Data_Rec/module_namelist_inc.F90 | 1 + hydro/HYDRO_drv/module_HYDRO_drv.F90 | 6 + hydro/Makefile | 23 +- hydro/OrchestratorLayer/config.F90 | 8 +- hydro/Routing/CMakeLists.txt | 9 +- hydro/Routing/Diversions/CMakeLists.txt | 10 + hydro/Routing/Diversions/Makefile | 27 +++ .../Routing/Diversions/module_diversions.F90 | 188 +++++++++++++++ .../module_diversions_timeslice.F90 | 81 +++++++ hydro/Routing/Makefile | 7 +- hydro/Routing/module_channel_routing.F90 | 52 ++++- hydro/arc/Makefile.mpp | 20 +- hydro/arc/Makefile.seq | 36 --- hydro/arc/macros.mpp.cray_fortran | 11 +- hydro/arc/macros.mpp.gfort | 3 +- hydro/arc/macros.mpp.ifort | 1 + hydro/arc/macros.mpp.ifort.luna | 107 --------- hydro/arc/macros.mpp.ifort.summit_has | 79 ------- hydro/arc/macros.mpp.ifort.theia | 92 -------- hydro/arc/macros.mpp.linux | 23 +- hydro/arc/macros.seq.IBM.xlf90_r | 39 ---- hydro/arc/macros.seq.gfort | 43 ---- hydro/arc/macros.seq.ifort | 56 ----- hydro/arc/macros.seq.linux | 57 ----- hydro/arc/macros.theia.debug | 92 -------- hydro/arc/macros.yellowstone | 92 -------- hydro/arc/macros.yellowstone.debug | 92 -------- hydro/configure | 98 +++----- hydro/nudging/CMakeLists.txt | 4 +- hydro/nudging/io/CMakeLists.txt | 10 + hydro/nudging/{ => io}/module_nudging_io.F90 | 20 +- hydro/utils/CMakeLists.txt | 2 + hydro/utils/fortglob/CMakeLists.txt | 4 + hydro/utils/fortglob/Makefile | 33 +++ hydro/utils/fortglob/fortglob.F90 | 76 ++++++ hydro/utils/fortglob/libfortglob.c | 19 ++ hydro/utils/fortglob/libfortglob.h | 13 ++ hydro/wrf_hydro_config | 11 +- 41 files changed, 831 insertions(+), 938 deletions(-) create mode 100644 hydro/Routing/Diversions/CMakeLists.txt create mode 100644 hydro/Routing/Diversions/Makefile create mode 100644 hydro/Routing/Diversions/module_diversions.F90 create mode 100644 hydro/Routing/Diversions/module_diversions_timeslice.F90 delete mode 100644 hydro/arc/Makefile.seq delete mode 100644 hydro/arc/macros.mpp.ifort.luna delete mode 100644 hydro/arc/macros.mpp.ifort.summit_has delete mode 100644 hydro/arc/macros.mpp.ifort.theia delete mode 100644 hydro/arc/macros.seq.IBM.xlf90_r delete mode 100644 hydro/arc/macros.seq.gfort delete mode 100644 hydro/arc/macros.seq.ifort delete mode 100644 hydro/arc/macros.seq.linux delete mode 100644 hydro/arc/macros.theia.debug delete mode 100644 hydro/arc/macros.yellowstone delete mode 100644 hydro/arc/macros.yellowstone.debug create mode 100644 hydro/nudging/io/CMakeLists.txt rename hydro/nudging/{ => io}/module_nudging_io.F90 (98%) create mode 100644 hydro/utils/fortglob/CMakeLists.txt create mode 100644 hydro/utils/fortglob/Makefile create mode 100644 hydro/utils/fortglob/fortglob.F90 create mode 100644 hydro/utils/fortglob/libfortglob.c create mode 100644 hydro/utils/fortglob/libfortglob.h diff --git a/hydro/CMakeLists.txt b/hydro/CMakeLists.txt index 5cf8615149..2c566b6f64 100644 --- a/hydro/CMakeLists.txt +++ b/hydro/CMakeLists.txt @@ -1,12 +1,20 @@ -# additions that WRF-Hydro's top CMakeLists.txt handles -add_compile_options( "${PROJECT_COMPILE_OPTIONS}" ) -add_compile_definitions( "${PROJECT_COMPILE_DEFINITIONS}" ) -set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/hydro/mods) -add_definitions(-DMPP_LAND) -if (WRF_HYDRO_NUDGING STREQUAL "1") - add_definitions(-DWRF_HYDRO_NUDGING=1) +if(${PROJECT_NAME} STREQUAL "WRF") + # additions that WRF-Hydro's top CMakeLists.txt handles + add_compile_options( "${PROJECT_COMPILE_OPTIONS}" ) + add_compile_definitions( "${PROJECT_COMPILE_DEFINITIONS}" ) + set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/hydro/mods) + add_definitions(-DMPP_LAND) + if (WRF_HYDRO_NUDGING STREQUAL "1") + add_definitions(-DWRF_HYDRO_NUDGING=1) + endif() + if (OUTPUT_CHAN_CONN STREQUAL "1" ) + add_definitions(-DOUTPUT_CHAN_CONN) + # requires nudging io module + set(WRF_HYDRO_NUDGING_IO "1") + endif() endif() + # build the various sup-projects add_subdirectory("MPP") add_subdirectory("utils") @@ -16,10 +24,19 @@ add_subdirectory("Debug_Utilities") add_subdirectory("Routing/Overland") add_subdirectory("Routing/Subsurface") add_subdirectory("Routing/Reservoirs") +add_subdirectory("Routing/Diversions") add_subdirectory("Data_Rec") add_subdirectory("Routing") add_subdirectory("HYDRO_drv") -add_subdirectory("CPL/WRF_cpl") +if(${PROJECT_NAME} STREQUAL "WRF") + add_subdirectory("CPL/WRF_cpl") +endif() + +if (WRF_HYDRO_NUDGING_IO STREQUAL "1" OR + WRF_HYDRO_NUDGING STREQUAL "1") + add_subdirectory("nudging/io") + add_dependencies(hydro_routing hydro_nudging_io) +endif() if (WRF_HYDRO_NUDGING STREQUAL "1") add_subdirectory("nudging") @@ -27,6 +44,10 @@ if (WRF_HYDRO_NUDGING STREQUAL "1") add_dependencies(hydro_driver hydro_nudging) endif() +if (WRF_HYDRO_NUOPC STREQUAL "1") + add_subdirectory("CPL/NUOPC_cpl") +endif() + # add module dependencies add_dependencies(hydro_debug_utils hydro_mpp) add_dependencies(hydro_utils hydro_mpp) @@ -75,21 +96,164 @@ add_dependencies(hydro_data_rec hydro_routing_reservoirs ) -add_library(wrfhydro INTERFACE) -target_link_libraries(wrfhydro INTERFACE - hydro_utils - hydro_mpp - hydro_debug_utils - hydro_routing_overland - hydro_routing_subsurface - hydro_data_rec - hydro_routing - hydro_routing_reservoirs_levelpool - hydro_routing_reservoirs_hybrid - hydro_routing_reservoirs_rfc - hydro_routing_reservoirs - hydro_wrf_cpl - hydro_orchestrator - hydro_netcdf_layer - hydro_driver -) +if (HYDRO_LSM MATCHES "NoahMP") + message("-- Building NoahMP LSM") + add_subdirectory("Land_models/NoahMP") + + add_subdirectory("CPL/NoahMP_cpl") + add_dependencies(hydro_noahmp_cpl hydro_routing) + add_dependencies(hydro_noahmp_cpl hydro_mpp ) + add_dependencies(hydro_noahmp_cpl hydro_driver ) + + add_executable(wrfhydro + Land_models/NoahMP/IO_code/main_hrldas_driver.F + Land_models/NoahMP/IO_code/module_hrldas_netcdf_io.F + Land_models/NoahMP/IO_code/module_NoahMP_hrldas_driver.F + ) + + target_include_directories(wrfhydro BEFORE PUBLIC ${PROJECT_BINARY_DIR}/mods) + + target_link_libraries(wrfhydro + hydro_utils + hydro_mpp + hydro_debug_utils + hydro_routing_overland + hydro_routing_subsurface + hydro_data_rec + hydro_routing + hydro_routing_reservoirs_levelpool + hydro_routing_reservoirs_hybrid + hydro_routing_reservoirs_rfc + hydro_routing_reservoirs + hydro_driver + noahmp_util + noahmp_phys + noahmp_data + hydro_noahmp_cpl + ${NETCDF_LIBRARIES} + # hydro_routing_groundwater + # hydro_routing_groundwater_bucket + # hydro_routing_groundwater_nhd + # hydro_routing_groundwater_simple + ) + + if (WRF_HYDRO_NUDGING_IO STREQUAL "1") + target_link_libraries(wrfhydro hydro_nudging_io) + add_dependencies(wrfhydro hydro_nudging_io) + endif() + + if (WRF_HYDRO_NUDGING STREQUAL "1") + target_link_libraries(wrfhydro hydro_nudging) + target_link_libraries(wrfhydro hydro_routing_diversions) + add_dependencies(wrfhydro hydro_nudging) + add_dependencies(wrfhydro hydro_routing_diversions) + endif() + + # bash commands to copy namelists to the Run directory + set(BASH_CP_HRLDAS_NML "if [[ ! -f ${CMAKE_BINARY_DIR}/Run/namelist.hrldas ]]\; then cp ${PROJECT_SOURCE_DIR}/src/template/NoahMP/namelist.hrldas ${CMAKE_BINARY_DIR}/Run \; fi\;") + set(BASH_CP_HYDRO_NML "if [[ ! -f ${CMAKE_BINARY_DIR}/Run/hydro.namelist ]]\; then cp ${PROJECT_SOURCE_DIR}/src/template/HYDRO/hydro.namelist ${CMAKE_BINARY_DIR}/Run \; fi\;") + + add_custom_command(TARGET wrfhydro POST_BUILD + COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/tests/ctests/run_dir_makefile.mk ${CMAKE_BINARY_DIR}/Run/Makefile + # copy tables + COMMAND cp ${PROJECT_SOURCE_DIR}/src/template/HYDRO/CHANPARM.TBL ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/src/template/HYDRO/HYDRO.TBL ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/src/Land_models/NoahMP/run/*.TBL ${CMAKE_BINARY_DIR}/Run + # copy namelists + COMMAND bash -c "${BASH_CP_HRLDAS_NML}" + COMMAND bash -c "${BASH_CP_HYDRO_NML}" + # copy and setup executables + COMMAND rm -f ${CMAKE_BINARY_DIR}/Run/wrf_hydro + COMMAND rm -f ${CMAKE_BINARY_DIR}/Run/wrf_hydro_NoahMP + COMMAND cp ${PROJECT_BINARY_DIR}/src/wrfhydro ${CMAKE_BINARY_DIR}/Run/wrf_hydro + COMMAND ln -sf ${CMAKE_BINARY_DIR}/Run/wrf_hydro ${CMAKE_BINARY_DIR}/Run/wrf_hydro_NoahMP + COMMAND rm ${PROJECT_BINARY_DIR}/src/wrfhydro + ) + if(WRF_HYDRO_CREATE_EXE_SYMLINK) + add_custom_command(TARGET wrfhydro POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_BINARY_DIR}/Run/wrf_hydro ${CMAKE_BINARY_DIR}/Run/wrf_hydro.exe + ) + endif() + +elseif (HYDRO_LSM MATCHES "Noah") + message("-- Building Noah LSM") + add_subdirectory("Land_models/Noah") + add_subdirectory("CPL/Noah_cpl") + + add_dependencies(hydro_noah_cpl hydro_routing) + add_dependencies(hydro_noah_cpl hydro_mpp ) + add_dependencies(hydro_noah_cpl hydro_driver ) + + add_executable(wrfhydro + Land_models/Noah/IO_code/module_hrldas_netcdf_io.F + Land_models/Noah/IO_code/Noah_hrldas_driver.F + ) + + target_include_directories(wrfhydro BEFORE PUBLIC ${PROJECT_BINARY_DIR}/mods) + + target_link_libraries(wrfhydro + hydro_utils + hydro_mpp + hydro_debug_utils + hydro_routing_overland + hydro_routing_subsurface + hydro_data_rec + hydro_routing + hydro_driver + hydro_routing_reservoirs_levelpool + hydro_routing_reservoirs_hybrid + hydro_routing_reservoirs_rfc + hydro_routing_reservoirs + noah_util + noah + hydro_noah_cpl + ${NETCDF_LIBRARIES} + ${MPI_Fortran_LIBRARIES} + # hydro_routing_groundwater + # hydro_routing_groundwater_bucket + # hydro_routing_groundwater_nhd + # hydro_routing_groundwater_simple + ) + + if (WRF_HYDRO_NUDGING STREQUAL "1") + target_link_libraries(wrfhydro hydro_nudging) + add_dependencies(wrfhydro hydro_nudging) + endif() + + add_custom_command(TARGET wrfhydro POST_BUILD + COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Run + COMMAND rm -f ${CMAKE_BINARY_DIR}/Run/* + COMMAND cp ${PROJECT_BINARY_DIR}/src/wrfhydro ${CMAKE_BINARY_DIR}/Run/wrf_hydro_Noah + COMMAND cp ${PROJECT_SOURCE_DIR}/src/template/Noah/* ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/src/template/HYDRO/CHANPARM.TBL ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/src/template/HYDRO/hydro.namelist ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/src/template/HYDRO/HYDRO.TBL ${CMAKE_BINARY_DIR}/Run + COMMAND cp ${PROJECT_SOURCE_DIR}/src/Land_models/Noah/Run/*.TBL ${CMAKE_BINARY_DIR}/Run + COMMAND ln -sf ${CMAKE_BINARY_DIR}/Run/wrf_hydro_Noah ${CMAKE_BINARY_DIR}/Run/wrf_hydro + COMMAND ln -sf ${CMAKE_BINARY_DIR}/Run/wrf_hydro_Noah ${CMAKE_BINARY_DIR}/Run/wrf_hydro.exe + COMMAND rm ${PROJECT_BINARY_DIR}/src/wrfhydro + ) + +elseif(${PROJECT_NAME} STREQUAL "WRF") + add_library(wrfhydro INTERFACE) + target_link_libraries(wrfhydro INTERFACE + hydro_utils + hydro_mpp + hydro_debug_utils + hydro_routing_overland + hydro_routing_subsurface + hydro_data_rec + hydro_routing + hydro_routing_reservoirs_levelpool + hydro_routing_reservoirs_hybrid + hydro_routing_reservoirs_rfc + hydro_routing_reservoirs + hydro_wrf_cpl + hydro_orchestrator + hydro_netcdf_layer + hydro_driver + ) +else() + message("Unknown land surface model:" ${HYDRO_LSM} ) +endif() diff --git a/hydro/CPL/WRF_cpl/CMakeLists.txt b/hydro/CPL/WRF_cpl/CMakeLists.txt index c98d242ddc..78ff27a6d6 100644 --- a/hydro/CPL/WRF_cpl/CMakeLists.txt +++ b/hydro/CPL/WRF_cpl/CMakeLists.txt @@ -14,7 +14,7 @@ add_dependencies(hydro_wrf_cpl MPI::MPI_Fortran ) -target_link_libraries( hydro_wrf_cpl PRIVATE hydro_driver ) +target_link_libraries(hydro_wrf_cpl PRIVATE hydro_driver) target_include_directories(hydro_wrf_cpl PRIVATE diff --git a/hydro/Data_Rec/module_namelist.F90 b/hydro/Data_Rec/module_namelist.F90 index c72a4275d3..083aee4ece 100644 --- a/hydro/Data_Rec/module_namelist.F90 +++ b/hydro/Data_Rec/module_namelist.F90 @@ -33,6 +33,7 @@ subroutine read_rt_nlst(nlst) character(len=256) :: route_lake_f="" character(len=256) :: route_direction_f="" character(len=256) :: route_order_f="" + character(len=256) :: diversions_file="" logical :: reservoir_persistence_usgs logical :: reservoir_persistence_usace character(len=256) :: reservoir_parameter_file="" @@ -105,8 +106,8 @@ subroutine read_rt_nlst(nlst) RT_OPTION, CHANRTSWCRT, channel_option, & SUBRTSWCRT,OVRTSWCRT,AGGFACTRT, dtrt_ter,dtrt_ch,dxrt,& GwSpinCycles, GwPreCycles, GwSpinUp, GwPreDiag, GwPreDiagInterval, gwIhShift, & - GWBASESWCRT, gwChanCondSw, gwChanCondConstIn, gwChanCondConstOut , & - route_topo_f,route_chan_f,route_link_f, compound_channel, route_lake_f, & + GWBASESWCRT, gwChanCondSw, gwChanCondConstIn, gwChanCondConstOut, & + route_topo_f,route_chan_f,route_link_f, compound_channel, route_lake_f, diversions_file, & reservoir_persistence_usgs, reservoir_persistence_usace, reservoir_parameter_file, reservoir_usgs_timeslice_path, & reservoir_usace_timeslice_path, reservoir_observation_lookback_hours, reservoir_observation_update_time_interval_seconds, & reservoir_rfc_forecasts, reservoir_rfc_forecasts_time_series_path, reservoir_rfc_forecasts_lookback_hours, & @@ -248,6 +249,7 @@ subroutine read_rt_nlst(nlst) nlst%DEEPGWSPIN = DEEPGWSPIN nlst%SOLVEG_INITSWC = SOLVEG_INITSWC nlst%reservoir_obs_dir = "testDirectory" + nlst%diversions_file = diversions_file nlst%reservoir_persistence_usgs = reservoir_persistence_usgs nlst%reservoir_persistence_usace = reservoir_persistence_usace nlst%reservoir_parameter_file = reservoir_parameter_file diff --git a/hydro/Data_Rec/module_namelist_inc.F90 b/hydro/Data_Rec/module_namelist_inc.F90 index c34b9d768c..52922903c9 100644 --- a/hydro/Data_Rec/module_namelist_inc.F90 +++ b/hydro/Data_Rec/module_namelist_inc.F90 @@ -42,6 +42,7 @@ module module_namelist_inc character(len=256) :: route_chan_f="" character(len=256) :: route_link_f="" character(len=256) :: route_lake_f="" + character(len=256) :: diversions_file="" logical :: reservoir_persistence_usgs logical :: reservoir_persistence_usace character(len=256) :: reservoir_parameter_file="" diff --git a/hydro/HYDRO_drv/module_HYDRO_drv.F90 b/hydro/HYDRO_drv/module_HYDRO_drv.F90 index a5a6a37df3..0efbc46ef5 100644 --- a/hydro/HYDRO_drv/module_HYDRO_drv.F90 +++ b/hydro/HYDRO_drv/module_HYDRO_drv.F90 @@ -29,6 +29,7 @@ module module_HYDRO_drv #endif use module_hydro_stop, only: HYDRO_stop use module_UDMAP, only: get_basn_area_nhd + use module_channel_diversions, only: init_diversions use netcdf implicit none @@ -1583,6 +1584,11 @@ subroutine HYDRO_ini(ntime, did,ix0,jx0, vegtyp,soltyp) if(nlst(did)%CHANRTSWCRT .ne. 0) call init_stream_nudging #endif +!#ifdef WRF_HYDRO_DIVERSIONS +! TODO: should this check to make sure we have nudging on too? [RC] + call init_diversions(nlst(did)%diversions_file, nlst(did)%timeSlicePath) +!#endif + ! if (trim(nlst_rt(did)%restart_file) == "") then ! output at the initial time diff --git a/hydro/Makefile b/hydro/Makefile index 240e9d359d..f624055ffc 100644 --- a/hydro/Makefile +++ b/hydro/Makefile @@ -1,6 +1,7 @@ -# Makefile +# Makefile # -CMD = Run/wrf_hydro.exe +CMD = Run/wrf_hydro +.PHONY: $(CMD) all: $(CMD) @@ -8,7 +9,7 @@ $(CMD): @if [ ! -d "Run" ]; then \ (mkdir Run);\ fi - (rm -f Run/wrf_hydro.exe ) + (rm -f Run/wrf_hydro ) (make -f Makefile.comm BASIC) @if [ -d "LandModel_cpl" ]; then \ (cd LandModel_cpl; make) \ @@ -24,16 +25,16 @@ $(CMD): (cd LandModel; make ) \ fi -debug:: - @echo 'F90FLAGS := $$(DEBUGFLAGS) $$(F90FLAGS)' >> ./macros +debug:: + @echo 'F90FLAGS := $$(DEBUGFLAGS) $$(F90FLAGS)' >> ./macros @echo 'F90FLAGS := $$(DEBUGFLAGS) $$(F90FLAGS)' >> ./LandModel/user_build_options debug:: $(CMD) install: - -rm -f ./Run/wrf_hydro.exe; \ - mv LandModel/run/hrldas.exe ./Run/wrf_hydro.exe + -rm -f ./Run/wrf_hydro + mv LandModel/run/hrldas.exe ./Run/wrf_hydro test: - @echo "No libraries or utilities are built, skip testing." + @echo "No libraries or utilities are built, skip testing." clean: @if [ -d "LandModel_cpl" ]; then \ (cd LandModel_cpl; make clean) \ @@ -42,7 +43,7 @@ clean: @if [ -d "LandModel" ]; then \ (cd LandModel; make clean) \ fi - if [ $(WRF_HYDRO_RAPID) -eq 1 ]; then \ - (cd Rapid_routing; make -f makefile.cpl clean); \ + @if [ "$(WRF_HYDRO_RAPID)" = "1" ]; then \ + (cd Rapid_routing; make -f makefile.cpl clean); \ fi - (rm -f */*.mod */*.o lib/*.a Run/wrf_hydro.exe) + (rm -f */*.mod */*.o lib/*.a Run/wrf_hydro) diff --git a/hydro/OrchestratorLayer/config.F90 b/hydro/OrchestratorLayer/config.F90 index 6e6d772959..7b957aff9e 100644 --- a/hydro/OrchestratorLayer/config.F90 +++ b/hydro/OrchestratorLayer/config.F90 @@ -124,6 +124,7 @@ module config_base character(len=256) :: route_link_f="" character(len=256) :: route_lake_f="" integer :: lake_option + character(len=256) :: diversions_file="" logical :: reservoir_persistence_usgs logical :: reservoir_persistence_usace character(len=256) :: reservoir_parameter_file="" @@ -170,7 +171,7 @@ module config_base integer :: maxAgePairsBiasPersist logical :: invDistTimeWeightBias logical :: noConstInterfBias - character(len=256) :: timeSlicePath + character(len=256) :: timeSlicePath = "./nudgingTimeSliceObs/" integer :: nLastObs integer :: bucket_loss integer :: imperv_adj @@ -554,6 +555,7 @@ subroutine init_namelist_rt_field(did) integer :: channel_loss_option = 0 character(len=256) :: route_lake_f="" integer :: lake_option !0: lakes off 1: level pool 2: passthrough, 3: reservoir da + character(len=256) :: diversions_file="" logical :: reservoir_persistence_usgs logical :: reservoir_persistence_usace character(len=256) :: reservoir_parameter_file="" @@ -628,7 +630,7 @@ subroutine init_namelist_rt_field(did) SUBRTSWCRT,OVRTSWCRT,AGGFACTRT, dtrt_ter,dtrt_ch,dxrt,& GwSpinCycles, GwPreCycles, GwSpinUp, GwPreDiag, GwPreDiagInterval, gwIhShift, & GWBASESWCRT, gwChanCondSw, gwChanCondConstIn, gwChanCondConstOut , & - route_topo_f,route_chan_f,route_link_f, compound_channel, channel_loss_option, lake_option, route_lake_f, & + route_topo_f,route_chan_f,route_link_f, compound_channel, channel_loss_option, lake_option, route_lake_f, diversions_file, & route_direction_f,route_order_f,gwbasmskfil, & geo_finegrid_flnm, gwstrmfil,GW_RESTART,RSTRT_SWC,TERADJ_SOLAR, sys_cpl, & order_to_write , rst_typ, rst_bi_in, rst_bi_out, gwsoilcpl, & @@ -880,6 +882,8 @@ subroutine init_namelist_rt_field(did) nlst(did)%route_link_f = route_link_f nlst(did)%route_lake_f = route_lake_f + nlst(did)%diversions_file = diversions_file + nlst(did)%reservoir_persistence_usgs = reservoir_persistence_usgs nlst(did)%reservoir_persistence_usace = reservoir_persistence_usace nlst(did)%reservoir_parameter_file = reservoir_parameter_file diff --git a/hydro/Routing/CMakeLists.txt b/hydro/Routing/CMakeLists.txt index 8c40440b07..748b941e8d 100644 --- a/hydro/Routing/CMakeLists.txt +++ b/hydro/Routing/CMakeLists.txt @@ -20,7 +20,6 @@ add_library(hydro_routing STATIC target_link_libraries(hydro_routing PRIVATE MPI::MPI_Fortran - netCDF::netcdff hydro_mpp hydro_utils hydro_orchestrator @@ -31,4 +30,12 @@ target_link_libraries(hydro_routing hydro_routing_reservoirs_hybrid hydro_data_rec hydro_routing_reservoirs_rfc + hydro_routing_diversions ) + +if (WRF_HYDRO_NUDGING_IO STREQUAL "1") + target_link_libraries(hydro_routing + PRIVATE + hydro_nudging_io + ) +endif() diff --git a/hydro/Routing/Diversions/CMakeLists.txt b/hydro/Routing/Diversions/CMakeLists.txt new file mode 100644 index 0000000000..c2b688564b --- /dev/null +++ b/hydro/Routing/Diversions/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(hydro_routing_diversions STATIC + module_diversions.F90 + module_diversions_timeslice.F90 +) + +add_dependencies(hydro_routing_diversions hydro_orchestrator) +add_dependencies(hydro_routing_diversions fortglob) + +target_link_libraries(hydro_routing_diversions PUBLIC hydro_orchestrator) +target_link_libraries(hydro_routing_diversions PUBLIC fortglob) diff --git a/hydro/Routing/Diversions/Makefile b/hydro/Routing/Diversions/Makefile new file mode 100644 index 0000000000..c7200a472b --- /dev/null +++ b/hydro/Routing/Diversions/Makefile @@ -0,0 +1,27 @@ +# Makefile +# +include ../../macros + +OBJS = \ + module_diversions_timeslice.o \ + module_diversions.o + +all: $(OBJS) + +%.o: %.F90 + @echo "Routing Diversions Makefile:" + $(COMPILER90) $(CPPINVOKE) $(CPPFLAGS) -o $(@) $(F90FLAGS) $(LDFLAGS) -I"../../mod" -I$(NETCDFINC) $(*).F90 + @echo "" + ar -r ../../lib/libHYDRO.a $(@) + cp *.mod ../../mod + + +fortglob_dir: + make -C ../../utils/fortglob + +module_diversions_timeslice.o: fortglob_dir + +module_diversions.o: module_diversions_timeslice.o + +clean: + rm -f *.o *.mod *.stb *~ diff --git a/hydro/Routing/Diversions/module_diversions.F90 b/hydro/Routing/Diversions/module_diversions.F90 new file mode 100644 index 0000000000..159731be2d --- /dev/null +++ b/hydro/Routing/Diversions/module_diversions.F90 @@ -0,0 +1,188 @@ +module module_channel_diversions + use netcdf + use iso_fortran_env, only: int8, int16, int64 + use ieee_arithmetic, only: ieee_is_nan + + use module_diversions_timeslice, only: get_flow_for_gage, init_timeslices + use module_hydro_stop, only: hydro_stop + + implicit none + + type diversion_t + character(len=128) :: name + + character(len=16) :: da_src, da_dest + integer(kind=int8) :: type_div, type_src, type_dest + integer(kind=int64) :: id_src, id_dest, src_index, dest_index + real :: capacity, fraction + integer(kind=int16) :: lookback + + real :: persisted_flow_src, persisted_flow_dest + end type + + logical :: diversions_active = .false. + integer :: ndivs = 0 + + type(diversion_t), allocatable :: diversions(:) + + character(*), parameter :: free = '(*(g0,1x))' + +contains + subroutine init_diversions(diversions_file, timeslice_path) + character(*), intent(in) :: diversions_file + character(*), intent(in) :: timeslice_path + + integer :: g, i, ierr = 0 + character(len=20) :: istr + character(len=256) :: char_tmp + + integer :: ncid, dimid + integer :: name_vid, type_div_vid, type_src_vid, type_dest_vid, da_src_vid, da_dest_vid + integer :: id_src_vid, id_dest_vid, capacity_vid, fraction_vid, lookback_vid + + if (len_trim(diversions_file) > 0) then + print *, "Loading diversions data from " // trim(diversions_file) + ierr = nf90_open(trim(diversions_file), NF90_NOWRITE, ncid) + if (ierr /= 0) call hydro_stop("Could not open diversions file: " // trim(diversions_file)) + ierr = nf90_inq_dimid(ncid, "diversion", dimid) + if (ierr /= 0) call hydro_stop("Error reading diversions file: " // trim(diversions_file)) + ierr = nf90_inquire_dimension(ncid, dimid, len=ndivs) + if (ierr /= 0) call hydro_stop("Error reading diversions file: " // trim(diversions_file)) + + write (istr, *) ndivs + print *, "Diversions file has " // trim(adjustl(istr)) // " diversions" + + ! get fields + ierr = 0 + ierr = ierr + nf90_inq_varid(ncid, "Diversion_Name", name_vid) + ierr = ierr + nf90_inq_varid(ncid, "DivType", type_div_vid) + ierr = ierr + nf90_inq_varid(ncid, "FromType", type_src_vid) + ierr = ierr + nf90_inq_varid(ncid, "ToType", type_dest_vid) + ierr = ierr + nf90_inq_varid(ncid, "DA_Src", da_src_vid) + ierr = ierr + nf90_inq_varid(ncid, "DA_Dest", da_dest_vid) + ierr = ierr + nf90_inq_varid(ncid, "DivFrom", id_src_vid) + ierr = ierr + nf90_inq_varid(ncid, "DivTo", id_dest_vid) + ierr = ierr + nf90_inq_varid(ncid, "DivCap", capacity_vid) + ierr = ierr + nf90_inq_varid(ncid, "DivFrac", fraction_vid) + ierr = ierr + nf90_inq_varid(ncid, "Lookback", lookback_vid) + + if (ierr /= 0) then + print free, "WARNING: error occurred accessing diversion file variables, will disable diversions" + return + end if + + if (ndivs > 0) then + ! Read the timeslice data + ierr = init_timeslices(timeslice_path) + if (ierr /= 0) then + print free, "WARNING: No timeslice files available when initializing diversions, will disable diversions" + return + end if + + diversions_active = .true. + + allocate(diversions(ndivs)) + do i = 1, ndivs + associate (div => diversions(i)) + div = diversion_t('', '', '', -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + + ierr = 0 + !ierr = ierr + nf_get_var1(ncid, name_vid, i, div%name) !! can't read string with Fortran :-( + + ierr = ierr + nf90_get_var(ncid, da_src_vid, div%da_src, start=(/i/), count=(/15/)) + div%persisted_flow_src = get_flow_for_gage(div%da_src) + ierr = ierr + nf90_get_var(ncid, da_dest_vid, div%da_dest, start=(/i/), count=(/15/)) + div%persisted_flow_dest = get_flow_for_gage(div%da_dest) + + ierr = ierr + nf90_get_var(ncid, type_div_vid, div%type_div, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, type_src_vid, div%type_src, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, type_dest_vid, div%type_dest, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, id_src_vid, div%id_src, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, id_dest_vid, div%id_dest, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, capacity_vid, div%capacity, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, fraction_vid, div%fraction, start=(/i/)) + ierr = ierr + nf90_get_var(ncid, lookback_vid, div%lookback, start=(/i/)) + + if (ierr /= 0) then + print free, "WARNING: error occurred reading diversion variables from diversion file, will disable diversions" + diversions_active = .false. + return + end if + end associate + end do + + end if + end if + + end subroutine + + subroutine calculate_diversion(src_link_in, qlink_src_in, diversion_quantity_out, diversion_quantity_in) + integer(kind=int64), intent(in) :: src_link_in + ! integer(kind=int64), intent(out) :: dst_out + real, intent(in) :: qlink_src_in + real, intent(out) :: diversion_quantity_out, diversion_quantity_in + + integer :: i + + diversion_quantity_out = 0 + diversion_quantity_in = 0 + + ! bail if we're inactive + if (.not. diversions_active) return + + ! link to gage + ! look to see what type of diversion it is + ! call into sub-procedure to handle type=1, type=2, type=3, etc + + do i = 1, ndivs + if (src_link_in == diversions(i)%id_src) then + if (diversions(i)%type_div /= 3) then + print free, "!!! UNSUPPORTED DIVERSION TYPE (", diversions(i)%type_div, "), skipping" + else + call gage_assisted_diversion(src_link_in, diversions(i), qlink_src_in, diversion_quantity_out) + ! dst_out = diversions(i)%id_dest + end if + end if + + if (src_link_in == diversions(i)%id_dest) then + if (diversions(i)%type_div /= 3) then + print free, "!!! UNSUPPORTED DIVERSION TYPE (", diversions(i)%type_div, "), skipping" + else + if (.not. ieee_is_nan(diversions(i)%persisted_flow_dest)) & + diversion_quantity_in = diversions(i)%persisted_flow_dest + end if + end if + end do + + ! subtract dst_out from source gage + + end subroutine + + subroutine gage_assisted_diversion(src_link, diversion, qlink_src, div_gage_flow) + integer(kind=int64), intent(in) :: src_link + type(diversion_t), intent(in) :: diversion + real, intent(in) :: qlink_src + real, intent(out) :: div_gage_flow + + real :: fraction + + ! This is the so-called "Type 3" diversion. We take the observed flow from div_gage, + ! and subtract it from the upstream qlink_src, if it's a valid flow (not-NaN). + ! + ! If it's not a valid flow, we try to use the Fraction property of the diversion, + ! and if -that's- not available, we just leave the flow untouched. + + div_gage_flow = diversion%persisted_flow_dest + if (ieee_is_nan(div_gage_flow)) then + fraction = diversion%fraction + if (fraction == -1) then + print free, "WARNING: No fractional diversion value specified for diversion at gage '" // trim(adjustl(diversion%da_dest)) // "', skipping" + fraction = 0 + else + print free, "INFO: No gage discharge available for diversion '" // trim(adjustl(diversion%da_dest)) // "', using fixed fractional diversion of", fraction + end if + div_gage_flow = qlink_src * fraction + end if + end subroutine + +end module diff --git a/hydro/Routing/Diversions/module_diversions_timeslice.F90 b/hydro/Routing/Diversions/module_diversions_timeslice.F90 new file mode 100644 index 0000000000..4cb59df682 --- /dev/null +++ b/hydro/Routing/Diversions/module_diversions_timeslice.F90 @@ -0,0 +1,81 @@ +module module_diversions_timeslice + use fortglob, only: glob_t, globfiles + use module_hydro_stop, only: hydro_stop + + use netcdf + use ieee_arithmetic, only: ieee_value, ieee_quiet_nan, ieee_is_nan + implicit none + + integer, parameter :: PATH_MAX = 4096 + type(glob_t) :: timeslice_files + + character(*), parameter :: free = '(*(g0,1x))' + + contains + + integer function init_timeslices(timeslice_path) result(ierr) + character(*), intent(in) :: timeslice_path + character(len=PATH_MAX) :: tslice_glob + + ierr = 0 + tslice_glob = trim(adjustl(timeslice_path)) // '/' // "*.15min.usgsTimeSlice.ncdf" + timeslice_files = globfiles(tslice_glob) + + if (timeslice_files%nfiles == 0) ierr = 1 + end function + + real function get_flow_for_gage(gage) result(flow) + character(len=15), intent(in) :: gage + + integer :: i, ierr=0, ncid, dimid, varid, num_stns, found(1) + real :: discharge(1) + character(len=15), allocatable :: gage_ids(:) + + flow = ieee_value(flow, ieee_quiet_nan) + + if (gage(1:4) == 'None') then + return + end if + + ! start looking at files, going backward from most recent + do i = timeslice_files%nfiles, 1, -1 + ierr = nf90_open(trim(timeslice_files%filenames(i)), NF90_NOWRITE, ncid) + + ! look for gage + ierr = ierr + nf90_inq_dimid(ncid, 'stationIdInd', dimid) + ierr = ierr + nf90_inquire_dimension(ncid, dimid, len=num_stns) + + allocate(gage_ids(num_stns)) + ierr = ierr + nf90_inq_varid(ncid, 'stationId', varid) + ierr = ierr + nf90_get_var(ncid, varid, gage_ids) + + if (ierr /= 0) call hydro_stop("Error occurred reading gage data from " // trim(timeslice_files%filenames(i))) + + found = findloc(gage_ids, gage) + if (found(1) /= 0) then +#ifdef HYDRO_D + print free, "DEBUG: Reading diversion discharge for gage " // trim(adjustl(gage)) // " from " // trim(timeslice_files%filenames(i)) +#endif + ierr = ierr + nf90_inq_varid(ncid, 'discharge', varid) + ierr = ierr + nf90_get_var(ncid, varid, discharge, start=found, count=(/1/)) + if (ierr /= 0) call hydro_stop("Error occurred reading gage data from " // trim(timeslice_files%filenames(i))) + + if (discharge(1) >= 0) then + flow = discharge(1) + deallocate(gage_ids) + return +#ifdef HYDRO_D + else + print free, "DEBUG: Diversion discharge value invalid, continuing search if able" +#endif + end if + end if + + deallocate(gage_ids) + ierr = nf90_close(ncid) + end do + + print free, "WARNING: Valid gage discharge not found in any timeslice file, falling back to fractional diversion" + end function + +end module \ No newline at end of file diff --git a/hydro/Routing/Makefile b/hydro/Routing/Makefile index 65d6ca4575..fbcb946cba 100644 --- a/hydro/Routing/Makefile +++ b/hydro/Routing/Makefile @@ -83,6 +83,7 @@ module_RT.o: module_GW_baseflow.o \ module_HYDRO_io.o \ module_noah_chan_param_init_rt.o \ module_UDMAP.o \ + module_channel_routing.o \ ../Data_Rec/module_namelist.o \ ../Data_Rec/module_RT_data.o \ ../Data_Rec/module_gw_gw2d_data.o @@ -102,9 +103,11 @@ endif module_UDMAP.o: ../Data_Rec/module_namelist.o ../Data_Rec/module_RT_data.o ifneq ($(WRF_HYDRO_NUDGING),-DWRF_HYDRO_NUDGING) -module_channel_routing.o: module_UDMAP.o +module_channel_routing.o: module_UDMAP.o \ + Diversions/module_diversions.o else -module_channel_routing.o: module_UDMAP.o\ +module_channel_routing.o: module_UDMAP.o \ + Diversions/module_diversions.o \ ../nudging/module_date_utils_nudging.o \ ../nudging/module_nudging_utils.o \ ../nudging/module_stream_nudging.o diff --git a/hydro/Routing/module_channel_routing.F90 b/hydro/Routing/module_channel_routing.F90 index c9d64962a6..cb4b79549d 100644 --- a/hydro/Routing/module_channel_routing.F90 +++ b/hydro/Routing/module_channel_routing.F90 @@ -509,10 +509,10 @@ subroutine SUBMUSKINGCUNGE( & !comment out to prevent excessive file sizes when running model !print*, "qloss,dx,WP,WPk,depth,ChannK,qdc,ql,dt,D", qloss,dx,WP,WPk,depth,ChannK,qdc,ql,dt,D if((qloss*dt)/D > ((ql*dt)/D - C4)) then - qloss = ql - C4*(D/dt) - if (qloss < 0) then - print*, 'WARNING CHANNEL LOSS IS NEGATIVE',qloss - endif + qloss = ql - C4*(D/dt) + if ((qloss < 0) .and. (ChannK /= 0)) then + print*, 'WARNING CHANNEL LOSS IS NEGATIVE',qloss + endif endif ! ---------------------------------------------------------------- @@ -876,7 +876,7 @@ Subroutine drive_CHANNEL(did, latval,lonval,KT, IXRT,JXRT, SUBRTSWCRT, & ! endif do k = 1, NLINKSL - if(TYPEL(k) .ne. 2) then + if(TYPEL(k) .ne. 1) then QLINK(k,2) = tmpQLINK(k,2) endif QLINK(k,1) = QLINK(k,2) !assing link flow of current to be previous for next time step @@ -1645,7 +1645,8 @@ subroutine drive_CHANNEL_RSL(did, UDMP_OPT,KT, IXRT,JXRT, & nudgeWAdvance, & nudge_apply_upstream_muskingumCunge #endif - + use module_channel_diversions, only: calculate_diversion + use ieee_arithmetic, only: ieee_is_nan implicit none @@ -1756,6 +1757,10 @@ subroutine drive_CHANNEL_RSL(did, UDMP_OPT,KT, IXRT,JXRT, & real, allocatable,dimension(:) :: tmpAssimilatedValue character(len=256), allocatable,dimension(:) :: tmpAssimilatedSourceFile + ! diversions + real :: div_src, div_dst + character(*), parameter :: free = '(*(g0,1x))' + #ifdef MPP_LAND if(my_id .eq. io_id) then #endif @@ -2005,6 +2010,41 @@ subroutine drive_CHANNEL_RSL(did, UDMP_OPT,KT, IXRT,JXRT, & ! QLateral(k), DTRT_CH, So(k), CHANLEN(k), & ! MannN(k), ChSSlp(k), Bw(k), Tw(k) ) + ! HANDLE DIVERSIONS + + call calculate_diversion(LINKID(k), Quc, div_src, div_dst) + + if (div_src /= 0) then + ! remove from upstream +#ifdef HYDRO_D + print free, "DEBUG: diverting", div_src, "of", Quc, "from link id =", LINKID(k) !, "on processor", my_id + if (div_src > Quc) & + print free, "DEBUG WARNING: diverted flow (", div_src, ") exceeds total flow, zeroing." +#endif + Quc = max(0.0, Quc - div_src) + Qup = max(0.0, Qup - div_src) + end if + + if (div_dst /= 0) then + ! apply observed value to downstream +#ifdef HYDRO_D + print free, "DEBUG: diverting", div_dst, "to link id =", LINKID(k) !, "on processor", my_id +#endif + Qup = div_dst + Quc = div_dst + tmpQLINK(k,2) = div_dst + + ! reset any NaNs that got through + if (ieee_is_nan(div_dst)) then + ! fallback to zero if div_dst is NaN + if (ieee_is_nan(QLINK(k,1))) QLINK(k,1) = 0.0 + if (ieee_is_nan(QLINK(k,2))) QLINK(k,2) = 0.0 + else + if (ieee_is_nan(QLINK(k,1))) QLINK(k,1) = tmpQLINK(k,2) + if (ieee_is_nan(QLINK(k,2))) QLINK(k,2) = tmpQLINK(k,2) + end if + end if + #ifdef WRF_HYDRO_NUDGING call nudge_apply_upstream_muskingumCunge( Qup, Quc, nudge(k), k ) #endif diff --git a/hydro/arc/Makefile.mpp b/hydro/arc/Makefile.mpp index 665961ede5..f93b78774a 100644 --- a/hydro/arc/Makefile.mpp +++ b/hydro/arc/Makefile.mpp @@ -1,4 +1,4 @@ -# Makefile +# Makefile all: (make -f Makefile.comm BASIC) @@ -6,8 +6,10 @@ all: BASIC: make -C MPP make -C IO + make -C utils/fortglob make -C utils make -C OrchestratorLayer + make -C Routing/Diversions make -C Routing/Overland make -C Routing/Subsurface make -C Routing/Reservoirs @@ -17,15 +19,17 @@ BASIC: make -C HYDRO_drv clean: - (cd IO; make -f Makefile clean) - (cd OrchestratorLayer; make -f Makefile clean) - (cd utils ; make -f Makefile clean) + make -C IO clean + make -C OrchestratorLayer clean + make -C utils clean + make -C utils/fortglob clean + make -C Routing/Diversions clean make -C Routing/Overland clean make -C Routing/Subsurface clean make -C Routing/Reservoirs clean - (cd Data_Rec; make -f Makefile clean) - (cd HYDRO_drv; make -f Makefile clean) - (cd MPP; make -f Makefile clean) + make -C Data_Rec clean + make -C HYDRO_drv clean + make -C MPP clean make -C Debug_Utilities/ clean - (cd Routing; make -f Makefile clean) + make -C Routing clean (rm -f lib/*.a */*.mod */*.o CPL/*/*.o CPL/*/*.mod) diff --git a/hydro/arc/Makefile.seq b/hydro/arc/Makefile.seq deleted file mode 100644 index 386935ce9f..0000000000 --- a/hydro/arc/Makefile.seq +++ /dev/null @@ -1,36 +0,0 @@ -# Makefile - -all: - (make -f Makefile BASIC) - -BASIC: - (cd Data_Rec ; make -f Makefile) - (cd Routing; make -f Makefile) - ifeq ($(WRF_HYDRO_NUDGING),-DWRF_HYDRO_NUDGING) - (cd nudging; make -f Makefile) - endif - (cd HYDRO_drv; make -f Makefile) - -LIS: - (make -f Makefile BASIC) - (cd LIS_cpl ; make -f Makefile) - -CLM: - (make -f Makefile BASIC) - (cd CLM_cpl ; make -f Makefile) - -WRF: - (make -f Makefile BASIC) - (cd WRF_cpl ; make -f Makefile) - -HYDRO: - (make -f Makefile BASIC) - -clean: - (cd Data_Rec; make -f Makefile clean) - (cd HYDRO_drv; make -f Makefile clean) - ifeq ($(WRF_HYDRO_NUDGING),-DWRF_HYDRO_NUDGING) - (cd nudging; make -f Makefile clean) - endif - (cd Routing; make -f Makefile clean) - (rm -f lib/*.a */*.mod CPL/*/*.o CPL/*/*.mod) diff --git a/hydro/arc/macros.mpp.cray_fortran b/hydro/arc/macros.mpp.cray_fortran index a222ca8ca6..315d3b8971 100644 --- a/hydro/arc/macros.mpp.cray_fortran +++ b/hydro/arc/macros.mpp.cray_fortran @@ -3,7 +3,7 @@ ifeq ($(SPATIAL_SOIL),1) SPATIAL_SOIL = -DSPATIAL_SOIL else -SPATIAL_SOIL = +SPATIAL_SOIL = endif ifeq ($(HYDRO_REALTIME),1) @@ -32,19 +32,19 @@ endif ifeq ($(WRF_HYDRO_NUDGING),1) WRF_HYDRO_NUDGING = -DWRF_HYDRO_NUDGING else -WRF_HYDRO_NUDGING = +WRF_HYDRO_NUDGING = endif ifeq ($(OUTPUT_CHAN_CONN),1) OUTPUT_CHAN_CONN = -DOUTPUT_CHAN_CONN else -OUTPUT_CHAN_CONN = +OUTPUT_CHAN_CONN = endif ifeq ($(PRECIP_DOUBLE),1) PRECIP_DOUBLE = -DPRECIP_DOUBLE else -PRECIP_DOUBLE = +PRECIP_DOUBLE = endif ifeq ($(NWM_META),1) @@ -61,6 +61,7 @@ endif RMD = rm -f COMPILER90 = ftn +COMPILERCC = cc FORMAT_FREE = -f free BYTESWAPIO = -h byteswapio F90FLAGS = -O2 -c -ef -h alias=none -h fp1 $(FORMAT_FREE) $(BYTESWAPIO) @@ -69,6 +70,6 @@ MODFLAG = -I./ -I ../../MPP -I ../MPP -I ../mod LDFLAGS = CPPINVOKE = -eT CPPFLAGS = -DMPP_LAND -I ../Data_Rec $(HYDRO_D) $(SPATIAL_SOIL) $(NWM_META) $(WRF_HYDRO_NUDGING) $(OUTPUT_CHAN_CONN) $(PRECIP_DOUBLE) $(NCEP_WCOSS) -LIBS = +LIBS = NETCDFINC = $(NETCDF_INC) NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.mpp.gfort b/hydro/arc/macros.mpp.gfort index 5f22389e02..ac8c56ff84 100644 --- a/hydro/arc/macros.mpp.gfort +++ b/hydro/arc/macros.mpp.gfort @@ -55,7 +55,8 @@ endif RMD = rm -f -COMPILER90 = mpif90 +COMPILER90 = mpif90 +COMPILERCC = mpicc F90FLAGS = -w -c -O2 -ffree-form -ffree-line-length-none -fconvert=big-endian -frecord-marker=4 -std=legacy DEBUGFLAGS = -DHYDRO_D -g -Wall -Wextra -Warray-temporaries -Wconversion -fimplicit-none -fbacktrace -ffree-line-length-0 -fcheck=all -ffpe-trap=invalid,zero,overflow,underflow -finit-real=nan MODFLAG = -I"./" -I"../../MPP" -I"../MPP" -I"../mod" diff --git a/hydro/arc/macros.mpp.ifort b/hydro/arc/macros.mpp.ifort index eb4c94b322..12e74cf49b 100644 --- a/hydro/arc/macros.mpp.ifort +++ b/hydro/arc/macros.mpp.ifort @@ -61,6 +61,7 @@ endif RMD = rm -f COMPILER90 = mpif90 +COMPILERCC = mpicc FORMAT_FREE = -FR BYTESWAPIO = -convert big_endian F90FLAGS = -O2 -g -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) diff --git a/hydro/arc/macros.mpp.ifort.luna b/hydro/arc/macros.mpp.ifort.luna deleted file mode 100644 index 39ac0d6362..0000000000 --- a/hydro/arc/macros.mpp.ifort.luna +++ /dev/null @@ -1,107 +0,0 @@ -## If you have multiple mpi biulds on a single machine -## this example may be relevant to you. -## Ex: The hydro-c1 machine has mpi and netcdf built against portland -## fortran in the PATH. However mpi and netcd built against intel -## fortran is also available. Here's how I build WRF HYDRO against -## intel -## Below, in this file, I make the changes: -## COMPILER90 = $(ifortCompiler90) -## LDFLAGS = $(ifortLdFlags) -## NETCDFINC = $(ifortNetcdfInc) -## NETCDFLIB = -L$(ifortNetcdfLib) -lnetcdff -lnetcdf -## In my ~/.bashrc I have -## ## WRF HYDRO -## export NETCDF=/opt/netcdf -## export WRF_HYDRO=1 -## export HYDRO_D=1 -## ### manage ifort on hydro -## export ifortNetcdfLib="/opt/netcdf-4.3.0+ifort-12.1/lib/" -## export ifortNetcdfInc="/opt/netcdf-4.3.0+ifort-12.1/include/" -## # RPATH for ifort (pgi is already default so no need) -## ifortMpiLib="/opt/openmpi-1.10.0-intel/lib/" -## export ifortLdFlags="-Wl,-rpath,${ifortNetcdfLib}:${ifortMpiLib} -L${ifortNetcdfLib} -L${ifortMpiLib}" -## export ifortCompiler90='/opt/openmpi-1.10.0-intel/bin/mpif90' -## # Aliases for invoking ifort -## alias impirun='/opt/openmpi-1.10.0-intel/bin/mpirun' -## alias iman='man -M/opt/openmpi+intel/man' -## # Bonus: Check your wrf hydro environment - up you to maintain to your needs. -## alias henv='printenv | egrep -i "(HYDRO|NUDG|PRECIP|CHAN_CONN|^NETCDF|^LDFLAGS|^ifort)" | egrep -v PWD' - -.IGNORE: - -ifeq ($(SPATIAL_SOIL),1) -SPATIAL_SOIL = -DSPATIAL_SOIL -else -SPATIAL_SOIL = -endif - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifeq ($(WRF_HYDRO_NUDGING),1) -WRF_HYDRO_NUDGING = -DWRF_HYDRO_NUDGING -else -WRF_HYDRO_NUDGING = -endif - -ifeq ($(OUTPUT_CHAN_CONN),1) -OUTPUT_CHAN_CONN = -DOUTPUT_CHAN_CONN -else -OUTPUT_CHAN_CONN = -endif - -ifeq ($(PRECIP_DOUBLE),1) -PRECIP_DOUBLE = -DPRECIP_DOUBLE -else -PRECIP_DOUBLE = -endif - -ifeq ($(NCEP_WCOSS),1) -NCEP_WCOSS = -DNCEP_WCOSS -else -NCEP_WCOSS = -endif - -ifeq ($(NWM_META),1) -NWM_META = -DNWM_META -else -NWM_META = -endif - -RMD = rm -f -COMPILER90 = ftn -FORMAT_FREE = -FR -BYTESWAPIO = -convert big_endian -F90FLAGS = -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) -DEBUGFLAGS = -DHYDRO_D -g -traceback -debug all -check all -MODFLAG = -I./ -I ../../MPP -I ../MPP -I ../mod -# -# Used for DMAPP -# module load dmapp/7.0.1-1.0502.11080.8.76.ari -#LDFLAGS = $(HDF5_LDFLAGS) -Wl,--whole-archive,-ldmapp,--no-whole-archive -LDFLAGS = $(HDF5_LDFLAGS) -CPPINVOKE = -fpp -CPPFLAGS = -DMPP_LAND -I ../Data_Rec $(HYDRO_D) $(SPATIAL_SOIL) $(NWM_META) $(WRF_HYDRO_NUDGING) $(OUTPUT_CHAN_CONN) $(PRECIP_DOUBLE) $(NCEP_WCOSS) -LIBS =$(Z_LIB) -NETCDFINC = $(NETCDF_INC) -NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.mpp.ifort.summit_has b/hydro/arc/macros.mpp.ifort.summit_has deleted file mode 100644 index f11747332a..0000000000 --- a/hydro/arc/macros.mpp.ifort.summit_has +++ /dev/null @@ -1,79 +0,0 @@ -.IGNORE: - -ifeq ($(SPATIAL_SOIL),1) -SPATIAL_SOIL = -DSPATIAL_SOIL -else -SPATIAL_SOIL = -endif - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - -ifeq ($(WRFIO_NCD_LARGE_FILE_SUPPORT),1) -WRFIO_NCD_LARGE_FILE_SUPPORT = -DWRFIO_NCD_LARGE_FILE_SUPPORT -else -WRFIO_NCD_LARGE_FILE_SUPPORT = -endif - -ifeq ($(WRF_HYDRO_NUDGING),1) -WRF_HYDRO_NUDGING = -DWRF_HYDRO_NUDGING -else -WRF_HYDRO_NUDGING = -endif - -ifeq ($(OUTPUT_CHAN_CONN),1) -OUTPUT_CHAN_CONN = -DOUTPUT_CHAN_CONN -else -OUTPUT_CHAN_CONN = -endif - -ifeq ($(PRECIP_DOUBLE),1) -PRECIP_DOUBLE = -DPRECIP_DOUBLE -else -PRECIP_DOUBLE = -endif - -ifeq ($(NCEP_WCOSS),1) -NCEP_WCOSS = -DNCEP_WCOSS -else -NCEP_WCOSS = -endif - -ifeq ($(NWM_META),1) -NWM_META = -DNWM_META -else -NWM_META = -endif - -RMD = rm -f -COMPILER90 = mpiifort -FORMAT_FREE = -FR -BYTESWAPIO = -convert big_endian -F90FLAGS = -O2 -g -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) -DEBUGFLAGS = -DHYDRO_D -g -traceback -debug all -check all -MODFLAG = -I./ -I ../../MPP -I ../MPP -I ../mod -LDFLAGS = -CPPINVOKE = -fpp -CPPFLAGS = -DMPP_LAND -I ../Data_Rec $(HYDRO_D) $(SPATIAL_SOIL) $(WRFIO_NCD_LARGE_FILE_SUPPORT) $(NWM_META) $(WRF_HYDRO_NUDGING) $(OUTPUT_CHAN_CONN) $(PRECIP_DOUBLE) $(NCEP_WCOSS) -LIBS = -NETCDFINC = $(NETCDF_INC) -NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.mpp.ifort.theia b/hydro/arc/macros.mpp.ifort.theia deleted file mode 100644 index 62e61dc176..0000000000 --- a/hydro/arc/macros.mpp.ifort.theia +++ /dev/null @@ -1,92 +0,0 @@ -.IGNORE: - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifneq ($(origin ESMFMKFILE), environment) -$(error Environment variable ESMFMKFILE was not set.) -endif -include $(ESMFMKFILE) - -RMD = rm -f -COMPILER90 = $(ESMF_F90COMPILER) -FORMAT_FREE = -FR -BYTESWAPIO = -convert big_endian -F90FLAGS = -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) -# -w Disables all warning messages -# -c Prevents linking. -# -g Produces symbolic debug information in the object -# file. -# -ftz Flushes denormal results to zero when the application -# is in the gradual underflow mode. -# -align all Tells the compiler to add padding bytes whenever -# possible to obtain the natural alignment of data -# items in common blocks, derived types, and record -# structures. -# -fno-alias Specifies that aliasing should not be assumed in -# the program. -# -fp-model precise Enables value-safe optimizations on floating- -# point data and rounds intermediate results to -# source-defined precision. -# -FR Specifies source files are in free format -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -u Sets the default type of a variable to undefined -# (IMPLICIT NONE) -# -traceback Tells the compiler to generate extra information in -# the object file to allow the display of source file -# traceback information at run time when a severe -# error occurs. -# -fpe0 Floating-point invalid, divide-by-zero, and -# overflow exceptions are enabled -# -nomixed_str_len_arg The hidden length passed for a character argument -# is to be placed in sequential order at the end of -# the argument list. [default] -# -names lowercase Causes the compiler to ignore case differences in -# identifiers and to convert external names to -# lowercase. [default] -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -assume byterecl Specifies that the units for the OPEN statement -# RECL specifier (record length) value are in bytes -# for unformatted data files, not longwords (four- -# byte units) -DEBUGFLAGS = -DHYDRO_D -g -traceback -debug all -check all -MODFLAG = -I./ -I../../MPP -I../MPP -I../mod -LDFLAGS = -CPPINVOKE = -fpp -CPPFLAGS = -DMPP_LAND -I../Data_Rec $(HYDRO_D) -# -C: Do not discard comments. -# -P: Inhibit generation of linemarkers in the output -# from the preprocessor. -# -traditional: Try to imitate the behavior of old-fashioned C -# preprocessors, as opposed to ISO C preprocessors. -LIBS = -NETCDFINC = $(NETCDF)/include -NETCDFLIB = -L$(NETCDF)/lib -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.mpp.linux b/hydro/arc/macros.mpp.linux index 8bb08839ad..ce3f13a7f8 100644 --- a/hydro/arc/macros.mpp.linux +++ b/hydro/arc/macros.mpp.linux @@ -3,7 +3,7 @@ ifeq ($(SPATIAL_SOIL),1) SPATIAL_SOIL = -DSPATIAL_SOIL else -SPATIAL_SOIL = +SPATIAL_SOIL = endif ifeq ($(HYDRO_REALTIME),1) @@ -32,32 +32,33 @@ endif ifeq ($(WRF_HYDRO_NUDGING),1) WRF_HYDRO_NUDGING = -DWRF_HYDRO_NUDGING else -WRF_HYDRO_NUDGING = +WRF_HYDRO_NUDGING = endif ifeq ($(OUTPUT_CHAN_CONN),1) OUTPUT_CHAN_CONN = -DOUTPUT_CHAN_CONN else -OUTPUT_CHAN_CONN = +OUTPUT_CHAN_CONN = endif ifeq ($(PRECIP_DOUBLE),1) PRECIP_DOUBLE = -DPRECIP_DOUBLE else -PRECIP_DOUBLE = +PRECIP_DOUBLE = endif -RM = rm -f -RMD = rm -f +RM = rm -f +RMD = rm -f COMPILER90= mpif90 -F90FLAGS = -Mfree -c -byteswapio -O2 -Kieee -DEBUGFLAGS = -DHYDRO_D -g +COMPILERCC= mpicc +F90FLAGS = -Mfree -c -byteswapio -O2 -Kieee +DEBUGFLAGS = -DHYDRO_D -g LDFLAGS = $(F90FLAGS) MODFLAG = -I./ -I ../../MPP -I ../MPP -I ../mod -I ../../mod -I ../../../mod -LDFLAGS = +LDFLAGS = CPPINVOKE = -Mpreprocess CPPFLAGS = -DMPP_LAND -I../Data_Rec $(HYDRO_D) $(SPATIAL_SOIL) $(WRF_HYDRO_NUDGING) $(OUTPUT_CHAN_CONN) $(PRECIP_DOUBLE) -LIBS = -NETCDFINC = $(NETCDF_INC) +LIBS = +NETCDFINC = $(NETCDF_INC) NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.seq.IBM.xlf90_r b/hydro/arc/macros.seq.IBM.xlf90_r deleted file mode 100644 index e5aebcc18c..0000000000 --- a/hydro/arc/macros.seq.IBM.xlf90_r +++ /dev/null @@ -1,39 +0,0 @@ -.IGNORE: - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - - - -RM = rm -f -RMD = rm -f -COMPILER90= xlf90_r -F90FLAGS = -c -O2 -qfree=f90 -qmaxmem=819200 -DEBUGFLAGS = -DHYDRO_D -g -MODFLAG = -I./ -I ../../MPP -I ../MPP -I ../mod -LDFLAGS = -CPP = cpp -C -P -CPPFLAGS = -I../Data_Rec $(HYDRO_D) -LIBS = -NETCDFINC = $(NETCDF_INC) -NETCDFLIB = -L$(NETCDF_LIB) -lnetcdf diff --git a/hydro/arc/macros.seq.gfort b/hydro/arc/macros.seq.gfort deleted file mode 100644 index 22bdfb68b9..0000000000 --- a/hydro/arc/macros.seq.gfort +++ /dev/null @@ -1,43 +0,0 @@ -.IGNORE: - -ifeq ($(SPATIAL_SOIL),1) -SPATIAL_SOIL = -DSPATIAL_SOIL -else -SPATIAL_SOIL = -endif - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - - -RMD = rm -f -COMPILER90= gfortran -F90FLAGS = -w -c -ffree-form -ffree-line-length-none -fconvert=big-endian -frecord-marker=4 -DEBUGFLAGS = -DHYDRO_D -g -Wall -Wextra -Warray-temporaries -Wconversion -fimplicit-none -fbacktrace -ffree-line-length-0 -fcheck=all -ffpe-trap=invalid,zero,overflow,underflow -finit-real=nan -MODFLAG = -I./ -I../mod -LDFLAGS = -CPPINVOKE = -cpp -CPPFLAGS = -I"../Data_Rec" $(HYDRO_D) $(SPATIAL_SOIL) -LIBS = -NETCDFINC = $(NETCDF_INC) -NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.seq.ifort b/hydro/arc/macros.seq.ifort deleted file mode 100644 index be68951c08..0000000000 --- a/hydro/arc/macros.seq.ifort +++ /dev/null @@ -1,56 +0,0 @@ -.IGNORE: - -ifeq ($(SPATIAL_SOIL),1) -SPATIAL_SOIL = -DSPATIAL_SOIL -else -SPATIAL_SOIL = -endif - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifeq ($(WRF_HYDRO_NUDGING),1) -WRF_HYDRO_NUDGING = -DWRF_HYDRO_NUDGING -else -WRF_HYDRO_NUDGING = -endif - -ifeq ($(OUTPUT_CHAN_CONN),1) -OUTPUT_CHAN_CONN = -DOUTPUT_CHAN_CONN -else -OUTPUT_CHAN_CONN = -endif - -RMD = rm -f -COMPILER90= ifort -##F90FLAGS = -w -c -ffree-form -ffree-line-length-none -fconvert=big-endian -frecord-marker=4 -F90FLAGS = -w -c -ftz -align all -fno-alias -fp-model precise -FR -convert big_endian -DEBUGFLAGS = -DHYDRO_D -g -traceback -debug all -check all - -MODFLAG = -I./ -I ../mod -LDFLAGS = -CPPINVOKE = -fpp -CPPFLAGS = -I ../Data_Rec $(HYDRO_D) $(SPATIAL_SOIL) $(WRF_HYDRO_NUDGING) $(OUTPUT_CHAN_CONN) -LIBS = -NETCDFINC = $(NETCDF_INC) -NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.seq.linux b/hydro/arc/macros.seq.linux deleted file mode 100644 index 614a7e0b51..0000000000 --- a/hydro/arc/macros.seq.linux +++ /dev/null @@ -1,57 +0,0 @@ -.IGNORE: - -ifeq ($(SPATIAL_SOIL),1) -SPATIAL_SOIL = -DSPATIAL_SOIL -else -SPATIAL_SOIL = -endif - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifeq ($(WRF_HYDRO_NUDGING),1) -WRF_HYDRO_NUDGING = -DWRF_HYDRO_NUDGING -else -WRF_HYDRO_NUDGING = -endif - -ifeq ($(OUTPUT_CHAN_CONN),1) -OUTPUT_CHAN_CONN = -DOUTPUT_CHAN_CONN -else -OUTPUT_CHAN_CONN = -endif - - -RMD = ls -RM = rm -f -COMPILER90= pgf90 -F90FLAGS = -Mfree -Mfptrap -c -byteswapio -Ktrap=fp -O2 -Kieee -DEBUGFLAGS = -DHYDRO_D -g -LDFLAGS = $(F90FLAGS) -MODFLAG = -I./ -I ../mod -LDFLAGS = -CPPINVOKE = -CPPFLAGS = -I ../Data_Rec $(HYDRO_D) $(WRF_HYDRO) $(SPATIAL_SOIL) $(WRF_HYDRO_NUDGING) $(OUTPUT_CHAN_CONN) -LIBS = -NETCDFINC = $(NETCDF_INC) -NETCDFLIB = -L$(NETCDF_LIB) -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.theia.debug b/hydro/arc/macros.theia.debug deleted file mode 100644 index 5b5b5799f1..0000000000 --- a/hydro/arc/macros.theia.debug +++ /dev/null @@ -1,92 +0,0 @@ -.IGNORE: - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifneq ($(origin ESMFMKFILE), environment) -$(error Environment variable ESMFMKFILE was not set.) -endif -include $(ESMFMKFILE) - -RMD = rm -f -COMPILER90 = $(ESMF_F90COMPILER) -FORMAT_FREE = -FR -BYTESWAPIO = -convert big_endian -F90FLAGS = -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) -F90FLAGS += -g -traceback -# -w Disables all warning messages -# -c Prevents linking. -# -g Produces symbolic debug information in the object -# file. -# -ftz Flushes denormal results to zero when the application -# is in the gradual underflow mode. -# -align all Tells the compiler to add padding bytes whenever -# possible to obtain the natural alignment of data -# items in common blocks, derived types, and record -# structures. -# -fno-alias Specifies that aliasing should not be assumed in -# the program. -# -fp-model precise Enables value-safe optimizations on floating- -# point data and rounds intermediate results to -# source-defined precision. -# -FR Specifies source files are in free format -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -u Sets the default type of a variable to undefined -# (IMPLICIT NONE) -# -traceback Tells the compiler to generate extra information in -# the object file to allow the display of source file -# traceback information at run time when a severe -# error occurs. -# -fpe0 Floating-point invalid, divide-by-zero, and -# overflow exceptions are enabled -# -nomixed_str_len_arg The hidden length passed for a character argument -# is to be placed in sequential order at the end of -# the argument list. [default] -# -names lowercase Causes the compiler to ignore case differences in -# identifiers and to convert external names to -# lowercase. [default] -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -assume byterecl Specifies that the units for the OPEN statement -# RECL specifier (record length) value are in bytes -# for unformatted data files, not longwords (four- -# byte units) -MODFLAG = -I./ -I../../MPP -I../MPP -I../mod -LDFLAGS = -CPPINVOKE = -fpp -CPPFLAGS = -DMPP_LAND -I../Data_Rec $(HYDRO_D) -# -C: Do not discard comments. -# -P: Inhibit generation of linemarkers in the output -# from the preprocessor. -# -traditional: Try to imitate the behavior of old-fashioned C -# preprocessors, as opposed to ISO C preprocessors. -LIBS = -NETCDFINC = $(NETCDF)/include -NETCDFLIB = -L$(NETCDF)/lib -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.yellowstone b/hydro/arc/macros.yellowstone deleted file mode 100644 index 8c5318c0f4..0000000000 --- a/hydro/arc/macros.yellowstone +++ /dev/null @@ -1,92 +0,0 @@ -.IGNORE: - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifneq ($(origin ESMFMKFILE), environment) -$(error Environment variable ESMFMKFILE was not set.) -endif -include $(ESMFMKFILE) - -RMD = rm -f -COMPILER90 = $(ESMF_F90COMPILER) -FORMAT_FREE = -FR -BYTESWAPIO = -convert big_endian -F90FLAGS = -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) -# -w Disables all warning messages -# -c Prevents linking. -# -g Produces symbolic debug information in the object -# file. -# -ftz Flushes denormal results to zero when the application -# is in the gradual underflow mode. -# -align all Tells the compiler to add padding bytes whenever -# possible to obtain the natural alignment of data -# items in common blocks, derived types, and record -# structures. -# -fno-alias Specifies that aliasing should not be assumed in -# the program. -# -fp-model precise Enables value-safe optimizations on floating- -# point data and rounds intermediate results to -# source-defined precision. -# -FR Specifies source files are in free format -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -u Sets the default type of a variable to undefined -# (IMPLICIT NONE) -# -traceback Tells the compiler to generate extra information in -# the object file to allow the display of source file -# traceback information at run time when a severe -# error occurs. -# -fpe0 Floating-point invalid, divide-by-zero, and -# overflow exceptions are enabled -# -nomixed_str_len_arg The hidden length passed for a character argument -# is to be placed in sequential order at the end of -# the argument list. [default] -# -names lowercase Causes the compiler to ignore case differences in -# identifiers and to convert external names to -# lowercase. [default] -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -assume byterecl Specifies that the units for the OPEN statement -# RECL specifier (record length) value are in bytes -# for unformatted data files, not longwords (four- -# byte units) -DEBUGFLAGS = -DHYDRO_D -g -traceback -debug all -check all -MODFLAG = -I./ -I../../MPP -I../MPP -I../mod -LDFLAGS = -CPP = cpp -CPPFLAGS = -P -traditional -DMPP_LAND -I../Data_Rec $(HYDRO_D) -# -C: Do not discard comments. -# -P: Inhibit generation of linemarkers in the output -# from the preprocessor. -# -traditional: Try to imitate the behavior of old-fashioned C -# preprocessors, as opposed to ISO C preprocessors. -LIBS = -NETCDFINC = $(NETCDF)/include -NETCDFLIB = -L$(NETCDF)/lib -lnetcdff -lnetcdf diff --git a/hydro/arc/macros.yellowstone.debug b/hydro/arc/macros.yellowstone.debug deleted file mode 100644 index 93e7aec444..0000000000 --- a/hydro/arc/macros.yellowstone.debug +++ /dev/null @@ -1,92 +0,0 @@ -.IGNORE: - -ifeq ($(HYDRO_REALTIME),1) -HYDRO_REALTIME = -DHYDRO_REALTIME -else -HYDRO_REALTIME = -endif - -ifeq ($(WRF_HYDRO),1) -WRF_HYDRO = -DWRF_HYDRO $(HYDRO_REALTIME) -else -WRF_HYDRO = -endif - -ifeq ($(WRF_HYDRO_RAPID),1) -WRF_HYDRO = -DWRF_HYDRO -DWRF_HYDRO_RAPID $(HYDRO_REALTIME) -endif - -ifeq ($(HYDRO_D),1) -HYDRO_D = -DHYDRO_D $(WRF_HYDRO) -else -HYDRO_D = $(WRF_HYDRO) -endif - - -ifneq ($(origin ESMFMKFILE), environment) -$(error Environment variable ESMFMKFILE was not set.) -endif -include $(ESMFMKFILE) - -RMD = rm -f -COMPILER90 = $(ESMF_F90COMPILER) -FORMAT_FREE = -FR -BYTESWAPIO = -convert big_endian -F90FLAGS = -w -c -ftz -align all -fno-alias -fp-model precise $(FORMAT_FREE) $(BYTESWAPIO) -F90FLAGS += -g -traceback -# -w Disables all warning messages -# -c Prevents linking. -# -g Produces symbolic debug information in the object -# file. -# -ftz Flushes denormal results to zero when the application -# is in the gradual underflow mode. -# -align all Tells the compiler to add padding bytes whenever -# possible to obtain the natural alignment of data -# items in common blocks, derived types, and record -# structures. -# -fno-alias Specifies that aliasing should not be assumed in -# the program. -# -fp-model precise Enables value-safe optimizations on floating- -# point data and rounds intermediate results to -# source-defined precision. -# -FR Specifies source files are in free format -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -u Sets the default type of a variable to undefined -# (IMPLICIT NONE) -# -traceback Tells the compiler to generate extra information in -# the object file to allow the display of source file -# traceback information at run time when a severe -# error occurs. -# -fpe0 Floating-point invalid, divide-by-zero, and -# overflow exceptions are enabled -# -nomixed_str_len_arg The hidden length passed for a character argument -# is to be placed in sequential order at the end of -# the argument list. [default] -# -names lowercase Causes the compiler to ignore case differences in -# identifiers and to convert external names to -# lowercase. [default] -# -convert big_endian Specifies that the format will be big endian for -# INTEGER*1, INTEGER*2, INTEGER*4, or INTEGER*8, -# and big endian IEEE floating-point for REAL*4, -# REAL*8, REAL*16, COMPLEX*8, COMPLEX*16, or COM- -# PLEX*32. -# -assume byterecl Specifies that the units for the OPEN statement -# RECL specifier (record length) value are in bytes -# for unformatted data files, not longwords (four- -# byte units) -MODFLAG = -I./ -I../../MPP -I../MPP -I../mod -LDFLAGS = -CPP = cpp -CPPFLAGS = -C -P -traditional -DMPP_LAND -I../Data_Rec $(HYDRO_D) -# -C: Do not discard comments. -# -P: Inhibit generation of linemarkers in the output -# from the preprocessor. -# -traditional: Try to imitate the behavior of old-fashioned C -# preprocessors, as opposed to ISO C preprocessors. -LIBS = -NETCDFINC = $(NETCDF)/include -NETCDFLIB = -L$(NETCDF)/lib -lnetcdff -lnetcdf diff --git a/hydro/configure b/hydro/configure index ce896c95fe..46a5ba0e33 100755 --- a/hydro/configure +++ b/hydro/configure @@ -4,6 +4,17 @@ theArgument=$1 ################################### ## Setup the HOSTNAME if not set +echo "---------------------------------------------------" +echo " WARNING" +echo "---------------------------------------------------" +echo "WARNING: configure is being deprecated and removed in the future." +echo " See docs/BUILD.md for more detail on building." +echo " Please switch to using CMake from the top directory." +echo " $ mkdir build" +echo " $ cd build" +echo " $ cmake .." +echo " $ make -j 4" +echo "---------------------------------------------------" if [ -z ${HOSTNAME+x} ]; then HOSTNAME=`hostname` @@ -48,9 +59,15 @@ if [[ -z $NETCDF_LIB ]]; then fi if [[ ! -e ${NETCDF_LIB}/libnetcdff.a ]]; then - echo "NETCDFLIB = -L${NETCDF_LIB} -lnetcdf" >> macros.tmp + echo "NETCDFLIB = -L${NETCDF_LIB} -lnetcdf" >> macros.tmp fi - + +# add any additional F90 flags that came out of nf-config (most likely separate module/library path) +if command -v nf-config &> /dev/null; then # ignore if nf-config isn't available + echo "F90FLAGS += $(nf-config --fflags)" >> macros.tmp + echo "NETCDFLIB += $(nf-config --flibs)" >> macros.tmp +fi + ################################### ## File/dir setups if [[ -e macros ]]; then rm -f macros; fi @@ -63,18 +80,17 @@ if [[ ! -e mod ]]; then mkdir mod; fi if [[ -z $theArgument ]]; then echo "Please select from following supported linux compilers" echo "using either the number or key (not case sensitive):" - echo + echo echo "Number Key Description" echo "---------------------------------------------------" - echo " 1 pgi PGI parallel" + echo " 1 nvfort nvidia parallel" echo " 2 gfort gfortran parallel" - echo " 3 ifort intel parallel (incl. Theia, Gordon, Summit)" - echo " 4 luna intel parallel (WCOSS Luna)" + echo " 3 ifx|ifort intel parallel" + echo " 4 cray cray (ftn) parallel" echo " 5 ifort_omp intel openmp" echo " 6 intel.cray_xc intel parallel (cray_xc)" - echo " 7 cray_fortran Cray Fortran PE (ftn)" echo " 0 exit exit" - echo + echo read -p "Enter selection: " theArgument echo fi @@ -86,57 +102,34 @@ theArgument=`echo $theArgument | tr '[:upper:]' '[:lower:]'` ################################### ## What to do with the choice -if [[ "$theArgument" == "1" ]] || [[ "$theArgument" == "pgi" ]]; then - cp arc/macros.mpp.linux macros - cp arc/Makefile.mpp Makefile.comm - echo "Configured: PGI" +if [[ "$theArgument" == "1" ]] || [[ "$theArgument" == "nvfort" ]]; then + cp arc/macros.mpp.linux macros + cp arc/Makefile.mpp Makefile.comm + echo "Configured: nvfort" fi if [[ "$theArgument" == "2" ]] || [[ "$theArgument" == "gfort" ]]; then - cp arc/macros.mpp.gfort macros + cp arc/macros.mpp.gfort macros cp arc/Makefile.mpp Makefile.comm echo "Configured: gfort" fi -if [[ "$theArgument" == "3" ]] || [[ "$theArgument" == "ifort" ]]; then - - ## theia login machines self identify as "tfe" and have - ## their own intel macros. We handle luna more explicitly... - if [[ $HOSTNAME = *tfe* ]]; then - cp arc/macros.mpp.ifort.theia macros - echo "Configured: ifort on Theia" - - elif [[ $HOSTNAME = *gordon* ]]; then - cp arc/macros.mpp.intel.cray_xc macros - echo "Configured: ifort on Gordon" - - elif [[ $HOSTNAME = *shas* ]]; then - cp arc/macros.mpp.ifort.summit_has macros - echo "Configured: ifort on Summit haswell" - - else - cp arc/macros.mpp.ifort macros - echo "Configured: ifort" - fi +if [[ "$theArgument" == "3" ]] || [[ "$theArgument" =~ ^(ifort|ifx|intel)$ ]]; then + cp arc/macros.mpp.ifort macros + echo "Configured: Intel" cp arc/Makefile.mpp Makefile.comm fi -if [[ "$theArgument" == "4" ]] || [[ "$theArgument" == "luna" ]]; then - cp arc/macros.mpp.ifort.luna macros +if [[ "$theArgument" == "4" ]] || [[ "$theArgument" == "cray" ]]; then + cp arc/macros.mpp.cray_fortran macros cp arc/Makefile.mpp Makefile.comm - echo "Configured: ifort on Luna" + echo "Configured: Cray Fortran PrgEnv" fi + if [[ "$theArgument" == "5" ]] || [[ "$theArgument" == "ifort_omp" ]]; then - ## theia login machines self identify as "tfe" and have - ## their own intel macros. We handle luna more explicitly... - if [[ $HOSTNAME != *tfe* ]]; then - cp arc/macros.mpp.ifort.omp macros - echo "Configured: ifort with OpenMP" - else - cp arc/macros.mpp.ifort.theia macros - echo "Configured: ifort on Theia" - fi + cp arc/macros.mpp.ifort.omp macros + echo "Configured: ifort with OpenMP" cp arc/Makefile.mpp Makefile.comm fi @@ -146,11 +139,6 @@ if [[ "$theArgument" == "6" ]] || [[ "$theArgument" == "intel.cray_xc" ]]; then echo "Configured: ifort on cray_xc" fi -if [[ "$theArgument" == "7" ]] || [[ "$theArgument" == "cray_fortran" ]]; then - cp arc/macros.mpp.cray_fortran macros - cp arc/Makefile.mpp Makefile.comm - echo "Configured: Cray Fortran PrgEnv" -fi ## The above result in a new macros file which was @@ -163,16 +151,6 @@ if [[ ! -e macros ]]; then exit 1 fi -# PGI sequential -# cp arc/macros.seq.linux macros -# cp arc/Makefile.seq Makefile.comm -# gfortran sequential -#zystem "cp arc/macros.seq.gfort macros -#cp arc/Makefile.seq Makefile.comm -# ifort sequential -#cp arc/macros.seq.ifort macros -#cp arc/Makefile.seq Makefile.comm - if [[ -e macros.tmp ]]; then cat macros macros.tmp > macros.a rm -f macros.tmp diff --git a/hydro/nudging/CMakeLists.txt b/hydro/nudging/CMakeLists.txt index efaa841343..e7b3856670 100644 --- a/hydro/nudging/CMakeLists.txt +++ b/hydro/nudging/CMakeLists.txt @@ -1,15 +1,13 @@ # build the version static library add_library(hydro_nudging STATIC module_date_utils_nudging.F90 - module_nudging_io.F90 module_nudging_utils.F90 module_stream_nudging.F90 ) target_link_libraries(hydro_nudging PRIVATE + hydro_nudging_io hydro_mpp hydro_data_rec hydro_orchestrator - netCDF::netcdff ) - diff --git a/hydro/nudging/io/CMakeLists.txt b/hydro/nudging/io/CMakeLists.txt new file mode 100644 index 0000000000..e7fdc6a1e8 --- /dev/null +++ b/hydro/nudging/io/CMakeLists.txt @@ -0,0 +1,10 @@ +# build the version static library +add_library(hydro_nudging_io STATIC + module_nudging_io.F90 +) + +target_link_libraries(hydro_nudging_io PRIVATE + hydro_orchestrator + hydro_data_rec + hydro_mpp +) diff --git a/hydro/nudging/module_nudging_io.F90 b/hydro/nudging/io/module_nudging_io.F90 similarity index 98% rename from hydro/nudging/module_nudging_io.F90 rename to hydro/nudging/io/module_nudging_io.F90 index 80f8780e1e..ff4c225071 100644 --- a/hydro/nudging/module_nudging_io.F90 +++ b/hydro/nudging/io/module_nudging_io.F90 @@ -1169,11 +1169,11 @@ end subroutine read_network_reexpression subroutine output_chan_connectivity( & inCHLAT, inCHLON, & !! Channel grid lat, lon. inCHANLEN, & !! The distance between channel grid centers in m. - inFROM_NODE, inTO_NODE, & !! Index of a given cell and the index which it flows to. + inFrom_node, inTo_node, & !! Index of a given cell and the index which it flows to. inCHANXI, inCHANYJ, & !! Index on fine/routing grid of grid cells. - inTYPEL, inLAKENODE & !! Lake type? and node? indications. + inTYPEL, inLakeNode & !! Lake type? and node? indications. ) - + use iso_fortran_env, only: int64 #ifdef MPP_LAND use module_mpp_land @@ -1183,7 +1183,9 @@ subroutine output_chan_connectivity( & !! These are the names used in module_HYDRO_io.F: SUBROUTINE READ_CHROUTING1 real, dimension(:), intent(in) :: inCHLAT, inCHLON, inCHANLEN -integer, dimension(:), intent(in) :: inFROM_NODE, inTO_NODE, inCHANXI, inCHANYJ, inTYPEL, inLAKENODE +integer, dimension(:), intent(in) :: inCHANXI, inCHANYJ, inTYPEL +integer(kind=int64), dimension(:), intent(in) :: inFrom_node, inTo_node +integer(kind=int64), dimension(:), intent(in) :: inLakeNode integer :: nStreamCells, streamCellDimID integer :: iret, projInfo_flag @@ -1196,7 +1198,9 @@ subroutine output_chan_connectivity( & character(len=256), parameter :: output_flnm = "CHANNEL_CONNECTIVITY.nc" real, allocatable, dimension(:) :: CHLAT, CHLON, CHANLEN -integer, allocatable, dimension(:) :: FROM_NODE, TO_NODE, CHANXI, CHANYJ, TYPEL, LAKENODE +integer, allocatable, dimension(:) :: CHANXI, CHANYJ, TYPEL +integer(kind=int64), allocatable, dimension(:) :: from_node, to_node +integer(kind=int64), allocatable, dimension(:) :: lakeNode !! handle the parallelization in this routine instead of in the main code. @@ -1219,9 +1223,9 @@ subroutine output_chan_connectivity( & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, chLon) call write_chanel_real(inChanLen, rt_domain(did)%map_l2g, & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, chanLen) -call write_chanel_int(inFrom_node, rt_domain(did)%map_l2g, & +call write_chanel_int8(inFrom_node, rt_domain(did)%map_l2g, & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, from_node) -call write_chanel_int(inTo_node, rt_domain(did)%map_l2g, & +call write_chanel_int8(inTo_node, rt_domain(did)%map_l2g, & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, to_node) call write_chanel_int(inChanXI, rt_domain(did)%map_l2g, & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, chanXI) @@ -1229,7 +1233,7 @@ subroutine output_chan_connectivity( & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, chanYJ) call write_chanel_int(inTypeL, rt_domain(did)%map_l2g, & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, typeL) -call write_chanel_int(inLakeNode, rt_domain(did)%map_l2g, & +call write_chanel_int8(inLakeNode, rt_domain(did)%map_l2g, & rt_domain(did)%gnlinks, rt_domain(did)%nlinks, lakeNode) #else diff --git a/hydro/utils/CMakeLists.txt b/hydro/utils/CMakeLists.txt index b6d2e57540..77f11eb09b 100644 --- a/hydro/utils/CMakeLists.txt +++ b/hydro/utils/CMakeLists.txt @@ -19,3 +19,5 @@ add_library(hydro_utils STATIC module_hydro_stop.F90 ) target_link_libraries(hydro_utils PRIVATE MPI::MPI_Fortran) + +add_subdirectory(fortglob) diff --git a/hydro/utils/fortglob/CMakeLists.txt b/hydro/utils/fortglob/CMakeLists.txt new file mode 100644 index 0000000000..54ef8bc904 --- /dev/null +++ b/hydro/utils/fortglob/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(fortglob STATIC + libfortglob.c + fortglob.F90 +) diff --git a/hydro/utils/fortglob/Makefile b/hydro/utils/fortglob/Makefile new file mode 100644 index 0000000000..423a33b53b --- /dev/null +++ b/hydro/utils/fortglob/Makefile @@ -0,0 +1,33 @@ +# Makefile + +.PHONY: cp *.F90 *.c + +include ../../macros + +OBJS = \ + fortglob.o \ + libfortglob.o + +all: $(OBJS) cp + +cp: + cp *.mod ../../mod + +%.o: %.F90 + @echo "Utils fortglob Makefile: %.F90" + $(COMPILER90) $(CPPINVOKE) $(CPPFLAGS) -o $(@) $(F90FLAGS) $(LDFLAGS) -I../../ -I$(NETCDFINC) $(*).F90 + @echo "" + ar -r ../../lib/libHYDRO.a $(@) +%.o: %.c + @echo "Utils fortglob Makefile: %.c" + $(COMPILERCC) -o $(@) -c $(*).c + ar -r ../../lib/libHYDRO.a $(@) + @echo "" +# +# Dependencies: +# +fortglob.o: libfortglob.o + + +clean: + rm -f *.o *.mod *.stb *~ diff --git a/hydro/utils/fortglob/fortglob.F90 b/hydro/utils/fortglob/fortglob.F90 new file mode 100644 index 0000000000..658c537d27 --- /dev/null +++ b/hydro/utils/fortglob/fortglob.F90 @@ -0,0 +1,76 @@ +module fortglob + use iso_c_binding + implicit none + + private + public :: glob_t, globfiles + + integer, parameter :: PATH_MAX = 4096 + + type :: glob_t + integer :: nfiles + character(len=PATH_MAX), allocatable :: filenames(:) + end type + + type, bind(c) :: globrec_c + integer (c_size_t) :: nfiles + type(c_ptr) :: filenames + type(c_ptr) :: globptr + end type globrec_c + + interface + function globfiles_c(pattern) bind(c) + use iso_c_binding + character(kind=c_char), dimension(*), intent(in) :: pattern + type(c_ptr) :: globfiles_c + end function globfiles_c + + subroutine freeglobrec(recptr) bind (c) + use iso_c_binding + type(c_ptr), intent(in) :: recptr + end subroutine + + function strlen(s) bind(c) + use iso_c_binding + type(c_ptr), intent(in), value :: s + integer(c_size_t) :: strlen + end function strlen + end interface + + contains + + function globfiles(pattern) + use iso_c_binding + + type(glob_t) :: globfiles + character(len=*), intent(in) :: pattern + + integer :: i, j, slen + character(len=PATH_MAX) :: pattern_c + type(c_ptr) :: glob_c_ptr + type(globrec_c), pointer :: glob_f_ptr + type(c_ptr), pointer :: c_strs(:) + character(kind=c_char), pointer, dimension(:) :: temp_fstrp + + pattern_c = pattern + slen = len_trim(pattern_c) + pattern_c(slen+1:slen+1) = c_null_char + glob_c_ptr = globfiles_c(pattern_c) + call c_f_pointer(glob_c_ptr, glob_f_ptr) + globfiles%nfiles = glob_f_ptr%nfiles + + allocate(globfiles%filenames(globfiles%nfiles)) + + call c_f_pointer(glob_f_ptr%filenames, c_strs, [glob_f_ptr%nfiles]) + do i = 1, globfiles%nfiles + slen = strlen(c_strs(i)) + call c_f_pointer(c_strs(i), temp_fstrp, [slen]) + globfiles%filenames(i) = '' + do j = 1, slen + globfiles%filenames(i)(j:j) = temp_fstrp(j) + end do + end do + + call freeglobrec(glob_f_ptr%globptr) + end function +end module diff --git a/hydro/utils/fortglob/libfortglob.c b/hydro/utils/fortglob/libfortglob.c new file mode 100644 index 0000000000..5a188746b2 --- /dev/null +++ b/hydro/utils/fortglob/libfortglob.c @@ -0,0 +1,19 @@ +#include "libfortglob.h" + +globrec * globfiles_c(const char * pattern) { + globrec *record = malloc(sizeof(globrec)); + glob_t *globbuf = malloc(sizeof(glob_t)); + + glob(pattern, 0, NULL, globbuf); + record->nfiles = globbuf->gl_pathc; + record->filenames = globbuf->gl_pathv; + record->__globptr = globbuf; + + return record; +} + +void freeglobrec(glob_t ** rec) { + glob_t *glob = *rec; + globfree(glob); + free(glob); +} diff --git a/hydro/utils/fortglob/libfortglob.h b/hydro/utils/fortglob/libfortglob.h new file mode 100644 index 0000000000..aec96808f7 --- /dev/null +++ b/hydro/utils/fortglob/libfortglob.h @@ -0,0 +1,13 @@ +#include +#include +#include +#include + +typedef struct globrec { + size_t nfiles; + char ** filenames; + glob_t * __globptr; +} globrec; + +globrec * globfiles_c(const char * pattern); +void freeglobrec(glob_t **rec); diff --git a/hydro/wrf_hydro_config b/hydro/wrf_hydro_config index 4e0e8becb7..5ab885a2fd 100755 --- a/hydro/wrf_hydro_config +++ b/hydro/wrf_hydro_config @@ -8,9 +8,9 @@ if($#ARGV ne 1) { $x = lc(shift(@ARGV)); $paropt = lc(shift(@ARGV)); - print("Configure option for Hydro : $x $paropt \n"); + print("Configure option for Hydro : $x $paropt \n"); if($x =~ "pgi") { - if($paropt eq 'serial') { + if($paropt eq 'serial') { # system("./configure 1"); print "Error : option not defined in WRF-Hyro. \n"; exit(1); @@ -24,15 +24,15 @@ if($#ARGV ne 1) { else {system("./configure 4");} } if($x =~ "gfortran") { - if($paropt eq 'serial') { + if($paropt eq 'serial') { # system("./configure 5"); print "Error : option not defined in WRF-Hyro. \n"; exit(1); } else {system("./configure 2"); exit(0);} } - if($x =~ "ifort") { - if($paropt eq 'serial') { + if ($x =~ /(?:ifort|ifx|intel|oneapi)/i) { + if($paropt eq 'serial') { #system("./configure 7"); print "Error : option not defined. \n"; exit(1); @@ -41,4 +41,3 @@ if($#ARGV ne 1) { } print "Error : option not defined. \n"; exit(1); - From 7f74ddd1aebb5bb54a738f68fc5533e8b1dbf80f Mon Sep 17 00:00:00 2001 From: SengersB <123557559+SengersB@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:37:36 +0100 Subject: [PATCH 6/7] Bug fix for Fitch wind farm scheme: axial induction factor (#2242) TYPE: bug fix KEYWORDS: fitch, wind farm parameterization, turbine, wind farm, wind energy SOURCE: Balthazar Sengers, Fraunhofer IWES, Germany DESCRIPTION OF CHANGES: Problem: 1. In the standard Fitch wind farm parameterization, the local (grid cell) wind speed is used to calculate power and thrust. This wind speed is however reduced because of induction. Power and thrust curves (look-up tables) are determined using free inflow wind speed. 2. The turbine thrust is a relevant metric that is not outputted. Solution: 1. The axial induction factor is calculated and used to correct the local (grid cell) wind speed back to the free inflow wind speed. This is done in 2 iterations. Code becomes an additional option for 'windfarm_opt=1' called windfarm_induction = 1 (default on) where 0 is old version. 2. The turbine thrust is calculated and passed through so it can be outputted now. LIST OF MODIFIED FILES: M Registry/Registry.EM_COMMON M dyn_em/module_first_rk_step_part1.F M phys/module_pbl_driver.F M phys/module_wind_fitch.F A doc/licenses/fraunhofer_license.txt TESTS CONDUCTED: 1. Yes, demonstrated in paper: https://doi.org/10.5194/wes-9-1689-2024 2. The regression tests have passed. RELEASE NOTE: This PR corrects local (grid cell) wind speed to free wind speed using axial induction correction proposed by Vollmer et al. (2024) https://doi.org/10.5194/wes-9-1689-2024 in Fitch wind farm parameterization. The fix can be turned off by using windfarm_induction = 0. --------- Co-authored-by: sengers Co-authored-by: Balthazar Arnoldus Maria Sengers --- LICENSE.txt | 2 +- Registry/Registry.EM_COMMON | 9 +- doc/licenses/fraunhofer_license.txt | 21 +++++ dyn_em/module_first_rk_step_part1.F | 3 + phys/module_pbl_driver.F | 9 ++ phys/module_wind_fitch.F | 131 ++++++++++++++++++++++++++-- run/README.namelist | 3 + 7 files changed, 167 insertions(+), 11 deletions(-) mode change 100644 => 100755 LICENSE.txt create mode 100644 doc/licenses/fraunhofer_license.txt diff --git a/LICENSE.txt b/LICENSE.txt old mode 100644 new mode 100755 index e0c9342282..d652582118 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,3 +1,3 @@ WRF was developed at the National Center for Atmospheric Research (NCAR) which is operated by the University Corporation for Atmospheric Research (UCAR). NCAR and UCAR make no proprietary claims, either statutory or otherwise, to this version and release of WRF and consider WRF to be in the public domain for use by any person or entity for any purpose without any fee or charge. UCAR requests that any WRF user include this notice on any partial or full copies of WRF. WRF is provided on an "AS IS" basis and any warranties, either express or implied, including but not limited to implied warranties of non-infringement, originality, merchantability and fitness for a particular purpose, are disclaimed. In no event shall UCAR be liable for any damages, whatsoever, whether direct, indirect, consequential or special, that arise out of or in connection with the access, use or performance of WRF, including infringement actions. -WRF® is a registered trademark of the University Corporation for Atmospheric Research (UCAR). +WRF® is a registered trademark of the University Corporation for Atmospheric Research (UCAR). \ No newline at end of file diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index d978d6ed1c..03694215d0 100644 --- a/Registry/Registry.EM_COMMON +++ b/Registry/Registry.EM_COMMON @@ -411,7 +411,9 @@ state real bldtacttime - - - - r "bld state real cudtacttime - - - - r "cudtacttime" "CUDTACTTIME" "CPS ACTIVATION TIME in s" state real ltngacttime - - - - r "ltngacttime" "LTNGACTTIME" "LTNG ACTIVATION TIME in s" state real power ij misc 1 - irh "Power" "Power production" "W" - +# THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt +state real thrust ij misc 1 - irh "thrust" "Thrust force" "N" +# END LICENSE # State for derived time quantities. state integer itimestep - - - - rh "itimestep" "" "" @@ -3008,6 +3010,9 @@ state integer nodyn_dummy - dyn_nodyn - - - "" "" "" rconfig integer windfarm_opt namelist,physics max_domains 0 rh "windfarm_opt" "" "" rconfig integer windfarm_ij namelist,physics 1 0 rh "windfarm_ij" "" "" rconfig real windfarm_tke_factor namelist,physics 1 0.25 rh "windfarm_tke_factor" "" "" +# THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt +rconfig integer windfarm_induction namelist,physics 1 1 rh "Fitch axial induction correction" "" "" +# END LICENSE # # Ideal case selection rconfig integer ideal_case namelist,ideal 1 0 rh "ideal_case" "" "" @@ -3398,7 +3403,7 @@ package wrfhydro wrf_hydro==1 - state:SOLDRAIN #WRF Windfarm package no_windfarm windfarm_opt==0 - - -package fitchscheme windfarm_opt==1 - state:power +package fitchscheme windfarm_opt==1 - state:power,thrust # Yulong add for WLM package mavscheme windfarm_opt==2 - state:power diff --git a/doc/licenses/fraunhofer_license.txt b/doc/licenses/fraunhofer_license.txt new file mode 100644 index 0000000000..c524bbbba6 --- /dev/null +++ b/doc/licenses/fraunhofer_license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 FraunhoferIWES + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dyn_em/module_first_rk_step_part1.F b/dyn_em/module_first_rk_step_part1.F index 4f879deef5..ed5c10a4a6 100644 --- a/dyn_em/module_first_rk_step_part1.F +++ b/dyn_em/module_first_rk_step_part1.F @@ -1116,6 +1116,9 @@ SUBROUTINE first_rk_step_part1 ( grid , config_flags & & AKHS=grid%akhs ,AKMS=grid%akms & & ,BL_PBL_PHYSICS=config_flags%bl_pbl_physics & & ,WINDFARM_OPT=config_flags%windfarm_opt,power=grid%power & + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + & ,thrust=grid%thrust & + ! END LICENSE & ,windfarm_wake_model=config_flags%windfarm_wake_model & ! Yulong add for WLM & ,windfarm_overlap_method=config_flags%windfarm_overlap_method & ! Yulong add for WLM & ,BLDT=grid%bldt, CURR_SECS=curr_secs, ADAPT_STEP_FLAG=adapt_step_flag & diff --git a/phys/module_pbl_driver.F b/phys/module_pbl_driver.F index 9aea4378c5..f787fbb19d 100644 --- a/phys/module_pbl_driver.F +++ b/phys/module_pbl_driver.F @@ -28,6 +28,9 @@ SUBROUTINE pbl_driver( & ,kpbl,mixht,ct,lh,snow,xice & ,znu, znw, mut, p_top & ,ctopo,ctopo2,windfarm_opt,power & + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + ,thrust & + ! END LICENSE ,windfarm_wake_model, windfarm_overlap_method & ,ysu_topdown_pblmix & ,shinhong_tke_diag & @@ -545,6 +548,9 @@ SUBROUTINE pbl_driver( & VOCE, & T2, & POWER, & + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + THRUST, & + ! END LICENSE WSPD REAL, DIMENSION( ims:ime, jms:jme ) , & INTENT(INOUT) :: HPBL_HOLD @@ -2071,6 +2077,9 @@ SUBROUTINE pbl_driver( & &,QKE=qke & &,DU=rublten,DV=rvblten & &,WINDFARM_OPT=windfarm_opt,POWER=power & + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + &,THRUST=thrust & + ! END LICENSE &,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 & diff --git a/phys/module_wind_fitch.F b/phys/module_wind_fitch.F index 3adaa8274c..a4e5f97d1f 100644 --- a/phys/module_wind_fitch.F +++ b/phys/module_wind_fitch.F @@ -61,6 +61,9 @@ MODULE module_wind_fitch ! REAL :: turbws(maxvals,maxvals2),turbtc(maxvals,maxvals2),turbpw(maxvals,maxvals2) REAL :: correction_factor + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + INTEGER :: induction_correction + ! END LICENSE ! CONTAINS @@ -70,6 +73,9 @@ SUBROUTINE dragforce( & &,dx,dz,dt,qke & &,du,dv & &,windfarm_opt,power & + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + &,thrust & + ! END LICENSE &,ids,ide,jds,jde,kds,kde & &,ims,ime,jms,jme,kms,kme & &,its,ite,jts,jte,kts,kte & @@ -85,6 +91,9 @@ SUBROUTINE dragforce( & REAL, DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(IN) :: dz,u,v,z_at_w REAL, DIMENSION(ims:ime,kms:kme,jms:jme), INTENT(INOUT) :: du,dv,qke REAL, DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: power + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + REAL, DIMENSION(ims:ime,jms:jme), INTENT(INOUT) :: thrust + ! END LICENSE ! ! Local ! @@ -101,13 +110,23 @@ SUBROUTINE dragforce( & REAL :: speedhub,speed1,speed2 real :: power1,power2,area,ec INTEGER :: kbot,ktop,kt - + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + REAL :: a_ind ! axial induction factor + REAL :: thrust1 + INTEGER :: ii ! running index + INTEGER, DIMENSION(:), ALLOCATABLE :: idx ! temporary array of indices + INTEGER :: nturb ! number of turbines in grid cell + ! END LICENSE + itf=MIN0(ite,ide-1) jtf=MIN0(jte,jde-1) ktf=MIN0(kte,kde-1) wfdensity = 1.0/(dx*dx) ! per turbine, so numerator is 1 power=0. + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + thrust=0. + ! END LICENSE DO kt = 1,nt IF ( windfarm_opt .eq. 1 ) THEN @@ -118,6 +137,15 @@ SUBROUTINE dragforce( & k_turbine_top=-1 !top level i = ival(kt,id) j = jval(kt,id) + + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + if (induction_correction == 1) then + ! BAMS: Number of turbines in current grid cell + idx = PACK([(ii, ii=1,nt)], ival(:,id) == i) ! indices of values equal to i in ival + idx = PACK([(ii, ii=1,SIZE(jval(idx,id)))], jval(idx,id) == j) ! indices of values equal j in jval(idx) + nturb = SIZE(idx) ! number of turbines in grid cell (i,j) + endif + ! END LICENSE ! if (i.ne.-9999.and.j.ne.-9999) then IF (( its .LE. i .AND. i .LE. itf ) .AND. & @@ -168,28 +196,85 @@ SUBROUTINE dragforce( & zheightl = z2 + 0.5*dz(i,k,j) ENDIF ENDDO -! + area = piconst/4.*diameter(kt)**2. ! area swept by turbine blades + + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + IF (induction_correction == 0) THEN ! original Fitch scheme + ! END LICENSE speed1=0. speed2=0. + a_ind=0.01 if (ktop.eq.1) then speedhub=sqrt(u(i,1,j)**2.+v(i,1,j)**2.)*hubheight(kt)/z1 + speedhub=speedhub/((1-a_ind)**nturb) ! BAMS else speed1=sqrt(u(i,kbot,j)**2.+v(i,kbot,j)**2.) speed2=sqrt(u(i,ktop,j)**2.+v(i,ktop,j)**2.) speedhub=speed1+((speed2-speed1)/(z2-z1))*(hubheight(kt)-z1) + speedhub=speedhub/((1-a_ind)**nturb) ! BAMS endif ! ! ... calculate TKE, power and thrust coeffs ! CALL dragcof(tkecof,powcof,thrcof, & speedhub,cutin(kt),cutout(kt), & - npower(kt),diameter(kt),stc(kt),stc2(kt),nkind(kt)) + npower(kt),diameter(kt),stc(kt),stc2(kt),nkind(kt)) + + + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + ELSEIF (induction_correction == 1) THEN ! Fitch scheme with induction correction + ! ... BAMS: first iteration with induction first estimate + speed1=0. + speed2=0. + a_ind=0.01 + if (ktop.eq.1) then + speedhub=sqrt(u(i,1,j)**2.+v(i,1,j)**2.)*hubheight(kt)/z1 + speedhub=speedhub/((1-a_ind)**nturb) + else + speed1=sqrt(u(i,kbot,j)**2.+v(i,kbot,j)**2.) + speed2=sqrt(u(i,ktop,j)**2.+v(i,ktop,j)**2.) + speedhub=speed1+((speed2-speed1)/(z2-z1))*(hubheight(kt)-z1) + speedhub=speedhub/((1-a_ind)**nturb) + endif +! +! ... calculate TKE, power and thrust coeffs +! + CALL dragcof(tkecof,powcof,thrcof, & + speedhub,cutin(kt),cutout(kt), & + npower(kt),diameter(kt),stc(kt),stc2(kt),nkind(kt)) + + ! ... BAMS: second iteration + a_ind = 0.5 * (1 - sqrt(1 - thrcof)) + a_ind = a_ind * area / ( diameter(kt) * dx * & + MIN(ABS(1/COS(ATAN( ((v(i,ktop,j) + v(i,kbot,j))/2) / ((u(i,ktop,j) + u(i,kbot,j))/2) ))), & + ABS(1/SIN(ATAN( ((v(i,ktop,j) + v(i,kbot,j))/2) / ((u(i,ktop,j) + u(i,kbot,j))/2) )))) ) ! Corrected induction factor + + speed1=0. + speed2=0. + if (ktop.eq.1) then + speedhub=sqrt(u(i,1,j)**2.+v(i,1,j)**2.)*hubheight(kt)/z1 + speedhub=speedhub/((1-a_ind)**nturb) + else + speed1=sqrt(u(i,kbot,j)**2.+v(i,kbot,j)**2.) + speed2=sqrt(u(i,ktop,j)**2.+v(i,ktop,j)**2.) + speedhub=speed1+((speed2-speed1)/(z2-z1))*(hubheight(kt)-z1) + speedhub=speedhub/((1-a_ind)**nturb) + endif + + CALL dragcof(tkecof,powcof,thrcof, & + speedhub,cutin(kt),cutout(kt), & + npower(kt),diameter(kt),stc(kt),stc2(kt),nkind(kt)) + ENDIF + ! END LICENSE ! ! ... PAJ: Computation of power generated by the wind turbine ... ! - area=piconst/4.*diameter(kt)**2. ! area swept by turbine blades power1=0.5*1.23*speedhub**3.*area*powcof power(i,j)=power1+power(i,j) + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + thrust1=0.5*1.23*speedhub**2.*area*thrcof + thrust(i,j)=thrust1+thrust(i,j) + ! END LICENSE power2=0. ! DO k=k_turbine_bot,k_turbine_top ! loop over turbine blade levels @@ -200,6 +285,11 @@ SUBROUTINE dragforce( & CALL turbine_area(z1,z2,diameter(kt),wfdensity,tarea) ! speed=sqrt(u(i,k,j)**2.+v(i,k,j)**2.) + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + IF (induction_correction == 1) THEN ! original Fitch scheme + speed= speed / ((1-a_ind)**nturb) + ENDIF + ! END LICENSE power2=power2+0.5*powcof*1.23*(speed**3.)*tarea/wfdensity ENDDO ! @@ -214,6 +304,11 @@ SUBROUTINE dragforce( & CALL turbine_area(z1,z2,diameter(kt),wfdensity,tarea) ! speed=sqrt(u(i,k,j)**2.+v(i,k,j)**2.) + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + IF (induction_correction == 1) THEN ! original Fitch scheme + speed= speed / ((1-a_ind)**nturb) + ENDIF + ! END LICENSE !` ! ... PAJ: normalization introduced to conserve energy ... ! @@ -225,10 +320,22 @@ SUBROUTINE dragforce( & ! ! output TKE qke(i,k,j) = qke(i,k,j)+speed**3.*tarea*tkecof*dt/dz(i,k,j)*ec - ! output u tendency - du(i,k,j) = du(i,k,j)-.5*u(i,k,j)*thrcof*speed*tarea/dz(i,k,j)*ec - ! output v tendency - dv(i,k,j) = dv(i,k,j)-.5*v(i,k,j)*thrcof*speed*tarea/dz(i,k,j)*ec + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + IF (induction_correction == 0) THEN + ! END LICENSE + ! output u tendency + du(i,k,j) = du(i,k,j)-.5*u(i,k,j)*thrcof*speed*tarea/dz(i,k,j)*ec + ! output v tendency + dv(i,k,j) = dv(i,k,j)-.5*v(i,k,j)*thrcof*speed*tarea/dz(i,k,j)*ec + + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + ELSEIF (induction_correction == 1) THEN + ! output u tendency + du(i,k,j) = du(i,k,j)-.5*(u(i,k,j)/((1-a_ind)**nturb))*thrcof*speed*tarea/dz(i,k,j)*ec + ! output v tendency + dv(i,k,j) = dv(i,k,j)-.5*(v(i,k,j)/((1-a_ind)**nturb))*thrcof*speed*tarea/dz(i,k,j)*ec + ENDIF + ! END LICENSE ENDDO ENDIF ENDIF @@ -310,6 +417,11 @@ SUBROUTINE dragcof(tkecof,powcof,thrcof,speed,cispeed,cospeed, & thrcof = turbtc(nkind,nb)+(turbtc(nkind,nu)-turbtc(nkind,nb))/(turbws(nkind,nu)-turbws(nkind,nb))*(speed-turbws(nkind,nb)) ENDIF ENDIF + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + IF (induction_correction == 1) THEN + thrcof = MAX(MIN(thrcof,0.9999),0.0001) ! BAMS + ENDIF + ! END LICENSE ! ! ... power coeficient ... ! @@ -354,6 +466,9 @@ SUBROUTINE init_module_wind_fitch(id,config_flags,xlong,xlat,windfarm_initialize ! correction_factor = config_flags%windfarm_tke_factor + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + induction_correction = config_flags%windfarm_induction + ! END LICENSE IF ( wrf_dm_on_monitor() ) THEN ! ! ... PAJ: Opens the file with the location of the wind turbines ... diff --git a/run/README.namelist b/run/README.namelist index 4ce895b539..74138252b1 100644 --- a/run/README.namelist +++ b/run/README.namelist @@ -1133,6 +1133,9 @@ Options for wind turbine drag parameterization: ! 1 = The coordinate of the turbines are defined in terms of grid points ! 2 = Valid only with windfarm_opt=2. The coordinate of the turbines are defined in terms of lat-lon with the filename of 'windturbines-ll.txt' + ! THE FOLLOWING LINES OF CODE ARE LICENSED UNDER doc/licenses/fraunhofer_license.txt + windfarm_induction = 1 ! Use the axial induction correction as described by Vollmer et al (2024). Valid only with 'windfarm_opt=1'. 0: Off, 1: On (default) + ! END LICENSE windfarm_wake_model = 2 ! Subgrid-scale wind turbine wake model, valid only with windfarm_opt=2, default is 2 ! 1 = The Jensen model ! 2 = The XA model From e39e090c94fbddf45b8cc63ebbbae25666860593 Mon Sep 17 00:00:00 2001 From: Chenghao Wang <49321740+chenghaow@users.noreply.github.com> Date: Fri, 13 Feb 2026 02:56:12 -0600 Subject: [PATCH 7/7] Add WRF-urban-Nature-based Solution development to Single-Layer Urban Canopy Model (#2272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **TYPE:** new feature **KEYWORDS:** urban canopy models, urban trees, nature-based solutions, urban grass, urban hydrology, radiative view factors **SOURCE:** Yuqi Huang (University of Oklahoma), Chenghao Wang (University of Oklahoma), Cenlin He (NCAR) **DESCRIPTION OF CHANGES:** _Problem:_ The current WRF-urban modeling system employs a single-layer urban canopy model (SLUCM) that assumes a dry street canyon. While a green roof module exists, ground vegetation and street trees are not represented. As a result, key nature-based solution (NbS) processes such as evapotranspiration, radiative shading, and soil–vegetation–atmosphere interactions are not captured. In addition, radiative exchanges involving trees are not explicitly resolved. A version of the urban tree module within SLUCM was developed and tested for the contiguous U.S. but only accounted for shading in a simplified way: - Wang, C., Wang, Z. H., & Yang, J. (2018). Cooling effect of urban trees on the built environment of contiguous United States. Earth's Future, 6(8), 1066–1081. https://doi.org/10.1029/2018EF000891 _Solution:_ This PR introduces urban ground vegetation and street trees into the single-layer urban canopy model. Round-shaped urban trees are explicitly represented, resolving evapotranspiration, shading, and root water uptake. Radiative exchanges between trees and surrounding urban elements are solved using newly implemented analytical view factors. The development is largely based on the Arizona State University Single-Layer Urban Canopy Model (ASLUM v3.1) and its hydrologically enhanced version, ASLUM-Hydro, and extends their capabilities within the WRF-Urban framework. See the following two papers for ASLUM v3.1 and ASLUM-Hydro: - Wang, C., Wang, Z. H., & Ryu, Y. H. (2021). A single-layer urban canopy model with transmissive radiation exchange between trees and street canyons. Building and Environment, 191, 107593. https://doi.org/10.1016/j.buildenv.2021.107593 - Huang, Y., Wang, C., & Wang, Z. H. (2025). Multi-parameterization of hydrological processes in an urban canopy model. Building and Environment, 113567. https://doi.org/10.1016/j.buildenv.2025.113567 This PR also includes the following fixes: 1. Shadow option: The default of `SHADOW` was changed to `.true.`. In the previous default setting, street-canyon shadowing was not considered. We can switch this back if you think the default should remain unchanged. 2. Impervious water retention: Minor bug fixes related to water retention depth over impervious surfaces. These only apply when `IMP_SCHEME == 2` (the default in the table is 1). 3. Radiative (green) roof term (`GROPTION = 1`): Changed `RGR = EPSV*(RX-SIG*(TA**4.)/60.)` to `RGR = EPSV*(RX-SIG*(TGRP**4.)/60.)`. This is a bug fix. Note that the default table value for `GROPTION` is 0. **LIST OF MODIFIED FILES:** M Registry/Registry.EM_COMMON M dyn_em/module_first_rk_step_part1.F M dyn_em/start_em.F M phys/module_physics_init.F M phys/module_sf_clm.F M phys/module_sf_noahdrv.F M phys/module_sf_urban.F M phys/module_surface_driver.F M run/URBPARM.TBL M run/URBPARM_LCZ.TBL M run/URBPARM_UZE.TBL M wrftladj/module_physics_init_ad.F M wrftladj/module_physics_init_tl.F M wrftladj/start_em_ad.F M wrftladj/start_em_tl.F **TESTS CONDUCTED:** - Successfully tested in offline mode coupled with the HRLDAS system - Demonstrated systematic performance improvements across 20 global urban sites when evaluated against flux-tower observations from the Urban-PLUMBER project - Successfully compiled on the NCAR Derecho system - Short-term online WRF simulations are currently ongoing - Have passed the regression tests. **Note:** Successful compilation requires Noah-MP-related source files that arenot included in WRF v3.7.1, including a modified version of`module_sf_noahmpdrv.F`. These changes will be addressed in a separatePR dedicated to Noah-MP. **RELEASE NOTE:** This PR introduces urban ground vegetation and street trees into the single-layer urban canopy model and it is based on the following two manuscripts in development: - Huang, Y., Wang, C., & He, C. Integrating nature-based solutions intothe WRF-urban modeling system. Manuscript in prepration. - Wang, C., Huang, Y., Miller, D. L., Katz, D., & Ghosh, A. K. Analytical view factors for urban canopy models with trees: model development and case study in New York City. Manuscript in preparation. --- Registry/Registry.EM_COMMON | 13 +- dyn_em/module_first_rk_step_part1.F | 9 + dyn_em/start_em.F | 3 + phys/module_physics_init.F | 29 + phys/module_sf_clm.F | 38 + phys/module_sf_noahdrv.F | 95 +- phys/module_sf_urban.F | 1805 ++++++++++++++++++++++++--- phys/module_surface_driver.F | 26 +- phys/noahmp | 2 +- run/URBPARM.TBL | 39 + run/URBPARM_LCZ.TBL | 42 +- run/URBPARM_UZE.TBL | 39 + wrftladj/module_physics_init_ad.F | 27 +- wrftladj/module_physics_init_tl.F | 27 +- wrftladj/start_em_ad.F | 3 +- wrftladj/start_em_tl.F | 3 +- 16 files changed, 1984 insertions(+), 216 deletions(-) diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON index 03694215d0..1f857fef58 100644 --- a/Registry/Registry.EM_COMMON +++ b/Registry/Registry.EM_COMMON @@ -935,8 +935,17 @@ state real DRELG_URB2D ij misc 1 - rd=(interp_m state real FLXHUMR_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "FLXHUMR_URB" "WATER FLUX ON ROOF IMPERVIOUS SURFACE" "m/s" state real FLXHUMB_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "FLXHUMB_URB" "WATER FLUX ON WALL IMPERVIOUS SURFACE" "m/s" state real FLXHUMG_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "FLXHUMG_URB" "WATER FLUX ON ROAD IMPERVIOUS SURFACE" "m/s" +# added by Chenghao Wang +state real TVG_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "TVG_URB" "URBAN VEGETATED GROUND TEMPERATURE" "K" +state real TT_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "TT_URB" "URBAN TREE TEMPERATURE" "K" +state real XXXVG_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "XXXVG_URB" "M-O LENGTH ABOVE URBAN VEGETATED GROUND" "dimensionless" +state real CMCG_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "CMCG_URB" "CANOPY INTERCEPTED WATER ON VEGETATED GROUND" "m" +state real FLXHUMVG_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "FLXHUMVG_URB" "WATER FLUX ON VEGETATED GROUND" "m/s" +state real FLXHUMT_URB2D ij misc 1 - rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "FLXHUMT_URB" "WATER FLUX ON URBAN TREES" "m/s" state real TGRL_URB3D ilj misc 1 Z rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "TGRL_URB" "GREEN ROOF LAYER TEMPERATURE" state real SMR_URB3D ilj misc 1 Z rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "SMR_URB" "GREEN ROOF LAYER SOIL MOISTURE" +state real TVGL_URB3D ilj misc 1 Z rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "TVGL_URB" "VEGETATED GROUND LAYER TEMPERATURE" "K" +state real SMG_URB3D ilj misc 1 Z rd=(interp_mask_land_field:lu_index)u=(copy_fcnm) "SMG_URB" "VEGETATED GROUND LAYER SOIL MOISTURE" "dimensionless" state real TRL_URB3D ilj misc 1 Z rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TRL_URB" "ROOF LAYER TEMPERATURE" "K" state real TBL_URB3D ilj misc 1 Z rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TBL_URB" "WALL LAYER TEMPERATURE" "K" state real TGL_URB3D ilj misc 1 Z rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TGL_URB" "ROAD LAYER TEMPERATURE" "K" @@ -3158,7 +3167,8 @@ package temfsfcscheme sf_sfclay_physics==10 - state:wm_ package idealscmsfcscheme sf_sfclay_physics==89 - - package sfclayscheme sf_sfclay_physics==91 - - -package noahucmscheme sf_urban_physics==1 - state:trb_urb4d,tw1_urb4d,tw2_urb4d,tgb_urb4d,sfw1_urb3d,sfw2_urb3d,sfr_urb3d,sfg_urb3d,a_u_bep,a_v_bep,a_t_bep,a_q_bep,a_e_bep,b_u_bep,b_v_bep,b_t_bep,b_q_bep,b_e_bep,dlg_bep,dl_u_bep,sf_bep,vl_bep,mh_urb2d,stdh_urb2d,lf_urb2d,lp_urb2d,hgt_urb2d,lb_urb2d,tgr_urb2d,cmcr_urb2d,drelr_urb2d,drelb_urb2d,drelg_urb2d,flxhumr_urb2d,flxhumb_urb2d,flxhumg_urb2d,tgrl_urb3d,smr_urb3d,cmgr_sfcdif,chgr_sfcdif,trl_urb3d,tgl_urb3d,tbl_urb3d,ahe,lf_urb2d_s,z0_urb2d,zd_urb2d +# added by Chenghao Wang +package noahucmscheme sf_urban_physics==1 - state:trb_urb4d,tw1_urb4d,tw2_urb4d,tgb_urb4d,sfw1_urb3d,sfw2_urb3d,sfr_urb3d,sfg_urb3d,a_u_bep,a_v_bep,a_t_bep,a_q_bep,a_e_bep,b_u_bep,b_v_bep,b_t_bep,b_q_bep,b_e_bep,dlg_bep,dl_u_bep,sf_bep,vl_bep,mh_urb2d,stdh_urb2d,lf_urb2d,lp_urb2d,hgt_urb2d,lb_urb2d,tgr_urb2d,cmcr_urb2d,drelr_urb2d,drelb_urb2d,drelg_urb2d,flxhumr_urb2d,flxhumb_urb2d,flxhumg_urb2d,tvg_urb2d,tt_urb2d,xxxvg_urb2d,cmcg_urb2d,flxhumvg_urb2d,flxhumt_urb2d,tgrl_urb3d,smr_urb3d,tvgl_urb3d,smg_urb3d,cmgr_sfcdif,chgr_sfcdif,trl_urb3d,tgl_urb3d,tbl_urb3d,ahe,lf_urb2d_s,z0_urb2d,zd_urb2d package bepscheme sf_urban_physics==2 - state:a_u_bep,a_v_bep,a_t_bep,a_q_bep,a_e_bep,b_u_bep,b_v_bep,b_t_bep,b_q_bep,b_e_bep,dlg_bep,dl_u_bep,sf_bep,vl_bep,trb_urb4d,tw1_urb4d,tw2_urb4d,tgb_urb4d,sfw1_urb3d,sfw2_urb3d,sfr_urb3d,sfg_urb3d,hi_urb2d,lp_urb2d,hgt_urb2d,lb_urb2d,trl_urb3d,tgl_urb3d,tbl_urb3d,tsk_rural package bep_bemscheme sf_urban_physics==3 - state:a_u_bep,a_v_bep,a_t_bep,a_q_bep,a_e_bep,b_u_bep,b_v_bep,b_t_bep,b_q_bep,b_e_bep,dlg_bep,dl_u_bep,sf_bep,vl_bep,trb_urb4d,tw1_urb4d,tw2_urb4d,tgb_urb4d,tlev_urb3d,qlev_urb3d,tw1lev_urb3d,tw2lev_urb3d,tglev_urb3d,tflev_urb3d,sf_ac_urb3d,lf_ac_urb3d,cm_ac_urb3d,sfvent_urb3d,lfvent_urb3d,sfwin1_urb3d,sfwin2_urb3d,sfw1_urb3d,sfw2_urb3d,sfr_urb3d,sfg_urb3d,hi_urb2d,lp_urb2d,hgt_urb2d,lb_urb2d,trl_urb3d,tgl_urb3d,tbl_urb3d,tsk_rural,ep_pv_urb3d,t_pv_urb3d,trv_urb4d,qr_urb4d,qgr_urb3d,tgr_urb3d,drain_urb4d,draingr_urb3d,sfrv_urb3d,lfrv_urb3d,dgr_urb3d,dg_urb3d,lfr_urb3d,lfg_urb3d @@ -3682,4 +3692,3 @@ rconfig real windfarm_deg namelist,physics max_domains # outputs for RCON model. state real CLOUDNC ij misc 1 - rh "CLOUDNC" "ACCUMULATED TOTAL GRID SCALE CLOUD PRECIPITATION" "mm" - diff --git a/dyn_em/module_first_rk_step_part1.F b/dyn_em/module_first_rk_step_part1.F index ed5c10a4a6..4aff0f798c 100644 --- a/dyn_em/module_first_rk_step_part1.F +++ b/dyn_em/module_first_rk_step_part1.F @@ -791,6 +791,15 @@ SUBROUTINE first_rk_step_part1 ( grid , config_flags & & ,FLXHUMR_URB2D=grid%flxhumr_urb2d & !H urban & ,FLXHUMB_URB2D=grid%flxhumb_urb2d & !H urban & ,FLXHUMG_URB2D=grid%flxhumg_urb2d & !H urban + & ! added by Chenghao Wang + & ,TVG_URB2D=grid%tvg_urb2d & !H urban + & ,XXXVG_URB2D=grid%xxxvg_urb2d & !H urban + & ,TVGL_URB3D=grid%tvgl_urb3d & !H urban + & ,SMG_URB3D=grid%smg_urb3d & !H urban + & ,TT_URB2D=grid%tt_urb2d & !H urban + & ,CMCG_URB2D=grid%cmcg_urb2d & !H urban + & ,FLXHUMVG_URB2D=grid%flxhumvg_urb2d & !H urban + & ,FLXHUMT_URB2D=grid%flxhumt_urb2d & !H urban & ,TRL_URB3D=grid%trl_urb3d ,TBL_URB3D=grid%tbl_urb3d & !H urban & ,TGL_URB3D=grid%tgl_urb3d & !H urban & ,SH_URB2D=grid%sh_urb2d ,LH_URB2D=grid%lh_urb2d & diff --git a/dyn_em/start_em.F b/dyn_em/start_em.F index 700f0df38c..78872ae19e 100644 --- a/dyn_em/start_em.F +++ b/dyn_em/start_em.F @@ -1148,6 +1148,9 @@ SUBROUTINE start_domain_em ( grid, allowed_to_read & grid%CMCR_URB2D,grid%TGR_URB2D,grid%TGRL_URB3D,grid%SMR_URB3D, & !Optional urban grid%DRELR_URB2D,grid%DRELB_URB2D,grid%DRELG_URB2D, & !Optional urban grid%FLXHUMR_URB2D,grid%FLXHUMB_URB2D,grid%FLXHUMG_URB2D, & !Optional urban + ! added by Chenghao Wang + grid%TVG_URB2D,grid%XXXVG_URB2D,grid%TVGL_URB3D,grid%SMG_URB3D,grid%TT_URB2D, & !Optional urban + grid%CMCG_URB2D,grid%FLXHUMVG_URB2D,grid%FLXHUMT_URB2D, & !Optional urban grid%TRB_URB4D,grid%TW1_URB4D,grid%TW2_URB4D,grid%TGB_URB4D,grid%TLEV_URB3D, & !multi-layer urban grid%QLEV_URB3D,grid%TW1LEV_URB3D,grid%TW2LEV_URB3D, & !multi-layer urban grid%TGLEV_URB3D,grid%TFLEV_URB3D,grid%SF_AC_URB3D, & !multi-layer urban diff --git a/phys/module_physics_init.F b/phys/module_physics_init.F index 2e9c6640bc..82f40de909 100644 --- a/phys/module_physics_init.F +++ b/phys/module_physics_init.F @@ -158,6 +158,8 @@ SUBROUTINE phy_init ( id, config_flags, DT, restart, zfull, zhalf, & DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !Optional urban FLXHUMR_URB2D,FLXHUMB_URB2D, & !Optional urban FLXHUMG_URB2D, & !Optional urban + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !Optional urban TRB_URB4D,TW1_URB4D,TW2_URB4D, & !Optional multi-layer urban TGB_URB4D,TLEV_URB3D,QLEV_URB3D, & !Optional multi-layer urban TW1LEV_URB3D,TW2LEV_URB3D, & !Optional multi-layer urban @@ -639,6 +641,13 @@ SUBROUTINE phy_init ( id, config_flags, DT, restart, zfull, zhalf, & REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMG_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TGR_URB2D + ! added by Chenghao Wang + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D ! REAL, DIMENSION(ims:ime, 1:num_roof_layers, jms:jme), INTENT(INOUT) :: TRL_URB3D !urban ! REAL, DIMENSION(ims:ime, 1:num_wall_layers, jms:jme), INTENT(INOUT) :: TBL_URB3D !urban @@ -648,6 +657,8 @@ SUBROUTINE phy_init ( id, config_flags, DT, restart, zfull, zhalf, & REAL, OPTIONAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: TGL_URB3D !urban REAL, OPTIONAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: TGRL_URB3D !urban REAL, OPTIONAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: SMR_URB3D !urban + REAL, OPTIONAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: TVGL_URB3D !urban + REAL, OPTIONAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: SMG_URB3D !urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: SH_URB2D !urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: LH_URB2D !urban @@ -1496,6 +1507,9 @@ SUBROUTINE phy_init ( id, config_flags, DT, restart, zfull, zhalf, & CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & !Optional urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !Optional urban FLXHUMR_URB2D,FLXHUMB_URB2D,FLXHUMG_URB2D, & !Optional urban + ! added by Chenghao Wang + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !Optional urban num_urban_ndm, & !Optional multi-layer urban urban_map_zrd, & !Optional multi-layer urban urban_map_zwd, & !Optional multi-layer urban @@ -2529,6 +2543,8 @@ SUBROUTINE bl_init(STEPBL,BLDT,DT,RUBLTEN,RVBLTEN,RTHBLTEN, & CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & !Optional urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !Optional urban FLXHUMR_URB2D,FLXHUMB_URB2D,FLXHUMG_URB2D, & !Optional urban + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !Optional urban num_urban_ndm, & !Optional multi-layer urban urban_map_zrd, & !Optional multi-layer urban urban_map_zwd, & !Optional multi-layer urban @@ -2877,6 +2893,13 @@ SUBROUTINE bl_init(STEPBL,BLDT,DT,RUBLTEN,RVBLTEN,RTHBLTEN, & REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMG_URB2D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCR_URB2D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TGR_URB2D !Optional urban + ! added by Chenghao Wang + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: SH_URB2D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: LH_URB2D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: G_URB2D !Optional urban @@ -2892,6 +2915,8 @@ SUBROUTINE bl_init(STEPBL,BLDT,DT,RUBLTEN,RVBLTEN,RTHBLTEN, & REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_soil_layers, jms:jme ), INTENT(INOUT) :: TGL_URB3D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_soil_layers, jms:jme ), INTENT(INOUT) :: TGRL_URB3D !Optional urban REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_soil_layers, jms:jme ), INTENT(INOUT) :: SMR_URB3D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_soil_layers, jms:jme ), INTENT(INOUT) :: TVGL_URB3D !Optional urban + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_soil_layers, jms:jme ), INTENT(INOUT) :: SMG_URB3D !Optional urban INTEGER , INTENT(IN) :: num_urban_ndm INTEGER , INTENT(IN) :: urban_map_zrd @@ -3335,6 +3360,8 @@ SUBROUTINE bl_init(STEPBL,BLDT,DT,RUBLTEN,RVBLTEN,RTHBLTEN, & CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & !urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !urban FLXHUMR_URB2D, FLXHUMB_URB2D, FLXHUMG_URB2D, & !urban + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & !urban + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !urban A_U_BEP,A_V_BEP,A_T_BEP,A_Q_BEP, & !multi-layer urban A_E_BEP,B_U_BEP,B_V_BEP, & !multi-layer urban B_T_BEP,B_Q_BEP,B_E_BEP,DLG_BEP, & !multi-layer urban @@ -3478,6 +3505,8 @@ SUBROUTINE bl_init(STEPBL,BLDT,DT,RUBLTEN,RVBLTEN,RTHBLTEN, & CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & !urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !urban FLXHUMR_URB2D, FLXHUMB_URB2D, FLXHUMG_URB2D, & !urban + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & !urban + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !urban A_U_BEP,A_V_BEP,A_T_BEP,A_Q_BEP, & !multi-layer urban A_E_BEP,B_U_BEP,B_V_BEP, & !multi-layer urban B_T_BEP,B_Q_BEP,B_E_BEP,DLG_BEP, & !multi-layer urban diff --git a/phys/module_sf_clm.F b/phys/module_sf_clm.F index 3a8c0d6006..f428430929 100644 --- a/phys/module_sf_clm.F +++ b/phys/module_sf_clm.F @@ -58802,6 +58802,8 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & cmcr_urb2d,tgr_urb2d,tgrl_urb3d,smr_urb3d, & ! urban drelr_urb2d,drelb_urb2d,drelg_urb2d, & ! urban flxhumr_urb2d,flxhumb_urb2d,flxhumg_urb2d, & + tvg_urb2d,xxxvg_urb2d,tvgl_urb3d,smg_urb3d,tt_urb2d, & + cmcg_urb2d,flxhumvg_urb2d,flxhumt_urb2d, & ! subgrids numc,nump,sabv,sabg,lwup,snl, & snowdp,wtc,wtp,h2osno,t_grnd,t_veg, & @@ -59240,6 +59242,15 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & REAL :: TGR_URB REAL, DIMENSION(1:num_roof_layers) :: SMR_URB ! green roof layer moisture REAL, DIMENSION(1:num_roof_layers) :: TGRL_URB ! green roof layer temp [K] + ! added by Chenghao Wang + REAL :: TVG_URB + REAL :: TT_URB + REAL :: XXXVG_URB + REAL :: CMCG_URB + REAL :: FLXHUMVG_URB + REAL :: FLXHUMT_URB + REAL, DIMENSION(1:num_road_layers) :: TVGL_URB ! vegetated ground layer temp [K] + REAL, DIMENSION(1:num_road_layers) :: SMG_URB ! vegetated ground layer moisture REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELB_URB2D @@ -59247,10 +59258,19 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMB_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMG_URB2D + ! added by Chenghao Wang + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TGR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_roof_layers, jms:jme ), INTENT(INOUT) :: TGRL_URB3D REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_roof_layers, jms:jme ), INTENT(INOUT) :: SMR_URB3D + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_road_layers, jms:jme ), INTENT(INOUT) :: TVGL_URB3D + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_road_layers, jms:jme ), INTENT(INOUT) :: SMG_URB3D ! state variable surface_driver <--> lsm <--> urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TR_URB2D @@ -60281,6 +60301,8 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & END DO DO K = 1,num_road_layers TGL_URB(K) = TGL_URB3D(I,K,J) + TVGL_URB(K) = TVGL_URB3D(I,K,J) + SMG_URB(K) = SMG_URB3D(I,K,J) END DO !sw++ TGR_URB = TGR_URB2D(I,J) @@ -60291,6 +60313,12 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & DRELR_URB = DRELR_URB2D(I,J) DRELB_URB = DRELB_URB2D(I,J) DRELG_URB = DRELG_URB2D(I,J) + TVG_URB = TVG_URB2D(I,J) + TT_URB = TT_URB2D(I,J) + XXXVG_URB = XXXVG_URB2D(I,J) + CMCG_URB = CMCG_URB2D(I,J) + FLXHUMVG_URB = FLXHUMVG_URB2D(I,J) + FLXHUMT_URB = FLXHUMT_URB2D(I,J) !sw-- XXXR_URB = XXXR_URB2D(I,J) @@ -60355,6 +60383,8 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & TGRL_URB,SMR_URB,CMGR_URB, CHGR_URB, jmonth, & ! H DRELR_URB,DRELB_URB, & ! H DRELG_URB,FLXHUMR_URB,FLXHUMB_URB,FLXHUMG_URB, & + ! added by Chenghao Wang + TVG_URB,TT_URB,XXXVG_URB,TVGL_URB,SMG_URB,CMCG_URB,FLXHUMVG_URB,FLXHUMT_URB, & lf_urb_s, z0_urb, vegfrac) !sw-- @@ -60390,6 +60420,8 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & END DO DO K = 1,num_road_layers TGL_URB3D(I,K,J) = TGL_URB(K) + TVGL_URB3D(I,K,J) = TVGL_URB(K) + SMG_URB3D(I,K,J) = SMG_URB(K) END DO !sw++ TGR_URB2D(I,J) = TGR_URB @@ -60400,6 +60432,12 @@ subroutine clmdrv(zgcmxy ,forc_qxy ,ps ,forc_txy ,tsxy & DRELR_URB2D(I,J) = DRELR_URB DRELB_URB2D(I,J) = DRELB_URB DRELG_URB2D(I,J) = DRELG_URB + TVG_URB2D(I,J)=TVG_URB + TT_URB2D(I,J)=TT_URB + XXXVG_URB2D(I,J)=XXXVG_URB + CMCG_URB2D(I,J)=CMCG_URB + FLXHUMVG_URB2D(I,J)=FLXHUMVG_URB + FLXHUMT_URB2D(I,J)=FLXHUMT_URB !sw-- XXXR_URB2D(I,J) = XXXR_URB XXXB_URB2D(I,J) = XXXB_URB diff --git a/phys/module_sf_noahdrv.F b/phys/module_sf_noahdrv.F index 21bced2f46..d5cec6d996 100644 --- a/phys/module_sf_noahdrv.F +++ b/phys/module_sf_noahdrv.F @@ -81,6 +81,9 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & !H urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !H urban FLXHUMR_URB2D,FLXHUMB_URB2D,FLXHUMG_URB2D, & !H urban + ! added by Chenghao Wang + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & !H urban + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !H urban julian, julyr, & !H urban FRC_URB2D,UTYPE_URB2D, & !O num_urban_ndm, & !I multi-layer urban @@ -518,17 +521,34 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & REAL :: TGR_URB REAL, DIMENSION(1:num_roof_layers) :: SMR_URB ! green roof layer moisture REAL, DIMENSION(1:num_roof_layers) :: TGRL_URB ! green roof layer temp [K] - + ! added by Chenghao Wang + REAL :: TVG_URB + REAL :: TT_URB + REAL :: XXXVG_URB + REAL :: CMCG_URB + REAL :: FLXHUMVG_URB + REAL :: FLXHUMT_URB + REAL, DIMENSION(1:num_road_layers) :: TVGL_URB ! vegetated ground layer temp [K] + REAL, DIMENSION(1:num_road_layers) :: SMG_URB ! vegetated ground layer moisture REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELB_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELG_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMB_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMG_URB2D + ! added by Chenghao Wang + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TGR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_roof_layers, jms:jme ), INTENT(INOUT) :: TGRL_URB3D REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_roof_layers, jms:jme ), INTENT(INOUT) :: SMR_URB3D + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_road_layers, jms:jme ), INTENT(INOUT) :: TVGL_URB3D + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_road_layers, jms:jme ), INTENT(INOUT) :: SMG_URB3D ! state variable surface_driver <--> lsm <--> urban @@ -1364,6 +1384,12 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & FLXHUMR_URB = FLXHUMR_URB2D(I,J) FLXHUMB_URB = FLXHUMB_URB2D(I,J) FLXHUMG_URB = FLXHUMG_URB2D(I,J) + TVG_URB = TVG_URB2D(I,J) + TT_URB = TT_URB2D(I,J) + XXXVG_URB = XXXVG_URB2D(I,J) + CMCG_URB = CMCG_URB2D(I,J) + FLXHUMVG_URB = FLXHUMVG_URB2D(I,J) + FLXHUMT_URB = FLXHUMT_URB2D(I,J) DRELR_URB = DRELR_URB2D(I,J) DRELB_URB = DRELB_URB2D(I,J) DRELG_URB = DRELG_URB2D(I,J) @@ -1378,6 +1404,8 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & END DO DO K = 1,num_road_layers TGL_URB(K) = TGL_URB3D(I,K,J) + TVGL_URB(K) = TVGL_URB3D(I,K,J) + SMG_URB(K) = SMG_URB3D(I,K,J) END DO XXXR_URB = XXXR_URB2D(I,J) @@ -1451,6 +1479,8 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & TGRL_URB,SMR_URB,CMGR_URB,CHGR_URB,jmonth, & ! H DRELR_URB,DRELB_URB, & ! H DRELG_URB,FLXHUMR_URB,FLXHUMB_URB,FLXHUMG_URB, & + ! added by Chenghao Wang + TVG_URB,TT_URB,XXXVG_URB,TVGL_URB,SMG_URB,CMCG_URB,FLXHUMVG_URB,FLXHUMT_URB, & lf_urb_s, z0_urb, vegfrac) #if 0 @@ -1526,6 +1556,12 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & FLXHUMR_URB2D(I,J)=FLXHUMR_URB FLXHUMB_URB2D(I,J)=FLXHUMB_URB FLXHUMG_URB2D(I,J)=FLXHUMG_URB + TVG_URB2D(I,J)=TVG_URB + TT_URB2D(I,J)=TT_URB + XXXVG_URB2D(I,J)=XXXVG_URB + CMCG_URB2D(I,J)=CMCG_URB + FLXHUMVG_URB2D(I,J)=FLXHUMVG_URB + FLXHUMT_URB2D(I,J)=FLXHUMT_URB DRELR_URB2D(I,J) = DRELR_URB DRELB_URB2D(I,J) = DRELB_URB DRELG_URB2D(I,J) = DRELG_URB @@ -1540,6 +1576,8 @@ SUBROUTINE lsm(DZ8W,QV3D,P8W3D,T3D,TSK, & END DO DO K = 1,num_road_layers TGL_URB3D(I,K,J) = TGL_URB(K) + TVGL_URB3D(I,K,J) = TVGL_URB(K) + SMG_URB3D(I,K,J) = SMG_URB(K) END DO XXXR_URB2D(I,J) = XXXR_URB XXXB_URB2D(I,J) = XXXB_URB @@ -2413,6 +2451,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & julian,julyr, & !H urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !H urban FLXHUMR_URB2D,FLXHUMB_URB2D,FLXHUMG_URB2D, & !H urban + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & !H urban + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !H urban FRC_URB2D,UTYPE_URB2D, & !O num_urban_ndm, & !I multi-layer urban urban_map_zrd, & !I multi-layer urban @@ -2850,6 +2890,15 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & REAL :: TGR_URB REAL, DIMENSION(1:num_roof_layers) :: SMR_URB ! green roof layer moisture REAL, DIMENSION(1:num_roof_layers) :: TGRL_URB ! green roof layer temp [K] + ! added by Chenghao Wang + REAL :: TVG_URB + REAL :: TT_URB + REAL :: XXXVG_URB + REAL :: CMCG_URB + REAL :: FLXHUMVG_URB + REAL :: FLXHUMT_URB + REAL, DIMENSION(1:num_road_layers) :: TVGL_URB ! vegetated ground layer temp [K] + REAL, DIMENSION(1:num_road_layers) :: SMG_URB ! vegetated ground layer moisture REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: DRELB_URB2D @@ -2857,10 +2906,18 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMB_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TGR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_roof_layers, jms:jme ), INTENT(INOUT) :: TGRL_URB3D REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_roof_layers, jms:jme ), INTENT(INOUT) :: SMR_URB3D + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_road_layers, jms:jme ), INTENT(INOUT) :: TVGL_URB3D + REAL, OPTIONAL, DIMENSION( ims:ime, 1:num_road_layers, jms:jme ), INTENT(INOUT) :: SMG_URB3D ! state variable surface_driver <--> lsm <--> urban REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TR_URB2D @@ -3826,6 +3883,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & END DO DO K = 1,num_road_layers TGL_URB(K) = TGL_URB3D(I,K,J) + TVGL_URB(K) = TVGL_URB3D(I,K,J) + SMG_URB(K) = SMG_URB3D(I,K,J) END DO TGR_URB = TGR_URB2D(I,J) @@ -3833,6 +3892,12 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & FLXHUMR_URB = FLXHUMR_URB2D(I,J) FLXHUMB_URB = FLXHUMB_URB2D(I,J) FLXHUMG_URB = FLXHUMG_URB2D(I,J) + TVG_URB = TVG_URB2D(I,J) + TT_URB = TT_URB2D(I,J) + XXXVG_URB = XXXVG_URB2D(I,J) + CMCG_URB = CMCG_URB2D(I,J) + FLXHUMVG_URB = FLXHUMVG_URB2D(I,J) + FLXHUMT_URB = FLXHUMT_URB2D(I,J) DRELR_URB = DRELR_URB2D(I,J) DRELB_URB = DRELB_URB2D(I,J) DRELG_URB = DRELG_URB2D(I,J) @@ -3907,6 +3972,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & TGRL_URB,SMR_URB,CMGR_URB,CHGR_URB,jmonth, & ! H DRELR_URB,DRELB_URB, & ! H DRELG_URB,FLXHUMR_URB,FLXHUMB_URB,FLXHUMG_URB, & + ! added by Chenghao Wang + TVG_URB,TT_URB,XXXVG_URB,TVGL_URB,SMG_URB,CMCG_URB,FLXHUMVG_URB,FLXHUMT_URB, & lf_urb_s, z0_urb, vegfrac) #if 0 @@ -3988,6 +4055,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & END DO DO K = 1,num_road_layers TGL_URB3D(I,K,J) = TGL_URB(K) + TVGL_URB3D(I,K,J) = TVGL_URB(K) + SMG_URB3D(I,K,J) = SMG_URB(K) END DO TGR_URB2D(I,J) =TGR_URB @@ -3995,6 +4064,12 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & FLXHUMR_URB2D(I,J)=FLXHUMR_URB FLXHUMB_URB2D(I,J)=FLXHUMB_URB FLXHUMG_URB2D(I,J)=FLXHUMG_URB + TVG_URB2D(I,J)=TVG_URB + TT_URB2D(I,J)=TT_URB + XXXVG_URB2D(I,J)=XXXVG_URB + CMCG_URB2D(I,J)=CMCG_URB + FLXHUMVG_URB2D(I,J)=FLXHUMVG_URB + FLXHUMT_URB2D(I,J)=FLXHUMT_URB DRELR_URB2D(I,J) = DRELR_URB DRELB_URB2D(I,J) = DRELB_URB DRELG_URB2D(I,J) = DRELG_URB @@ -4705,6 +4780,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & END DO DO K = 1,num_road_layers TGL_URB(K) = TGL_URB3D(I,K,J) + TVGL_URB(K) = TVGL_URB3D(I,K,J) + SMG_URB(K) = SMG_URB3D(I,K,J) END DO TGR_URB = TGR_URB2D(I,J) @@ -4712,6 +4789,12 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & FLXHUMR_URB = FLXHUMR_URB2D(I,J) FLXHUMB_URB = FLXHUMB_URB2D(I,J) FLXHUMG_URB = FLXHUMG_URB2D(I,J) + TVG_URB = TVG_URB2D(I,J) + TT_URB = TT_URB2D(I,J) + XXXVG_URB = XXXVG_URB2D(I,J) + CMCG_URB = CMCG_URB2D(I,J) + FLXHUMVG_URB = FLXHUMVG_URB2D(I,J) + FLXHUMT_URB = FLXHUMT_URB2D(I,J) DRELR_URB = DRELR_URB2D(I,J) DRELB_URB = DRELB_URB2D(I,J) DRELG_URB = DRELG_URB2D(I,J) @@ -4787,6 +4870,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & TGRL_URB,SMR_URB,CMGR_URB,CHGR_URB,jmonth, & ! H DRELR_URB,DRELB_URB, & ! H DRELG_URB,FLXHUMR_URB,FLXHUMB_URB,FLXHUMG_URB, & + ! added by Chenghao Wang + TVG_URB,TT_URB,XXXVG_URB,TVGL_URB,SMG_URB,CMCG_URB,FLXHUMVG_URB,FLXHUMT_URB, & lf_urb_s, z0_urb, vegfrac) #if 0 @@ -4865,6 +4950,8 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & END DO DO K = 1,num_road_layers TGL_URB3D(I,K,J) = TGL_URB(K) + TVGL_URB3D(I,K,J) = TVGL_URB(K) + SMG_URB3D(I,K,J) = SMG_URB(K) END DO TGR_URB2D(I,J) =TGR_URB @@ -4872,6 +4959,12 @@ SUBROUTINE lsm_mosaic(DZ8W,QV3D,P8W3D,T3D,TSK, & FLXHUMR_URB2D(I,J)=FLXHUMR_URB FLXHUMB_URB2D(I,J)=FLXHUMB_URB FLXHUMG_URB2D(I,J)=FLXHUMG_URB + TVG_URB2D(I,J)=TVG_URB + TT_URB2D(I,J)=TT_URB + XXXVG_URB2D(I,J)=XXXVG_URB + CMCG_URB2D(I,J)=CMCG_URB + FLXHUMVG_URB2D(I,J)=FLXHUMVG_URB + FLXHUMT_URB2D(I,J)=FLXHUMT_URB DRELR_URB2D(I,J) = DRELR_URB DRELB_URB2D(I,J) = DRELB_URB DRELG_URB2D(I,J) = DRELG_URB diff --git a/phys/module_sf_urban.F b/phys/module_sf_urban.F index a25e7d899c..c49b9c31fe 100644 --- a/phys/module_sf_urban.F +++ b/phys/module_sf_urban.F @@ -8,9 +8,7 @@ MODULE module_sf_urban #define FATAL_ERROR(M) call wrf_error_fatal( M ) #define WRITE_MESSAGE(M) call wrf_message( M ) #endif - -USE module_model_constants, ONLY : piconst - +use module_model_constants, only : piconst !=============================================================================== ! Single-Layer Urban Canopy Model for WRF Noah-LSM ! Original Version: 2002/11/06 by Hiroyuki Kusaka @@ -65,7 +63,9 @@ MODULE module_sf_urban REAL, ALLOCATABLE, DIMENSION(:) :: Z0HB_TBL, Z0HG_TBL REAL, ALLOCATABLE, DIMENSION(:) :: TRLEND_TBL, TBLEND_TBL, TGLEND_TBL REAL, ALLOCATABLE, DIMENSION(:) :: AKANDA_URBAN_TBL + !for BEP + ! MAXDIRS :: The maximum number of street directions we're allowed to define INTEGER, PARAMETER :: MAXDIRS = 3 ! MAXHGTS :: The maximum number of building height bins we're allowed to define @@ -99,12 +99,25 @@ MODULE module_sf_urban REAL, DIMENSION(1:3) :: dengimp ! maximum water-holding depth of pavement !===end hydrological processes=== - - INTEGER :: allocate_status -! INTEGER :: num_roof_layers -! INTEGER :: num_wall_layers -! INTEGER :: num_road_layers +! + +!===Huang and Wang, 2025/12/28, urban nature-based solutions for single layer UCM (including trees)=== + INTEGER :: TREEOPTION ! Urban Tree&Vegetation Option ! add by yuqi + REAL :: fvg_data = 0.0 ! vegetated ground fraction from URBPARM + REAL, ALLOCATABLE, DIMENSION(:) :: RTREE_TBL ! Tree crown radius [normalized] + REAL, ALLOCATABLE, DIMENSION(:) :: RTREE_M_TBL ! Tree crown radius in meter + REAL, ALLOCATABLE, DIMENSION(:) :: RW_M_TBL ! Road width in meter + REAL, ALLOCATABLE, DIMENSION(:) :: HTREE_TBL ! Tree crown center height [normalized] + REAL, ALLOCATABLE, DIMENSION(:) :: DTREE_TBL ! Tree crown center distance from wall (half canyon width currently) [normalized] + REAL, ALLOCATABLE, DIMENSION(:) :: LAI_TREE_TBL ! Tree leaf area index + REAL, ALLOCATABLE, DIMENSION(:) :: LAI_VEG_TBL ! Vegetated ground leaf area index + REAL, ALLOCATABLE, DIMENSION(:) :: Z0VG_TBL ! Roughness length for momentum of vegetated ground + REAL, ALLOCATABLE, DIMENSION(:) :: Z0HVG_TBL ! Roughness length for heat of vegetated ground + REAL, ALLOCATABLE, DIMENSION(:) :: CAPVG_TBL ! Heat capacity of vegetated ground + REAL, ALLOCATABLE, DIMENSION(:) :: EPSVG_TBL ! Emissivity of vegetated ground + REAL, ALLOCATABLE, DIMENSION(:) :: EPST_TBL ! Emissivity of tree canopy +!===end urban nature-based solutions processes=== CHARACTER (LEN=256) , PRIVATE :: mesg @@ -289,6 +302,7 @@ MODULE module_sf_urban ! Kusaka et al. (2001) Bound.-Layer Meteor., vol.101, p329-358 ! ! History: +! 2025/11, modified by Yuqi Huang, Chenghao Wang (Univ. Oklahoma) [urban nature-based solutions, including trees] ! 2014/10, modified by Jiachuan Yang (ASU) ! 2006/06 modified by H. Kusaka (Univ. Tsukuba), M. Tewari ! 2005/10/26, modified by Fei Chen, Mukul Tewari @@ -319,24 +333,128 @@ SUBROUTINE urban(LSOLAR, & ! L lp_urb,hgt_urb,frc_urb,lb_urb,zo_check, & ! O CMCR,TGR,TGRL,SMR,CMGR_URB,CHGR_URB,jmonth, & ! H DRELR,DRELB,DRELG,FLXHUMR,FLXHUMB,FLXHUMG, & - lf_urb_s, z0_urb, vegfrac_in) - + ! added by Chenghao Wang + TVG,TT,XXXVG,TVGL,SMG,CMCG,FLXHUMVG,FLXHUMT, & ! H (add by huang) + lf_urb_s, z0_urb, vegfrac_in & ! I (distributed aerodynamics) + ) IMPLICIT NONE - REAL, PARAMETER :: CP=0.24 ! heat capacity of dry air [cgs unit] - REAL, PARAMETER :: EL=583. ! latent heat of vaporation [cgs unit] - REAL, PARAMETER :: SIG=8.17E-11 ! stefun bolzman constant [cgs unit] - REAL, PARAMETER :: SIG_SI=5.67E-8 ! [MKS unit] + REAL, PARAMETER :: CP=0.24 ! heat capacity of dry air [cgs unit] ! cal/g/c (yuqi) + REAL, PARAMETER :: EL=583. ! latent heat of vaporization [cgs unit] ! cal/g (yuqi) + REAL, PARAMETER :: SIG=8.17E-11 ! stefun bolzman constant [cgs unit] ! cal/cm^2/min/k^4 + REAL, PARAMETER :: SIG_SI=5.67E-8 ! [MKS unit] ! w/m2/k^4 (yuqi) REAL, PARAMETER :: AK=0.4 ! kalman const. [-] REAL, PARAMETER :: PI=3.14159 ! pi [-] REAL, PARAMETER :: TETENA=7.5 ! const. of Tetens Equation [-] REAL, PARAMETER :: TETENB=237.3 ! const. of Tetens Equation [-] REAL, PARAMETER :: SRATIO=0.75 ! ratio between direct/total solar [-] - REAL, PARAMETER :: CPP=1004.5 ! heat capacity of dry air [J/K/kg] REAL, PARAMETER :: ELL=2.442E+06 ! latent heat of vaporization [J/kg] REAL, PARAMETER :: XKA=2.4E-5 +! ----------------------------------- Newly Define Urban Vegetation (NbS) Related Variables (Yuqi) ------------------------------------- + !------------------------------------------------------------------------------- + ! H: Historical (state) variables of Urban : LSM <--> Urban + !------------------------------------------------------------------------------- + ! added by Chenghao Wang + REAL, INTENT(INOUT):: TVG ! Vegetated Ground Temperature (At Previous Time Step) [K] + REAL, INTENT(INOUT):: TT ! Tree Temperature (At Previous Time Step) [K] + REAL, INTENT(INOUT):: XXXVG ! Monin-Obkhov length for Vegetated Ground [dimensionless] + REAL, DIMENSION(1:num_road_layers), INTENT(INOUT):: TVGL ! Vegetated Ground Temperature (multi_layer approach) + REAL, DIMENSION(1:num_road_layers), INTENT(INOUT) :: SMG ! Soil Moisture at Each Layer on Vegetated Ground [-] + REAL, INTENT(INOUT):: CMCG ! Canopy Intercepted Water on Vegetated Ground + REAL, INTENT(INOUT):: FLXHUMVG, FLXHUMT ! Evaporation Over Vegetated Ground and Tree + !------------------------------------------------------------------------------- + ! L: Local variables + !------------------------------------------------------------------------------- + REAL :: TVGP, TTP ! Temperature at Pervious Time Step + REAL :: ALBGE ! Effective Surface Albedo of Ground + REAL :: ALBVG ! Surface Albedo of Vegetated Ground + REAL :: XI ! Tree Shadow Related Variable + REAL :: ANGLE, TAN1, TAN2 ! Reference Angles Between Tree and Roof + REAL :: SDT ! Direct Short Wave Radiation incident on Tree + REAL :: SDG ! Direct Short Wave Radiation incident on Ground + REAL :: SDB ! Direct Short Wave Radiation incident on Wall + REAL :: TAU ! Transmittance of Tree Crown + REAL :: SVG, SVG1, SVG2, ST, ST1, ST2 ! Short Wave Radiation Absorbed by Vegetated Ground and Tree + REAL :: SLEAF ! Short Wave Radiation Absorbed by Tree Averaged by Leaf Area + REAL :: CHI_SHADED, CHI_SHADED_TREE ! Shadow Length on the Ground Casted by Wall/Tree + REAL :: ETA_SHADED, ETA_SHADED_TREE ! Shadow Length on the Wall Casted by Wall/Tree + REAL :: VFWS_TREE,VFWW_TREE,VFTS_TREE,VFWT_TREE,VFGS_TREE,VFWG_TREE,VFGW_TREE,VFGT_TREE,VFTW_TREE,VFTG_TREE ! urban tree view factor related + REAL :: BHVG, RIBVG + REAL :: ALPHAVG + REAL :: CHVG ! Local Bulk Transfer Coef for Heat For Vegetated Ground + REAL :: CDVG ! Local Bulk Transfer Coef for Momentum For Vegetated Ground + REAL :: SRUN1 ! Surface Runoff for Vegetated Ground (Infiltration Excess) + REAL :: SRUN2 ! Subsurface runoff for 2nd soil layer + REAL :: SRUN3 ! Runoff Within Soil Layers + REAL, DIMENSION(1:num_road_layers) :: ZSOILG ! Total Depth of Vegetated Ground (Negative) [m], (Accumulated From Surface) + REAL, DIMENSION(1:num_road_layers) :: SMGP ! Soil Moisture at Each Layer on Vegetated Ground at Pervious Time Step + REAL, DIMENSION(1:num_road_layers) :: ETG ! Vegetated Canopy Evapotranspiration + REAL, DIMENSION(1:num_road_layers) :: DZVG ! Depth of Each Single Layer (Positive)[m] ! This Could be an Input Variable (yuqi) + REAL :: QS0VG, DQS0VGDTVG, QS0T, DQS0TDTT ! Saturation QS and derivative for vegetated ground/tree + REAL :: EPVG ! Potential Evaporation For Vegetated Ground [kg/m2/s] + REAL :: EDIRG ! Direct Evaporation From Vegetated Ground + REAL :: ETTG ! Vegetated Canopy Evapotranspiration + REAL :: ECG ! Evaporation from Canopy Interception + REAL :: ETAG ! Actual(Total) ET For Vegetated Ground + REAL :: DRIPG ! Canopy Drippage Into the Ground + REAL :: BETVG ! Reduction Factor for Calculating Latent Heat Flux + REAL :: VFAC ! Vegetation Fraction + REAL :: EMITW,EMITG,EMITT ! Emitted Longwave Radiation From One Wall/Ground/Tree + REAL :: EPSGE ! Effective Surface Emissivity of Ground + REAL :: RVG1,RVG2,RVG,RT1,RT2,RT ! Longwave Radiation Received by Vegetated Ground/Tree + REAL :: RLEAF ! Longwave Radiation Received by Tree averaged by Leaf Area + REAL(Kind = 8) :: DRBDTVG1,DRBDTVG2,DRBDTT1,DRBDTT2,DRGDTVG1,DRGDTVG2,DRGDTT1,DRGDTT2,DRVGDTB1,DRVGDTB2,DRVGDTVG1,DRVGDTVG2 ! derivatives wrt temperature (radiation) + REAL(Kind = 8) :: DRVGDTG1,DRVGDTG2,DRVGDTT1,DRVGDTT2,DRTDTB1,DRTDTB2,DRTDTG1,DRTDTG2,DRTDTVG1,DRTDTVG2,DRTDTT1,DRTDTT2 ! derivatives wrt temperature (radiation) + REAL(Kind = 8) :: DRBDTVG,DRBDTT,DRGDTVG,DRGDTT,DRVGDTB,DRVGDTG,DRVGDTVG,DRVGDTT,DRTDTB,DRTDTG,DRTDTVG,DRTDTT ! derivatives wrt temperature (radiation) + REAL(Kind = 8) :: DHBDTVG,DHBDTT,DHGDTVG,DHGDTT,DHVGDTB,DHVGDTG,DHVGDTVG,DHVGDTT,DHTDTB,DHTDTG,DHTDTVG,DHTDTT ! derivatives wrt temperature (sensible heat) + REAL :: HVG ! Sensible Heat Flux by Vegetated Ground + REAL :: HT ! Sensible Heat Flux by Tree + REAL :: RA_LEAF ! Leaf Boundary Layer Resistent (Empirical Calculated) + REAL :: ALPHAT ! sensible heat transfer coefficient for urban trees + REAL :: W2 ! Deep Soil Moisture + REAL :: RS_LEAF ! Leaf Stomatal Resistance + REAL :: ELET ! Latent Heat of Tree Leaf ! w/m/m (yuqi) + REAL :: AVAILABLE_WATER_SUM, POTENTIAL_ELET ! newly added by yuqi + REAL :: QS0C ! Saturation specific humidity at canyon air temperature + CHARACTER(LEN=256) :: WARN_MSG ! A character string for the warning message + REAL, DIMENSION(1:num_road_layers) :: SROOT, SROOTP ! Root Water Uptake (m/s) + REAL :: DES,MIX,DMIX,QSAT,DQSAT,ESAT,DESAT,DELEBDTVG,DELEBDTT,DELEGDTVG,DELEGDTT,DELEVGDTB,DELEVGDTG ! derivatives wrt humidity/saturation + REAL(Kind = 8) :: DRS_LEAF, M,D,DD,FE,DFE,S,DM,KK,L,N + REAL(Kind = 8) :: DELEVGDTVG,DELEVGDTT,DELETDTB,DELETDTG,DELETDTVG,DELETDTT,DTCDTVG,DTCDTT ! derivatives wrt temperature (latent heat) + REAL :: DQCDTVG,DQCDTT,ELEVG,KVG,G0VG,DG0BDTVG,DG0BDTT,DG0GDTVG,DG0GDTT,DG0VGDTB,DG0VGDTG,DG0VGDTVG,DG0VGDTT ! derivatives wrt temperature + REAL(Kind = 8) :: WF,A,B,C,E,FF,GG,H,VGF,I,J,O,P,CHARA,det,det_tol,det_scale !,RVGT + REAL(Kind = 8) :: A_use,FF_use,KK_use,lambda,relax + REAL :: max_step + REAL :: SSOILG ! Soil Heat Flux output from SHFLX W/m2 + REAL :: TGE, TGEP, QS0GE, ALPHAGE, FLXTHVG, FLXTHT ! effective ground values + REAL :: CMCGP ! Canopy Intercepted Water on Vegetated Ground + !----------- fixed universe parameters for urban vegetation --------------- + INTEGER, PARAMETER :: NVG = 4 ! Total Layer of Vegetated Ground + REAL, PARAMETER :: CPP=1004.5 ! heat capacity of dry air [J/K/kg] + REAL, PARAMETER :: ALBT = 0.2 ! Leaf Surface Albedo + REAL, PARAMETER :: DLEAF = 0.1 ! Unit = m + REAL, PARAMETER :: TREF = 298.0 ! Unit = K + REAL, PARAMETER :: EREF = 3167.0 ! Unit = K + + !----------- local variables from read_para (Yuqi) --------------- + REAL :: FVG ! Vegetated Fraction for Ground + REAL :: Z0VG ! Roughness Length for Momentum of Vegetated Ground + REAL :: Z0HVG ! Roughness Length for Heat of Vegetated Ground + REAL :: CAPVG ! Heat Capacity of Vegetated Ground + REAL :: EPSVG ! Vegetated Ground Emissivity + REAL :: EPST ! Tree Emissivity + REAL :: RTREE ! Radius of Tree Crown Center + REAL :: RTREE_M ! Radius of Tree Crown Center in meters + REAL :: RW_M ! road width in meters + REAL :: DTREE ! Distance of Tree Crown Center From Wall (RW/2) + REAL :: HTREE ! Height of Tree Crown Center + REAL :: LAI_VEG ! Vegetated Ground Leaf Areal Index + REAL :: LAI_TREE ! Leaf Area Index of Trees (Could be an input) +! -------------------------------------End Urban Vegetation Variable Define----------------------------------------------------------------------------------------------------- + + !------------------------------------------------------------------------------- ! C: configuration variables !------------------------------------------------------------------------------- @@ -379,7 +497,7 @@ SUBROUTINE urban(LSOLAR, & ! L REAL, INTENT(IN) :: XLAT ! latitude [deg] REAL, INTENT(IN) :: DELT ! time step [s] - REAL, INTENT(IN) :: CHS,CHS2 ! CH*U at za and 2 m [m/s] + REAL, INTENT(INOUT) :: CHS,CHS2 ! CH*U at za and 2 m [m/s] REAL, INTENT(INOUT) :: SSGD ! downward direct short wave radiation [W/m/m] REAL, INTENT(INOUT) :: SSGQ ! downward diffuse short wave radiation [W/m/m] @@ -393,7 +511,7 @@ SUBROUTINE urban(LSOLAR, & ! L !------------------------------------------------------------------------------- REAL, INTENT(INOUT) :: mh_urb ! mean building height [m] REAL, INTENT(INOUT) :: stdh_urb ! standard deviation of building height [m] - REAL, INTENT(INOUT) :: hgt_urb ! area weighted mean building height [m] + REAL, INTENT(INOUT) :: hgt_urb ! area weighted mean building height [m] ! if hgt_urb>0 use NUDAPT else use default urban parameter table (yuqi) REAL, INTENT(INOUT) :: lp_urb ! plan area fraction [-] REAL, INTENT(INOUT) :: frc_urb ! urban fraction [-] REAL, INTENT(INOUT) :: lb_urb ! building surface to plan area ratio [-] @@ -540,7 +658,7 @@ SUBROUTINE urban(LSOLAR, & ! L REAL :: DELEBDTB, DELEBDTG, DELEGDTG, DELEGDTB REAL :: DG0BDTB, DG0BDTG, DG0GDTG, DG0GDTB REAL :: DQS0BDTB, DQS0GDTG - REAL :: DTB, DTG, DTC + REAL :: DTB, DTG, DTC, DTVG, DTT REAL :: THEATAZ ! Solar Zenith Angle [rad] REAL :: THEATAS ! = PI/2. - THETAZ @@ -553,7 +671,7 @@ SUBROUTINE urban(LSOLAR, & ! L REAL :: XXX2, PSIM2, PSIH2, XXX10, PSIM10, PSIH10 REAL :: PSIX, PSIT, PSIX2, PSIT2, PSIX10, PSIT10 - REAL :: TRP, TBP, TGP, TCP, QCP, TST, QST + REAL :: TRP, TBP, TGP, TCP, QCP, TST, QST ! TCP is local variable ? (yuqi) REAL :: TSP, CHS_LOCAL, CHS2_LOCAL REAL :: WDR,HGT2,BW,DHGT @@ -578,7 +696,7 @@ SUBROUTINE urban(LSOLAR, & ! L ! REAL :: DQS0GRDTGR, ETR, ECR,RAIN1, RAINDR, DEW, ETAR, BETGR REAL :: DQS0GRDTGR, ECR,RAIN1, RAINDR, DEW, ETAR, BETGR ! REAL :: DF1, RGR, RGRR, RCH, RR1, RR2, YY, ZZ1, SSOILR - REAL :: DF1, RGR, RGRR, RCH, YY, ZZ1, SSOILR + REAL :: DF1, RGR, RGRR, RCH, YY, ZZ1, SSOILR, RVGT !(RVGT add by yuqi) REAL :: DRRDTGR, DHRDTGR, DELERDTGR, DG0RDTGR, DFDVT real,parameter :: SHDFAC = 0.80 ! Vegetated area fraction of green roof vegetation real,parameter :: ALBV = 0.20 ! green roof albedo @@ -607,14 +725,9 @@ SUBROUTINE urban(LSOLAR, & ! L integer,parameter :: IMPB = 2 integer,parameter :: IMPG = 3 - SHADOW = .false. -! SHADOW = .true. - IF (distributed_aerodynamics_option .and. groption == 1) THEN FATAL_ERROR("slucm_distributed_drag is not compatible with groption") - END IF - - + END IF !------------------------------------------------------------------------------- ! Set parameters !------------------------------------------------------------------------------- @@ -632,21 +745,24 @@ SUBROUTINE urban(LSOLAR, & ! L if(tloc2==0) tloc2=48 endif - CALL read_param(UTYPE,ZR,SIGMA_ZED,Z0C,Z0HC,ZDC,SVF,R,RW,HGT, & - AH,CAPR,CAPB,CAPG,AKSR,AKSB,AKSG,ALBR,ALBB, & - ALBG,EPSR,EPSB,EPSG,Z0R,Z0B,Z0G,Z0HB,Z0HG, & - BETR,BETB,BETG,TRLEND,TBLEND,TGLEND, & + CALL read_param(UTYPE,ZR,SIGMA_ZED,Z0C,Z0HC,ZDC,SVF,R,RW,HGT, & + AH,CAPR,CAPB,CAPG,AKSR,AKSB,AKSG,ALBR,ALBB, & + ALBG,EPSR,EPSB,EPSG,Z0R,Z0B,Z0G,Z0HB,Z0HG, & + BETR,BETB,BETG,TRLEND,TBLEND,TGLEND, & + RTREE,RTREE_M,RW_M,HTREE,DTREE,LAI_TREE,LAI_VEG, & ! added by yuqi + Z0VG,Z0HVG,CAPVG,EPSVG,EPST, & ! added by yuqi !for BEP NUMDIR, STREET_DIRECTION, STREET_WIDTH, & BUILDING_WIDTH, NUMHGT, HEIGHT_BIN, & - HPERCENT_BIN, & + HPERCENT_BIN, & !end BEP - BOUNDR,BOUNDB,BOUNDG,CH_SCHEME,TS_SCHEME, & - AKANDA_URBAN,ALH) + BOUNDR,BOUNDB,BOUNDG,CH_SCHEME,TS_SCHEME, & + AKANDA_URBAN,ALH) + FVG = FVG_DATA ! Glotfelty, 2012/07/05, NUDAPT Modification - if (mh_urb.gt.0.0 .and. .not. distributed_aerodynamics_option) THEN + if(mh_urb.gt.0.0 .and. .not. distributed_aerodynamics_option)THEN !write(mesg,*) 'Mean Height NUDAPT',mh_urb !WRITE_MESSAGE(mesg) !write(mesg,*) 'Mean Height Table',ZR @@ -683,7 +799,7 @@ SUBROUTINE urban(LSOLAR, & ! L !WRITE_MESSAGE(mesg) !Calculate Building Width and Street Width Based on BEP formulation - if(lb_urb.gt.lp_urb)THEN + if(lb_urb.gt.lp_urb)THEN ! building surface to plan area ratio > plain area fraction (yuqi) BW=2.*hgt_urb*lp_urb/(lb_urb-lp_urb) SW=2.*hgt_urb*lp_urb*((frc_urb/lp_urb)-1.)/(lb_urb-lp_urb) !write(mesg,*) 'Building Width',BW @@ -694,7 +810,7 @@ SUBROUTINE urban(LSOLAR, & ! L BW=BUILDING_WIDTH(1) SW=STREET_WIDTH(1) else - BW=BUILDING_WIDTH(1) + BW=BUILDING_WIDTH(1) SW=STREET_WIDTH(1) end if @@ -738,10 +854,10 @@ SUBROUTINE urban(LSOLAR, & ! L beta_macd = 1.0 - ZDC = ZR * ( 1.0 + ( alpha_macd ** ( -R ) ) * ( R - 1.0 ) ) + ZDC = ZR * ( 1.0 + ( alpha_macd ** ( -R ) ) * ( R - 1.0 ) ) ! e.q 23 in Macdonald's (1998) (yuqi) Z0C = ZR * ( 1.0 - ZDC/ZR ) * & - exp (-(0.5 * beta_macd * Cd / (VonK**2) * ( 1.0-ZDC/ZR) * lambda_f )**(-0.5)) + exp (-(0.5 * beta_macd * Cd / (VonK**2) * ( 1.0-ZDC/ZR) * lambda_f )**(-0.5)) ! e.q 26 in Macdonald's (1998) (yuqi) if(zo_check.eq.1)THEN write(mesg,*) 'Roughness Length NUDAPT',Z0C @@ -789,7 +905,6 @@ SUBROUTINE urban(LSOLAR, & ! L !End NUDAPT Modification - ! Miao, 2007/01/17, cal. ah if(ahoption==1) AH=AH*ahdiuprf(tloc) @@ -845,11 +960,11 @@ SUBROUTINE urban(LSOLAR, & ! L ! Renew surface and layer temperatures !------------------------------------------------------------------------------- - SX=(SSGD+SSGQ)/697.7/60. ! downward short wave radition [ly/min] + SX=(SSGD+SSGQ)/697.7/60. ! downward short wave radition [ly/s] or [cal/cm2/s] - Chenghao Wang SD=SSGD/697.7/60. ! downward direct short wave radiation SQ=SSGQ/697.7/60. ! downward diffuse short wave radiation RX=LLG/697.7/60. ! downward long wave radiation - RHO=RHOO*0.001 ! air density at first atmospheric level + RHO=RHOO*0.001 ! air density at first atmospheric level [g/cm3] TRP=TR TBP=TB @@ -857,8 +972,9 @@ SUBROUTINE urban(LSOLAR, & ! L TCP=TC QCP=QC - TSP = (TR * R + TB * W + TG * RW) / (R + RW + W) + TSP = (TR * R + TB * W + TG * RW) / (R + RW + W) ! for force-restore chw + !===Yang,2014/10/08, urban hydrological variables for single layer UCM=== FLXHUMRP = FLXHUMR FLXHUMBP = FLXHUMB @@ -885,6 +1001,13 @@ SUBROUTINE urban(LSOLAR, & ! L TAV=TA*(1.+0.61*QA) PS=RHOO*287.*TAV/100. ![hPa] + ! ===Yuqi Huang, 2024/07, urban tree & vegetation variables for UCM based on ASLUM + TVGP = TVG + TGEP = TGE + CMCGP = CMCG + SMGP = SMG + TTP = TT + SROOTP = SROOT !------------------------------------------------------------------------------- ! Canopy wind !------------------------------------------------------------------------------- @@ -894,7 +1017,11 @@ SUBROUTINE urban(LSOLAR, & ! L ZC=0.7*ZR XLB=0.4*(ZR-ZDC) ! BB formulation from Inoue (1963) +! #ifdef DOUBLE_PRECISION ! dlog is newly added (yuqi) - code follows HRLDAS (2025 summer) +! BB = 0.4 * ZR / ( XLB * dlog( ( ZR - ZDC ) / Z0C ) ) +! #else BB = 0.4 * ZR / ( XLB * alog( ( ZR - ZDC ) / Z0C ) ) +! #endif UC=UR*EXP(-BB*(1.-ZC/ZR)) ELSE ! PRINT *, 'Warning ZR + 2m is larger than the 1st WRF level' @@ -906,21 +1033,14 @@ SUBROUTINE urban(LSOLAR, & ! L ! Net Short Wave Radiation at roof, wall, and road !------------------------------------------------------------------------------- - IF (SSG > 0.0) THEN - - IF(.NOT.SHADOW) THEN ! no shadow effects model - - SR1=SX*(1.-ALBR) - SGR1=SX*(1.-ALBV) - SG1=SX*VFGS*(1.-ALBG) - SB1=SX*VFWS*(1.-ALBB) - SG2=SB1*ALBB/(1.-ALBB)*VFGW*(1.-ALBG) - SB2=SG1*ALBG/(1.-ALBG)*VFWG*(1.-ALBB) + SB1*ALBB*VFWW + SHADOW = .true. +! SHADOW = .false. +! SHADOW has not been activated in previous versions of SLUCM (chenghao) - it's not turned on - ELSE ! shadow effects model + IF (SSG > 0.0) THEN + IF(SHADOW) THEN ! shadow effects, calculate SLX FAI=XLAT*PI/180. - THEATAS=ABS(ASIN(COSZ)) THEATAZ=ABS(ACOS(COSZ)) @@ -955,33 +1075,112 @@ SUBROUTINE urban(LSOLAR, & ! L IF(SLX8 > RW) SLX8=RW SLX=(SLX1+SLX2+SLX3+SLX4+SLX5+SLX6+SLX7+SLX8)/8. + END IF + + IF(.NOT.SHADOW) THEN ! no shadow effects model + + SR1=SX*(1.-ALBR) + SGR1=SX*(1.-ALBV) + SG1=SX*VFGS*(1.-ALBG) + SB1=SX*VFWS*(1.-ALBB) + SG2=SB1*ALBB/(1.-ALBB)*VFGW*(1.-ALBG) + SB2=SG1*ALBG/(1.-ALBG)*VFWG*(1.-ALBB) + SB1*ALBB*VFWW ! add one term in the new version (yuqi) + + ELSEIF (TREEOPTION .ne. 1) THEN ! shadow effects model without urban vegetations SR1=SD*(1.-ALBR)+SQ*(1.-ALBR) SGR1=SD*(1.-ALBV)+SQ*(1.-ALBV) SG1=SD*(RW-SLX)/RW*(1.-ALBG)+SQ*VFGS*(1.-ALBG) SB1=SD*SLX/W*(1.-ALBB)+SQ*VFWS*(1.-ALBB) SG2=SB1*ALBB/(1.-ALBB)*VFGW*(1.-ALBG) - SB2=SG1*ALBG/(1.-ALBG)*VFWG*(1.-ALBB) + SB1*ALBB*VFWW + SB2=SG1*ALBG/(1.-ALBG)*VFWG*(1.-ALBB) + SB1*ALBB*VFWW ! newly added last term (Huang) + ELSE ! shadow effects model with urban vegetations (Huang) + ! ------------------------------------------------------------------------------------------------------------------ + ! tree module only activated under shadow case + ! ------------------------------------------------------------------------------------------------------------------ + IF ( HTREE+RTREE .gt. ZR) THEN ! add by Huang + FATAL_ERROR("tree crown protrude roof height, adjust tree size") + END IF + + ALBGE = (1. - FVG) * ALBG + FVG * ALBVG + XI = SLX/HGT ! check if XI matches with our ucm, (yuqi) + + ANGLE = DTREE**2. + (HGT - HTREE)**2. - RTREE**2. + TAN1 = (RTREE * (HGT-HTREE) + DTREE * SQRT(ANGLE))/((HGT - HTREE) * SQRT(ANGLE) - RTREE * DTREE) + TAN2 = (-RTREE * (HGT-HTREE) + DTREE * SQRT(ANGLE))/((HGT - HTREE) * SQRT(ANGLE) + RTREE * DTREE) + + IF (THEATAZ > PI/2.) THEN ! no SW radiation during night + SDT = 0 + SDG = 0 + SDB = 0 + ELSEIF (XI .ge. TAN1) THEN ! direct SW incident on tree + SDT = 0 + ELSEIF (XI .ge. TAN2 .and. XI .lt. TAN1) THEN ! tree partillay illuminated + SDT = SD * (RTREE * SQRT(1 + XI**2.) + DTREE - (HGT - HTREE) * XI)/(2. * PI * RTREE) + ELSE ! XI <= tan2 in the sun - completely illuminated + SDT = SD * (2. * RTREE * SQRT(1. + XI**2.))/(2. * PI * RTREE) + END IF + print*, 'THEATAZ is:', THEATAZ ! add by yuqi for testing purpose + + TAU = EXP(-0.61 * LAI_TREE) + CALL SHADOW_TREE(XI, HGT, RW, HTREE, RTREE, DTREE, CHI_SHADED, ETA_SHADED, CHI_SHADED_TREE, ETA_SHADED_TREE) + ! print*, 'road weidth, building height, tree height, tree radius are:', RW, HGT, HTREE, RTREE ! add by yuqi for testing purpose + CALL VF_TREE_ANALYTICAL(RW, HGT, HTREE, RTREE, TAU, VFGS_TREE, VFGW_TREE, VFGT_TREE, VFWS_TREE, VFWG_TREE, VFWW_TREE, VFWT_TREE, VFTS_TREE, VFTG_TREE, VFTW_TREE) + + SDG = SD * (RW - CHI_SHADED + CHI_SHADED_TREE * TAU)/RW + SDB = SD * XI * (HGT - ETA_SHADED +ETA_SHADED_TREE * TAU)/W + + SR1 = SD * (1. - ALBR) + SQ * (1. - ALBR) ! SAME AS NO TREE OPTION + SGR1= SD * (1. - ALBV) + SQ * (1. - ALBV) + SB1 = (SDB + SQ * VFWS_TREE) * (1. - ALBB) + SB2 = (SDB + SQ * VFWS_TREE) * ALBB * VFWW_TREE * (1 - ALBB) + & + (SDT + SQ * VFTS_TREE) * ALBT * VFWT_TREE * (1 - ALBB) + & + (SDG + SQ * VFGS_TREE) * ALBGE* VFWG_TREE * (1 - ALBB) + SG1 = (SDG + SQ * VFGS_TREE) * (1 - ALBG) + SG2 = 2. * (SDB + SQ * VFWS_TREE) * ALBB * VFGW_TREE * (1 - ALBG) + & + (SDT + SQ * VFTS_TREE) * ALBT * VFGT_TREE * (1 - ALBG) + SVG1= (SDG + SQ * VFGS_TREE) * (1 - ALBVG) + SVG2 = 2. * (SDB + SQ * VFWS_TREE) * ALBB * VFGW_TREE * (1 - ALBVG) + & + (SDT + SQ * VFTS_TREE) * ALBT * VFGT_TREE * (1 - ALBVG) + ST1 = (SDT + SQ * VFTS_TREE) * (1- ALBT) + ST2 = 2. * (SDB + SQ * VFWS_TREE) * ALBB * VFTW_TREE *(1 - ALBT) + & + (SDG + SQ * VFGS_TREE) * ALBG * VFTG_TREE * (1 - ALBT) END IF - SR=SR1 + SR=SR1 ! units: [cal/cm2/s] SGR=SGR1 SG=SG1+SG2 + SVG=SVG1+SVG2 ! Huang SB=SB1+SB2 - IF (GROPTION ==1) THEN - SNET=R*FGR*SGR+R*(1.-FGR)*SR+W*SB+RW*SG + IF (TREEOPTION == 1) THEN + ST = (ST1 + ST2) * 2. * PI * RTREE * (1 - TAU) ! unit: [cal/cm2/s] + SLEAF = (ST / (2. * RTREE * LAI_TREE)) *697.7*60. ! unit: [w/m/m] + ELSE + ST = 0 + END IF + + + IF (GROPTION ==1 .and. TREEOPTION .ne. 1) THEN + SNET=R*FGR*SGR+R*(1.-FGR)*SR+W*SB+RW*SG+ST + ELSEIF (TREEOPTION == 1 .and. GROPTION .ne. 1) THEN + SNET=R*SR+W*SB+(1.-FVG)*RW*SG+FVG*RW*SVG+ST + ELSEIF (TREEOPTION == 1 .and. GROPTION ==1) THEN + SNET=R*FGR*SGR+R*(1.-FGR)*SR+W*SB+(1.-FVG)*RW*SG+FVG*RW*SVG+ST ELSE - SNET=R*SR+W*SB+RW*SG + SNET=R*SR+W*SB+RW*SG+ST ENDIF + ELSE SR=0. SG=0. SGR=0. + SVG=0. SB=0. + ST=0. SNET=0. END IF @@ -1032,9 +1231,9 @@ SUBROUTINE urban(LSOLAR, & ! L IF (IMP_SCHEME==2) then IF (FLXHUMRP <= 0.) FLXHUMRP = 0. ! Compute water retention depth from previous time step - ! Convert kinematic water flux to evaporation in m/s: multiply flux by rho_air/who_water in SI units + ! Convert kinematic water flux to evaporation in m/s: multiply flux by rho_air/who_water in SI units DrelR = DrelRP+(RAIN1-FLXHUMRP*RHOO/1000.)*DELT/porimp(IMPR) - IF (RAIN > 0. .AND. DrelR < DrelRP) DrelR = DrelRP +! IF (RAIN > 0. .AND. DrelR < DrelRP) DrelR = DrelRP ! remove this line to allow Drel to decrease even when RAIN > 0 (chenghao wang) IF (DrelR <= 0.) then DrelR = 0.0 @@ -1133,6 +1332,7 @@ SUBROUTINE urban(LSOLAR, & ! L RUNOFF1 = 0.0 RUNOFF2 = 0.0 RUNOFF3 = 0.0 + SROOT = 0.0 KZ = 1 ZSOILR (KZ) = - DZGR (KZ) @@ -1147,16 +1347,18 @@ SUBROUTINE urban(LSOLAR, & ! L QS0GR=0.622*ES/(PS-0.378*ES) DQS0GRDTGR = DESDT*0.622*PS/((PS-0.378*ES)**2.) EPGR=RHOO*CHGR*UA*(QS0GR-QA) ! Potential evaporation [kg/m2/s] - + ! print*, 'vegetated roof temperature is:', TGRP ! add by yuqi for testing purpose + ! print*, 'potential et from vegetated roof is:', EPGR ! add by yuqi for testing purpose + IF (EPGR > 0.0) THEN ! Direct evaporation from soil on green roof - CALL DIREVAP (EDIR,EPGR,SMRP(KZ),SHDFAC,SMCMAX,SMCDRY,FXEXP) + CALL DIREVAP (EDIR,EPGR,SMRP(KZ),SHDFAC,SMCMAX,SMCDRY,FXEXP) ! CONTRIBUTED FROM BARE SOIL ! Evapotranspiration and canopy intercepted evaporation - CALL TRANSP (ETTR,ETR,ECR,SHDFAC,EPGR,CMCRP,CFACTR,CMCMAX,LAI,RSMIN,RSMAX,RGL,SX, & + CALL TRANSP (ETTR,ETR,ECR,SHDFAC,EPGR,CMCRP,CFACTR,CMCMAX,LAI,RSMIN,RSMAX,RGL,SX, & ! CONTRIBUTED FROM VEGETED all layers (yuqi) TGRP,TA,QA,SMRP,SMCWLT,SMCREF,CPP,PS,CHGR,EPSV,DELT,NROOT,NGR,DZGR, & ZSOILR,HS) ! Update moisture in soil layers - CALL SMFLX (SMRP,SMR,NGR,CMCRP,CMCR,DELT,RAIN,ZSOILR,SMCMAX,BEXP,SMCWLT,DKSAT,& + CALL SMFLX (SMRP,SMR,NGR,CMCRP,CMCR,DELT,RAIN,ZSOILR,SMCMAX,BEXP,SMCWLT,SROOT,DKSAT,& DWSAT,SHDFAC,CMCMAX,RUNOFF1,RUNOFF2,RUNOFF3,EDIR,ECR,ETR,DRIP) else DEW = - EPGR @@ -1164,7 +1366,7 @@ SUBROUTINE urban(LSOLAR, & ! L EDIR=0.0 ECR =0.0 ETTR=0.0 - CALL SMFLX (SMRP,SMR,NGR,CMCRP,CMCR,DELT,RAINDR,ZSOILR,SMCMAX,BEXP,SMCWLT,DKSAT,& + CALL SMFLX (SMRP,SMR,NGR,CMCRP,CMCR,DELT,RAINDR,ZSOILR,SMCMAX,BEXP,SMCWLT,SROOT,DKSAT,& DWSAT,SHDFAC,CMCMAX,RUNOFF1,RUNOFF2,RUNOFF3,EDIR,ECR,ETR,DRIP) END IF ! ---------------------------------------------------------------------- @@ -1173,7 +1375,7 @@ SUBROUTINE urban(LSOLAR, & ! L EDIR = EDIR * 1000.0 ETTR = ETTR * 1000.0 ECR = ECR * 1000.0 - ETAR = EDIR + ETTR + ECR + ETAR = EDIR + ETTR + ECR ! [kg/m2/s] IF (ETAR < 1.E-20) ETAR = 0.0 IF ( EPGR <= 0.0 ) THEN @@ -1181,12 +1383,12 @@ SUBROUTINE urban(LSOLAR, & ! L ELSE BETGR = ETAR / EPGR END IF - ELEGR= ETAR* RHO * EL /RHOO * 100 + ELEGR= ETAR* RHO * EL /RHOO * 100 ! [cal/cm2/s] [EL is cal/g] CALL TDFCND (DF1,SMR(KZ), QUARTZ, SMCMAX ) - DF1 = DF1 * EXP(-2.0 * SHDFAC) - RGR = EPSV*(RX-SIG*(TA**4.)/60.) - RGRR= (SGR+RGR) * 697.7 * 60. + DF1 = DF1 * EXP(-2.0 * SHDFAC) + RGR = EPSV*(RX-SIG*(TGRP**4.)/60.) ! change TGRP to TA in the new version (Yuqi) - bug + RGRR= (SGR+RGR) * 697.7 * 60. ! [cal/cm2/s] RCH = RHOO*CPP*CHGR RR1 = EPSV*(TA**4) * 6.48E-8 / (PS* CHGR) + 1.0 IF (RAIN > 0.0) then @@ -1203,12 +1405,12 @@ SUBROUTINE urban(LSOLAR, & ! L RUNOFF2 = RUNOFF2+ RUNOFF3 G0GR = DF1*(TGRP-TGRL(1))/(DZGR(1)/2.)/697.7/60 - FV = SGR + RGR - HGR - ELEGR - G0GR + FV = SGR + RGR - HGR - ELEGR - G0GR ! cgs unit DRRDTGR = (-4.*EPSV*SIG*TGRP**3.)/60. DHRDTGR = RHO*CP*CHGR*UA*100. DELERDTGR = RHO*EL*CHGR*UA*BETGR*DQS0GRDTGR*100. DG0RDTGR = 2.*DF1/ DZGR(KZ) * ( 1.0 / 4.1868 ) * 1.E-4 - DFDVT = DRRDTGR - DHRDTGR - DELERDTGR - DG0RDTGR + DFDVT = DRRDTGR - DHRDTGR - DELERDTGR - DG0RDTGR ! HERE USE ETP INSTEAD OF ACTUAL ET TO DERIVE DELEDTGR (YUQI) DTGR = FV/DFDVT/ 6 TGR = TGRP - DTGR TGRP = TGR @@ -1246,7 +1448,7 @@ SUBROUTINE urban(LSOLAR, & ! L T1VC = TCP* (1.0+ 0.61 * QA) RLMO_URB=0.0 - CALL SFCDIF_URB(ZA,Z0C,T1VC,TH2V,UA,AKANDA_URBAN,CMC_URB,CHC_URB,RLMO_URB,CDC) + CALL SFCDIF_URB(ZA,Z0C,T1VC,TH2V,UA,AKANDA_URBAN,CMC_URB,CHC_URB,RLMO_URB,CDC) ! CDC: momentum exchange coefficient for canopy (yuqi) ALPHAC = RHO*CP*CHC_URB IF (CH_SCHEME == 1) THEN @@ -1272,7 +1474,6 @@ SUBROUTINE urban(LSOLAR, & ! L CHC=ALPHAC/RHO/CP/UA CHB=ALPHAB/RHO/CP/UC CHG=ALPHAG/RHO/CP/UC - END IF !Yang 10/10/2013 -- LH from impervious wall and ground @@ -1285,11 +1486,10 @@ SUBROUTINE urban(LSOLAR, & ! L IF (FLXHUMBP <= 0.) FLXHUMBP = 0. IF (FLXHUMGP <= 0.) FLXHUMGP = 0. ! Compute water retention from previous time step for wall and ground - ! Convert kinematic water flux to evaporation in m/s: multiply flux by rho_air/who_water in SI units - DrelB = DrelBP+(RAIN1-FLXHUMBP*RHOO/1000.)*DELT/porimp(IMPB) - IF (RAIN > 0. .AND. DrelB < DrelBP) DrelB = DrelBP - DrelG = DrelGP+(RAIN1-FLXHUMGP*RHOO/1000.)*DELT/porimp(IMPG) - IF (RAIN > 0. .AND. DrelG < DrelGP) DrelG = DrelGP + DrelB = DrelBP+(RAIN1-FLXHUMBP*RHOO/1000.)*DELT/porimp(IMPB) + ! IF (RAIN > 0. .AND. DrelB < DrelBP) DrelB = DrelBP ! remove this line to allow Drel to decrease even when RAIN > 0 (Chenghao) + DrelG = DrelGP+(RAIN1-FLXHUMGP*RHOO/1000.)*DELT/porimp(IMPG) + ! IF (RAIN > 0. .AND. DrelG < DrelGP) DrelG = DrelGP ! remove this line to allow Drel to decrease even when RAIN > 0 (Chenghao) IF (DrelB <= 0.) then DrelB = 0.0 @@ -1316,16 +1516,17 @@ SUBROUTINE urban(LSOLAR, & ! L ENDIF - IF (TS_SCHEME == 1) THEN - !------------------------------------------------------------------------------- -! TB, TG Solving Non-Linear Simultaneous Equation by Newton-Rapson -! TBL,TGL Solving Heat Equation by Tri Diagonal Matrix Algorithm +! ENERGY BUDGET WITHOUT URBAN TREE + !------------------------------------------------------------------------------- - -! TBP=350. -! TGP=350. - + IF (TREEOPTION .ne. 1) THEN + + IF (TS_SCHEME == 1) THEN + !------------------------------------------------------------------------------- + ! TB, TG Solving Non-Linear Simultaneous Equation by Newton-Rapson + ! TBL,TGL Solving Heat Equation by Tri Diagonal Matrix Algorithm + !------------------------------------------------------------------------------- DO ITERATION=1,20 ES=6.11*EXP( (2.5*10.**6./461.51)*(TBP-273.15)/(273.15*TBP) ) @@ -1396,7 +1597,7 @@ SUBROUTINE urban(LSOLAR, & ! L HB=RHO*CP*CHB*UC*(TBP-TCP)*100. HG=RHO*CP*CHG*UC*(TGP-TCP)*100. - DTCDTB=W*ALPHAB/(RW*ALPHAC+RW*ALPHAG+W*ALPHAB) + DTCDTB=W*ALPHAB/(RW*ALPHAC+RW*ALPHAG+W*ALPHAB) DTCDTG=RW*ALPHAG/(RW*ALPHAC+RW*ALPHAG+W*ALPHAB) DHBDTB=RHO*CP*CHB*UC*(1.-DTCDTB)*100. @@ -1407,7 +1608,7 @@ SUBROUTINE urban(LSOLAR, & ! L ELEB=RHO*EL*CHB*UC*BETB*(QS0B-QCP)*100. ELEG=RHO*EL*CHG*UC*BETG*(QS0G-QCP)*100. - DQCDTB=W*ALPHAB*BETB*DQS0BDTB/(RW*ALPHAC+RW*ALPHAG*BETG+W*ALPHAB*BETB) + DQCDTB=W*ALPHAB*BETB*DQS0BDTB/(RW*ALPHAC+RW*ALPHAG*BETG+W*ALPHAB*BETB) DQCDTG=RW*ALPHAG*BETG*DQS0GDTG/(RW*ALPHAC+RW*ALPHAG*BETG+W*ALPHAB*BETB) DELEBDTB=RHO*EL*CHB*UC*BETB*(DQS0BDTB-DQCDTB)*100. @@ -1434,7 +1635,7 @@ SUBROUTINE urban(LSOLAR, & ! L DTB = (GF*FY-F*GY)/(FX*GY-GX*FY) DTG = -(GF+GX*DTB)/GY - + TB = TBP + DTB TG = TGP + DTG @@ -1443,7 +1644,7 @@ SUBROUTINE urban(LSOLAR, & ! L IF (distributed_aerodynamics_option) THEN DTC = 0.0 - ELSE + ELSE TC1=RW*ALPHAC+RW*ALPHAG+W*ALPHAB TC2=RW*ALPHAC*TA+RW*ALPHAG*TGP+W*ALPHAB*TBP TC=TC2/TC1 @@ -1463,10 +1664,9 @@ SUBROUTINE urban(LSOLAR, & ! L END DO - CALL multi_layer(num_wall_layers,BOUNDB,G0B,CAPB,AKSB,TBL,DZB,DELT,TBLEND) + CALL multi_layer(num_wall_layers,BOUNDB,G0B,CAPB,AKSB,TBL,DZB,DELT,TBLEND) CALL multi_layer(num_road_layers,BOUNDG,G0G,CAPG,AKSG,TGL,DZG,DELT,TGLEND) - ELSE !------------------------------------------------------------------------------- @@ -1526,19 +1726,564 @@ SUBROUTINE urban(LSOLAR, & ! L TCP=TC QCP=QC + END IF + + ELSE + !------------------------------------------------------------------------------- + ! ENERGY BUDGET WITH URBAN TREE (Huang) + ! VFAC: VEGE FRACTION IN VEGETATED GROUND, SIMILAR TO SHDFAC, BUT SHOULD BE PARAMETERIZED (YUQI) + ! NEW VARIABLES: + ! BHVG,Z0VG,Z0HVG,RIBVG,TVGP,XXXVG,ALPHAVG,CDVG,CHVG,SRUN1,SRUN2,SRUN3,ZSOILG(total depth),DZVG(depth of each single layer), + ! QS0VG,DQS0VGDTVG,QS0T,DQS0TDTT,EPVG,EDIRG,ETTG,ETG,ECG,LAI_VEG,NVG,DRIPG,ETAG,BETVG, + ! EPSGE,EMITW,EMITG,EMITT,RVG1,RVG2,RVG,RT1,RT2,RT,RLEAF, + ! DRBDTVG1,DRBDTVG2,DRBDTT1,DRBDTT2,DRGDTVG1,DRGDTVG2,DRGDTT1,DRGDTT2,DRVGDTB1,DRVGDTB2,DRVGDTVG1,DRVGDTVG2, + ! DRVGDTG1,DRVGDTG2,DRVGDTT1,DRVGDTT2,DRTDTB1,DRTDTB2,DRTDTG1,DRTDTG2,DRTDTVG1,DRTDTVG2,DRTDTT1,DRTDTT2, + ! DRBDTVG,DRBDTT,DRGDTVG,DRGDTT,DRVGDTB,DRVGDTG,DRVGDTVG,DRVGDTT,DRTDTB,DRTDTG,DRTDTVG,DRTDTT, + ! HVG,HT,RA_LEAF,ALPHAT,DLEAF, + ! W2,RS_LEAF,ELET,SROOT, + ! MIX,DMIX,QSAT,DQSAT,ESAT,D,DD,FE,DFE,DRS_LEAF,S,M,KK,L,N,DELEBDTVG,DELEBDTT,DELEGDTVG,DELEGDTT,DELEVGDTB,DELEVGDTG, + ! DELEVGDTVG,DELEVGDTT,DELETDTB,DELETDTG,DELETDTVG,DELETDTT,DTCDTVG,DTCDTT,DHBDTVG,DHBDTT,DHGDTVG,DHGDTT,DHVGDTB,DHVGDTG,DHVGDTVG,DHVGDTT, + ! DHTDTB,DHTDTG,DHTDTVG,DHTDTT,DQCDTVG,DQCDTT,ELEVG,KVG,G0VG,DG0BDTVG,DG0BDTT,DG0GDTVG,DG0GDTT,DG0VGDTB,DG0VGDTG,DG0VGDTVG,DG0VGDTT, + ! WF,A,B,C,D,E,F,GG,H,VGF,I,J,KK,L,M,N,O,P,CHARA,RVGT,CAPVG,TVGL,SSOILG + ! TGEP,QS0GE,ALPHAGE,FLXTHVG,FLXHUMVG,FLXTHT,FLXHUMT + !------------------------------------------------------------------------------- + + IF (TS_SCHEME == 1) THEN + + ! ------------ FIRST CALCULATE CHVG, CDVG, BETVG---------- + IF (CH_SCHEME == 1) THEN ! calculate heat exchange coefficient for vegetated ground (yuqi) + Z=ZDC + BHVG=LOG(Z0VG/Z0HVG)/0.4 + RIBVG=(9.8*2/(TCP+TVGP))*(TCP-TVGP)*(Z+Z0VG)/(UC*UC) + CALL mos(XXXVG,ALPHAVG,CDVG,BHVG,RIBVG,Z,Z0VG,UC,TCP,TVGP,RHO) + ELSE + ALPHAVG=RHO*CP*(6.15+4.18*UC)/1200 + IF(UC > 5) ALPHAVG=RHO*CP*(7.51*UC**0.78)/1200 + END IF + CHVG=ALPHAVG/RHO/CP/UC + + SRUN1 = 0.0 ! mainly following green roof's scheme below (yuqi) + SRUN2 = 0.0 + SRUN3 = 0.0 + + DZVG = DZGR ! set identical green roof depth and vegetated ground layer depth (Yuqi) [m] + KZ = 1 + ZSOILG (KZ) = - DZVG (KZ) ! dz: (positive) depth of each single layer; zsoil: (negative) accumulated depth from ground (yuqi) + DO KZ = 2,NVG ! nvg: total layer of vegetated ground, = 4 in here (yuqi) + ZSOILG (KZ) = - DZVG(KZ) + ZSOILG (KZ -1) + END DO + + TTP = TCP + DO ITERATION=1,100 + ! print* , 'Current iteration:', ITERATION + KZ=1 + ES=6.11*EXP( (2.5*10**6/461.51)*(TVGP-273.15)/(273.15*TVGP) ) + DESDT=(2.5*10**6/461.51)*ES/(TVGP**2) + QS0VG=0.622*ES/(PS-0.378*ES) + DQS0VGDTVG = DESDT*0.622*PS/((PS-0.378*ES)**2) + EPVG=RHOO*CHVG*UC*(QS0VG-QCP) + + + !print*, 'vegetated ground temperature is:', TVGP ! add by yuqi for testing purpose + !print*, 'potential et from vegetated ground is:', EPVG ! add by yuqi for testing purpose + !print*, 'soil moisture for vegetated ground is:', SMGP ! add by yuqi for testing purpose + + VFAC = 1.0 - EXP(-0.52 * LAI_VEG) ! following PhenologyMainMod.F90 in Noah_MP (yuqi) + IF (EPVG > 0.0) THEN + CALL DIREVAP (EDIRG,EPVG,SMGP(KZ),VFAC,SMCMAX,SMCDRY,FXEXP) ! CONTRIBUTED FROM BARE SOIL (YUQI) + CALL TRANSP (ETTG,ETG,ECG,VFAC,EPVG,CMCGP,CFACTR,CMCMAX,LAI_VEG,RSMIN,RSMAX,RGL,SX, & ! CONTRIBUTED FROM VEGETED, USE TC AND QC INSTEAD OF TA AND QA (YUQI) + TVGP,TCP,QCP,SMGP,SMCWLT,SMCREF,CPP,PS,CHVG,EPSVG,DELT,NROOT,NVG,DZVG, & ! NROOT IS NUMBER OF VEGE ROOT, SAME AS IN GREEN ROOF (YUQI) + ZSOILG,HS) + CALL SMFLX (SMGP,SMG,NVG,CMCGP,CMCG,DELT,RAIN,ZSOILG,SMCMAX,BEXP,SMCWLT,SROOTP,DKSAT,& ! NVG: LAYER OF VEGETATED GROUND (YUQI) + DWSAT,VFAC,CMCMAX,SRUN1,SRUN2,SRUN3,EDIRG,ECG,ETG,DRIPG) + ELSE + DEW = - EPVG + RAINDR = RAIN + DEW * 3600 + EDIRG=0.0 + ECG =0.0 + ETTG=0.0 + CALL SMFLX (SMGP,SMG,NVG,CMCGP,CMCG,DELT,RAINDR,ZSOILG,SMCMAX,BEXP,SMCWLT,SROOTP,DKSAT, & + DWSAT,VFAC,CMCMAX,SRUN1,SRUN2,SRUN3,EDIRG,ECG,ETG,DRIPG) + END IF + ! print*, 'Vegetated soil moisture=', SMG ! add by yuqi for testing purpose + + EDIRG = EDIRG * 1000 + ETTG = ETTG * 1000 + ECG = ECG * 1000 + ETAG = EDIRG + ETTG + ECG ! unit: converted from m/s to kg/m2/s (Chenghao) + IF (ETAG < 1.E-20) ETAG = 0 + IF ( EPVG <= 0 ) THEN + BETVG = 0 + ELSE + BETVG = ETAG / EPVG + END IF + + + ES=6.11*EXP( (2.5*10**6/461.51)*(TBP-273.15)/(273.15*TBP) ) + DESDT=(2.5*10**6/461.51)*ES/(TBP**2) + QS0B=0.622*ES/(PS-0.378*ES) + DQS0BDTB=DESDT*0.622*PS/((PS-0.378*ES)**2) + + ES=6.11*EXP( (2.5*10**6/461.51)*(TGP-273.15)/(273.15*TGP) ) + DESDT=(2.5*10**6/461.51)*ES/(TGP**2) + QS0G=0.622*ES/(PS-0.378*ES) + DQS0GDTG=DESDT*0.622*PS/((PS-0.378*ES)**2) + + ES=6.11*EXP( (2.5*10**6/461.51)*(TTP-273.15)/(273.15*TTP) ) + DESDT=(2.5*10**6/461.51)*ES/(TTP**2) + QS0T=0.622*ES/(PS-0.378*ES) + + + EPSGE = (1 - FVG) * EPSG + FVG * EPSVG + TGEP = (1 - FVG) * TGP + FVG * TVGP + + + EMITW = EPSB * SIG * TBP**4./60 + EMITG = EPSGE* SIG * TGEP**4./60 + EMITT = EPST * SIG * TTP**4./60 + + RG1 = EPSG * (RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE - & + SIG * TGP**4./60) + + RVG1= EPSVG * (RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE - & + SIG * TVGP**4./60) + + RB1 = EPSB * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE - & + SIG * TBP**4./60) + + RG2 = EPSG * ((2 * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE) * (1 - EPSB) * VFGW_TREE) + & + ((RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) * (1 - EPST) * VFGT_TREE)) + + RVG2= EPSVG * ((2 * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE) * (1 - EPSB) * VFGW_TREE) + & + ((RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) * (1 - EPST) * VFGT_TREE)) + + RB2 = EPSB * (((RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE) * (1 - EPSGE) * VFWG_TREE) + & + ((RX * VFWS_TREE + EMITW * VFWW_TREE + EMITG * VFWG_TREE + & + EMITT * VFWT_TREE) * (1 - EPSB) * VFWW_TREE) + & + ((RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) * (1 - EPST) * VFWT_TREE)) + + RT1 = EPST * (RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) - EMITT + + RT2 = EPST * ((2 * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE) * (1 - EPSB) * VFTW_TREE) + & + ((RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE) * (1 - EPSGE) * VFTG_TREE)) + + RG = RG1 + RG2 ! Note: unit as cal/cm2/s + RB = RB1 + RB2 ! Note: unit as cal/cm2/s + RVG= RVG1+RVG2 ! Note: unit as cal/cm2/s + RT = RT1 + RT2 ! Note: unit as cal/cm2/s + RLEAF = RT * (2 * PI * RTREE * (1-TAU))/(2 * RTREE * LAI_TREE) *697.7*60. ! unit: w/m/m + ! print*,'RB, RVG, RT, RLEAF=', RB, RVG, RT, RLEAF ! add by yuqi for testing purpose + + + DRBDTB1 = EPSB * (4 * EPSB * SIG * TB**3 * VFWW_TREE - 4 * SIG * TB**3)/60 + DRBDTG1 = EPSB * (4 * EPSGE* SIG * TGE**3* VFWG_TREE * (1 - FVG))/60 + DRBDTVG1= EPSB * (4 * EPSGE* SIG * TGE**3* VFWG_TREE * FVG)/60 + DRBDTB2 = EPSB * (8 * EPSB * SIG * TB**3 * VFGW_TREE * (1 - EPSGE)* VFWG_TREE + & + 4 * EPSB * SIG * TB**3 * VFWW_TREE * (1 - EPSB) * VFWW_TREE + & + 8 * EPSB * SIG * TB**3 * VFTW_TREE * (1 - EPST) * VFWT_TREE)/60 + DRBDTG2 = EPSB * (4 * EPSGE* SIG * TGE**3* VFWG_TREE * (1 - FVG) * (1 - EPSB) * VFWW_TREE + & + 4 * EPSGE* SIG * TGE**3* VFTG_TREE * (1 - FVG) * (1 - EPST) * VFWT_TREE)/60 + DRBDTVG2= EPSB * (4 * EPSGE* SIG * TGE**3* VFWG_TREE * FVG * (1 - EPSB) * VFWW_TREE + & + 4 * EPSGE* SIG * TGE**3* VFTG_TREE * FVG * (1 - EPST) * VFWT_TREE)/60 + + + DRGDTB1 = EPSG * (8 * EPSB * SIG * TB**3 * VFGW_TREE)/60 + DRGDTG1 = EPSG * (-4 * SIG * TG**3)/60 + DRGDTVG1= 0 + DRGDTB2 = EPSG * (8 * EPSB * SIG * TB**3 * VFWW_TREE * (1- EPSB) * VFGW_TREE + & + 8 * EPSB * SIG * TB**3 * VFTW_TREE * (1- EPST) * VFGT_TREE)/60 + DRGDTG2 = EPSG * (8 * EPSGE* SIG * TGE**3* (1 - FVG)* VFWG_TREE * (1- EPSB) * VFGW_TREE + & + 4 * EPSGE* SIG * TGE**3* (1 - FVG)* VFTG_TREE * (1- EPST) * VFGT_TREE)/60 + DRGDTVG2= EPSG * (8 * EPSGE* SIG * TGE**3* FVG * VFWG_TREE * (1- EPSB) * VFGW_TREE + & + 4 * EPSGE* SIG * TGE**3* FVG * VFTG_TREE * (1- EPST) * VFGT_TREE)/60 + + + DRVGDTB1 = EPSVG * (8 * EPSB * SIG * TB**3 * VFGW_TREE)/60 + DRVGDTG1 = 0 + DRVGDTVG1= EPSVG * (-4* SIG * TVG**3)/60 + DRVGDTB2 = EPSVG * (8 * EPSB * SIG * TB**3 * VFWW_TREE * (1- EPSB) * VFGW_TREE + & + 8 * EPSB * SIG * TB**3 * VFTW_TREE * (1- EPST) * VFGT_TREE)/60 + DRVGDTG2 = EPSVG * (8 * EPSGE* SIG * TGE**3* (1 - FVG)* VFWG_TREE * (1- EPSB) * VFGW_TREE + & + 4 * EPSGE* SIG * TGE**3* (1 - FVG)* VFTG_TREE * (1- EPST) * VFGT_TREE)/60 + DRVGDTVG2= EPSVG * (8 * EPSGE* SIG * TGE**3* FVG * VFWG_TREE * (1- EPSB) * VFGW_TREE + & + 4 * EPSGE* SIG * TGE**3* FVG * VFTG_TREE * (1- EPST) * VFGT_TREE)/60 + + + DRBDTB = DRBDTB1 + DRBDTB2 + DRBDTG = DRBDTG1 + DRBDTG2 + DRBDTVG = DRBDTVG1 + DRBDTVG2 + DRGDTB = DRGDTB1 + DRGDTB2 + DRGDTG = DRGDTG1 + DRGDTG2 + DRGDTVG = DRGDTVG1 + DRGDTVG2 + DRVGDTB = DRVGDTB1 + DRVGDTB2 + DRVGDTG = DRVGDTG1 + DRVGDTG2 + DRVGDTVG = DRVGDTVG1+ DRVGDTVG2 + + HB=RHO*CP*CHB*UC*(TBP-TCP)*100 ! Note: unit [cal/cm2/s] ; RHO [g/cm3], CP [cal/g/K], UC [m/s] + HG=RHO*CP*CHG*UC*(TGP-TCP)*100 ! Note: unit [cal/cm2/s] + HVG=RHO*CP*CHVG*UC*(TVGP-TCP)*100 ! Note: unit [cal/cm2/s] + + + ELEB=RHO*EL*CHB*UC*BETB*(QS0B-QCP)*100 ! Note: unit [cal/cm2/s] + ELEG=RHO*EL*CHG*UC*BETG*(QS0G-QCP)*100 ! Note: unit [cal/cm2/s] + + RA_LEAF = 58 * (LAI_TREE**0.56) * SQRT(DLEAF/UC) ! DLEAF = 0.1 (YUQI) + W2 = 0.5 * (SMGP(NVG/2-1) + SMGP(NVG/2)) + CALL STOMATAL(RS_LEAF, RSMIN, SLEAF, LAI_TREE, W2, SMCREF, SMCMAX, TCP, TT, QCP, QS0T) + CALL LELEAF(ELET, SLEAF, RLEAF, RA_LEAF, RS_LEAF, RHOO, TCP, QCP, QS0T) + + AVAILABLE_WATER_SUM = 0.0 + DO K = 1, 3 + AVAILABLE_WATER_SUM = AVAILABLE_WATER_SUM + ((SMG(K)-SMCWLT) * DZVG(K)) ! unit: m (Yuqi) + END DO + + IF ((RTREE > 0.) .AND. (LAI_TREE > 0.)) THEN + POTENTIAL_ELET = (ELL * 1000 * AVAILABLE_WATER_SUM * FVG * RW / DELT) / & + (2.0 * RTREE * LAI_TREE) ! [J/kg]*[1000 kg/m3 - density]*[m]/[s] = [W/m2] + ELSE + POTENTIAL_ELET = 0.0 + END IF + ELET = MIN(POTENTIAL_ELET, ELET) ! unit: W/m2 + + CALL ROOT_UPTAKE(SROOT, NVG, SMG, SMCMAX, SMCDRY, RTREE_M, LAI_TREE, DZVG, ZSOILG, ELET, FVG, RW_M) ! SROOT unit: m/s (Yuqi) + + + ! residual approach (Yuqi) + HT = (SLEAF + RLEAF - ELET - (TT - TTP)/DELT*640) * (1/697.7/60.) ! following e.q 28 in (Ryu, 2016), unit same as HB, HG in [cal/cm2/s] + + ! ALPHAT = (RHO*CP*100.)/(1.27*RA_LEAF) ! unit [cal/cm2/s/K] ([g/cm3] * [cal/g/K] / [s/m] * [m/cm]) % commented out, no longer used for residual approach (Chenghao Wang) + DTCDTB = (W * ALPHAB)/(RW * ALPHAC + RW * FVG * ALPHAVG + RW * (1 - FVG) * ALPHAG + W * ALPHAB) + DTCDTG = (RW * ALPHAG * (1 - FVG))/(RW * ALPHAC + RW * FVG * ALPHAVG + RW * (1 - FVG) * ALPHAG + W * ALPHAB) + DTCDTVG= (RW * ALPHAVG * FVG)/(RW * ALPHAC + RW * FVG * ALPHAVG + RW * (1 - FVG) * ALPHAG + W * ALPHAB) + ! ALPHAs in the unit of cal/cm2/s/K + + + DHBDTB=RHO*CP*CHB*UC*(1-DTCDTB)*100 + DHBDTG=RHO*CP*CHB*UC*(0-DTCDTG)*100 + DHBDTVG=RHO*CP*CHB*UC*(0-DTCDTVG)*100 + DHGDTB=RHO*CP*CHG*UC*(0-DTCDTB)*100 + DHGDTG=RHO*CP*CHG*UC*(1-DTCDTG)*100 + DHGDTVG=RHO*CP*CHG*UC*(0-DTCDTVG)*100 + DHVGDTB=RHO*CP*CHVG*UC*(0-DTCDTB)*100 + DHVGDTG=RHO*CP*CHVG*UC*(0-DTCDTG)*100 + DHVGDTVG=RHO*CP*CHVG*UC*(1-DTCDTVG)*100 + + + DQCDTB=W*ALPHAB*BETB*DQS0BDTB/(W * ALPHAB * BETB + RW * (1 - FVG) * ALPHAG * BETG + RW * ALPHAC) + DQCDTG=RW * (1 - FVG) * ALPHAG * BETG * DQS0GDTG/(W * ALPHAB * BETB + RW * (1 - FVG) * ALPHAG * BETG + RW * ALPHAC) + ! DQCDTVG=0 ! no QS0VG in QC2 + DQCDTVG=RW * FVG * ALPHAVG * BETVG * DQS0VGDTVG/(W * ALPHAB * BETB + RW * (1 - FVG) * ALPHAG * BETG + RW * ALPHAC) + + DELEBDTB=RHO*EL*CHB*UC*BETB*(DQS0BDTB-DQCDTB)*100 + DELEBDTG=RHO*EL*CHB*UC*BETB*(0-DQCDTG)*100 + DELEBDTVG=RHO*EL*CHB*UC*BETB*(0-DQCDTVG)*100 + DELEGDTB=RHO*EL*CHG*UC*BETG*(0-DQCDTB)*100 + DELEGDTG=RHO*EL*CHG*UC*BETG*(DQS0GDTG-DQCDTG)*100 + DELEGDTVG=RHO*EL*CHG*UC*BETG*(0-DQCDTVG)*100 + DELEVGDTB=RHO*EL*CHVG*UC*BETVG*(0-DQCDTB)*100 + DELEVGDTG=RHO*EL*CHVG*UC*BETVG*(0-DQCDTG)*100 + DELEVGDTVG=RHO*EL*CHVG*UC*BETVG*(DQS0VGDTVG-DQCDTVG)*100 + + + ELEVG = ETAG * EL * 0.1 ! unit: cal/cm2/s + ! print*, 'actual et from vegetated ground=', ELEVG ! add by yuqi for testing purpose + + G0B=AKSB*(TBP-TBL(1))/(DZB(1)/2) ! unit: cal/cm2/s (yuqi) + G0G=AKSG*(TGP-TGL(1))/(DZG(1)/2) + + CALL TDFCND (KVG,SMG(KZ), QUARTZ, SMCMAX ) + KVG = KVG * EXP(-2.0 * VFAC) + G0VG= KVG * (TVGP-TVGL(1))/(DZVG(1)/2.)/697.7/60 ! unit: cal/cm2/s (Yuqi) + ! print*, 'G0B, G0G, G0VG=', G0B, G0G, G0VG + + DG0BDTB = 2 * AKSB/DZB(1) + DG0BDTG = 0 + DG0BDTVG = 0 + DG0GDTB = 0 + DG0GDTG = 2 * AKSG/DZG(1) + DG0GDTVG = 0 + DG0VGDTB = 0 + DG0VGDTG = 0 + DG0VGDTVG = 2 * KVG/DZVG(1)/697.7/60 + + WF = SB + RB - HB - ELEB - G0B + A = DRBDTB - DHBDTB - DELEBDTB - DG0BDTB + B = DRBDTG - DHBDTG - DELEBDTG - DG0BDTG + C = DRBDTVG - DHBDTVG - DELEBDTVG - DG0BDTVG + + GF = SG + RG - HG - ELEG - G0G + E = DRGDTB - DHGDTB - DELEGDTB - DG0GDTB + FF= DRGDTG - DHGDTG - DELEGDTG - DG0GDTG + GG = DRGDTVG - DHGDTVG - DELEGDTVG - DG0GDTVG + + VGF = SVG + RVG - HVG - ELEVG - G0VG + I = DRVGDTB - DHVGDTB - DELEVGDTB - DG0VGDTB + J = DRVGDTG - DHVGDTG - DELEVGDTG - DG0VGDTG + KK = DRVGDTVG - DHVGDTVG - DELEVGDTVG - DG0VGDTVG + + + det_scale = MAX(1.0D0, ABS(A), ABS(B), ABS(C), ABS(E), ABS(FF), ABS(GG), & + ABS(I), ABS(J), ABS(KK)) + det_tol = 1.0D-12 * det_scale**3 + det = A*(FF*KK-GG*J)-B*(E*KK-GG*I)+C*(E*J-FF*I) + A_use = A + FF_use = FF + KK_use = KK + relax = 1.0D0 + max_step = 5.0 + + ! Near-singular check: regularize diagonals and relax the update + IF (ABS(det) < det_tol) THEN + lambda = 1.0D-6 * det_scale + A_use = A + lambda + FF_use = FF + lambda + KK_use = KK + lambda + det = A_use*(FF_use*KK_use-GG*J)-B*(E*KK_use-GG*I)+C*(E*J-FF_use*I) + relax = 0.5D0 + IF (ABS(det) < det_tol) THEN + det = SIGN(det_tol, det) + END IF + WRITE_MESSAGE("WARNING: Near-singular matrix in Urban Tree Energy Budget; regularizing solve and relaxing update") + END IF + + CHARA = 1.0D0 / det + + DTB = -CHARA* (WF*(FF_use*KK_use-GG*J)+GF*(C*J-B*KK_use)+VGF*(B*GG-C*FF_use)) + DTG = -CHARA* (WF*(GG*I-E*KK_use)+GF*(A_use*KK_use-C*I)+VGF*(C*E-A_use*GG)) + DTVG= -CHARA* (WF*(E*J-FF_use*I)+GF*(B*I-A_use*J)+VGF*(A_use*FF_use-B*E)) + DTB = DTB * relax + DTG = DTG * relax + DTVG = DTVG * relax + DTB = SIGN(MIN(ABS(DTB), max_step), DTB) + DTG = SIGN(MIN(ABS(DTG), max_step), DTG) + DTVG = SIGN(MIN(ABS(DTVG), max_step), DTVG) + + + TB = TBP + DTB + TG = TGP + DTG + TVG= TVGP+DTVG + + + ! print*, 'DTB, DTG, DTVG=', DTB, DTG, DTVG ! add by yuqi for testing purpose + + TBP = TB + TGP = TG + TVGP= TVG + + ! print*, 'TBP, TGP, TVGP=',TBP, TGP, TVGP ! add by yuqi for testing purpose + + ! After updating the temperatures (e.g., TBP = TB) (yuqi) + TBP = MAX(223.15, MIN(353.15, TBP)) !-50C to +80C + TGP = MAX(223.15, MIN(353.15, TGP)) + TVGP = MAX(223.15, MIN(353.15, TVGP)) + + !IF (distributed_aerodynamics_option) THEN + !DTC = 0.0 + !ELSE + + + TC1 = RW * ALPHAC + RW * FVG * ALPHAVG + RW * (1 - FVG) * ALPHAG + W * ALPHAB + TC2 = RW * ALPHAC * TA + RW * FVG * ALPHAVG * TVGP + RW * (1 - FVG) * ALPHAG * TGP + W * ALPHAB * TBP + 2 * RTREE * LAI_TREE * (HT/100) + TC = TC2 / TC1 + ! Chenghao: HT unit is cgs, keep it as is [RHO - g/cm3, CP - cal/g/K] + ! print*, 'ALPHAT, ALPHAC, ALPHAVG, TC1, TC2, tmp=', ALPHAT, ALPHAC, ALPHAVG,TC1, TC2, 2 * RTREE * LAI_TREE * HT * ALPHAT ! add by yuqi + + QC1 = W * ALPHAB * BETB + RW * (1 - FVG) * ALPHAG * BETG + RW * ALPHAC + QC2 = W * ALPHAB * BETB * QS0B + RW * (1 - FVG) * ALPHAG * BETG * QS0G + RW * FVG * ETAG *CP / 1000 + RW * ALPHAC * QA + (2 * RTREE * LAI_TREE * CP * (ELET/697.7/60.)/100/EL) + QC=QC2/QC1 + ! Chenghao: ELET - [W/m2], convert it to cgs to be consistent with all other terms (e.g., ALPHAB) + + + ES=6.11*EXP( (2.5*10**6/461.51)*(TC-273.15)/(273.15*TC) ) + DESDT=(2.5*10**6/461.51)*ES/(TC**2) + QS0C=0.622*ES/(PS-0.378*ES) + + QC = MIN(QC, QS0C) + QC = MAX(QC, 0.0) + IF (QC <= 1.E-9 .AND. QCP > 1.E-9) THEN + QC = QCP + ELSE IF (QC <= 1.E-9 .AND. QCP <= 1.E-9) THEN + WARN_MSG = 'WARNING: Canyon air has become completely dry.' + WRITE_MESSAGE(WARN_MSG) + END IF + + ! print*, 'ELET, QS0B, QS0G, QS0VG,QC1,QC2=', ELET, QS0B, QS0G, QS0VG, QC1,QC2 ! add by yuqi + + TT = TC ! update TT (yuqi) + !TTP = TT ! update TTP (yuqi) + + DTC = TCP - TC + TCP = TC ! update TCP (yuqi) + QCP = QC + !END IF + ! print*, 'updated TT ,TC and QC=', TT, TC, QC ! add by yuqi for testing purpose + + RVGT= (SVG+RVG) * 697.7 * 60. + RCH = RHOO*CPP*CHVG + RR1 = EPSVG*(TVGP**4) * 6.48E-8 / (PS* CHVG) + 1.0 ! FOLLOWING JIACHUAN'S SCHEME, BUT DIFFERENT FROM OSU CODE (YUQI) + IF (RAIN > 0.0) THEN ! May cause some problem sicne we can't use TA to linearize TC, we can do that for TR (yuqi) + RR2 = RR1 + RAIN / 3600 * 4.218E+3 / RCH + ELSE + RR2 = RR1 + END IF + YY = TVG + (RVGT / RCH - BETVG * EPVG * ELL/ RCH) / RR2 ! THIS TVG IS WRONG (yuqi) + ZZ1 = KVG / (-0.5 * ZSOILG (KZ) * RCH * RR2 ) + 1.0 + SRUN3 = SRUN3/ DELT + SRUN2 = SRUN2 + SRUN3 + + + IF( ABS(WF) < 0.000001 .AND. ABS(DTB) < 0.000001 & + .AND. ABS(GF) < 0.000001 .AND. ABS(DTG) < 0.000001 & + .AND. ABS(VGF) < 0.000001 .AND. ABS(DTVG) < 0.000001 & + ! .AND. ABS(DTT) < 0.000001 & + .AND. ABS(DTC) < 0.000001) EXIT + + END DO + TT = TC ! add by yuqi + TTP = TT ! update TTP (yuqi) + + + CALL multi_layer(num_wall_layers,BOUNDB,G0B,CAPB,AKSB,TBL,DZB,DELT,TBLEND) + CALL multi_layer(num_road_layers,BOUNDG,G0G,CAPG,AKSG,TGL,DZG,DELT,TGLEND) + ! CALL multi_layer(num_road_layers,BOUNDG,G0VG,CAPVG,KVG,TVGL,DZVG*0.01,DELT,TGLEND) ! DZVG unit ([m] as input, needed to convert to[cm]) (Chenghao 2026/01/20) + CALL SHFLX (SSOILG,TVGL,SMG,SMCMAX,NVG,TVGP,DELT,YY,ZZ1,ZSOILG,TGLEND,ZBOT,SMCWLT,KVG,QUARTZ,CSOIL,CAPVG) ! Update temperature in vegetated ground soil layer (yuqi) + ! print*, 'TVGL=', TVGL ! add by yuqi for testing purpose + !print*, 'Soil heat flux=', SSOILG ! add by yuqi for testing purpose + + ELSE + !------------------------------------------------------------------------------- + ! TB, TG by Force-Restore Method + ! Note, Conflict With Vegetated Ground Scheme (Huang) + !------------------------------------------------------------------------------- + + ES=6.11*EXP( (2.5*10**6/461.51)*(TBP-273.15)/(273.15*TBP) ) + QS0B=0.622*ES/(PS-0.378*ES) + + ES=6.11*EXP( (2.5*10**6/461.51)*(TGP-273.15)/(273.15*TGP) ) + QS0G=0.622*ES/(PS-0.378*ES) + + ES=6.11*EXP( (2.5*10**6/461.51)*(TTP-273.15)/(273.15*TTP) ) + QS0T=0.622*ES/(PS-0.378*ES) + + ES=6.11*EXP( (2.5*10**6/461.51)*(TVGP-273.15)/(273.15*TVGP) ) ! following green roof scheme (yuqi) + QS0VG=0.622*ES/(PS-0.378*ES) + + EPSGE = (1 - FVG) * EPSG + FVG * EPSVG ! DEFINE NEW EPSVG HERE (YUQI) + TGEP = (1 - FVG) * TGP + FVG * TVGP + QS0GE = (1 - FVG) * QS0G + FVG * QS0VG + ALPHAGE = (1 - FVG) * ALPHAG + FVG * ALPHAVG + + EMITW = EPSB * SIG * TBP**4/60 + EMITG = EPSGE * SIG * TGEP**4/60 + EMITT = EPST * SIG * TTP**4/60 + + RG1 = EPSG * (RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE - & + SIG * TGP**4/60) + + RVG1= EPSVG * (RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE - & + SIG * TVGP**4/60) + + RB1 = EPSB * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE - & + SIG * TBP**4/60) + + RG2 = EPSG * ((2 * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE) * (1 - EPSB) * VFGW_TREE) + & + ((RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) * (1 - EPST) * VFGT_TREE)) + + RVG2= EPSVG * ((2 * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE) * (1 - EPSB) * VFGW_TREE) + & + ((RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) * (1 - EPST) * VFGT_TREE)) + + RB2 = EPSB * (((RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE) * (1 - EPSGE) * VFWG_TREE) + & + ((RX * VFWS_TREE + EMITW * VFWW_TREE + EMITG * VFWG_TREE + & + EMITT * VFWT_TREE) * (1 - EPSB) * VFWW_TREE) + & + ((RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) * (1 - EPST) * VFWT_TREE)) + + RT1 = EPST * (RX * VFTS_TREE + 2 * EMITW * VFTW_TREE + & + EMITG * VFTG_TREE) - EMITT + + RT2 = EPST * ((2 * (RX * VFWS_TREE + EMITW * VFWW_TREE + & + EMITG * VFWG_TREE + EMITT * VFWT_TREE) * (1 - EPSB) * VFTW_TREE) + & + ((RX * VFGS_TREE + 2 * EMITW * VFGW_TREE + & + EMITT * VFGT_TREE) * (1 - EPSGE) * VFTG_TREE)) + + RG = RG1 + RG2 + RB = RB1 + RB2 + RVG= RVG1+RVG2 + RT = RT1 + RT2 + + HB=RHO*CP*CHB*UC*(TBP-TCP)*100 + ELEB=RHO*EL*CHB*UC*BETB*(QS0B-QCP)*100 + G0B=SB+RB-HB-ELEB ! unit: cal/cm2/s + + HG=RHO*CP*CHG*UC*(TGP-TCP)*100 + ELEG=RHO*EL*CHG*UC*BETG*(QS0G-QCP)*100 + G0G=SG+RG-HG-ELEG ! unit: cal/cm2/s + + RA_LEAF = 58 * (LAI_TREE**0.56) * SQRT(DLEAF/UC) + HT = (SLEAF + RLEAF - ELET - (TT - TTP)/DELT*640)/697.7/60. ! HT in unit of cal/cm2/s (unit consistent with HB and HG) + W2 = 0.5 * (SMGP(NVG/2-1) + SMGP(NVG/2)) ! POTENTIAL ERROR (YUQI) + CALL STOMATAL(RS_LEAF, RSMIN, SLEAF, LAI_TREE, W2, SMCREF, SMCMAX, TC, TT, QC, QS0T) + CALL LELEAF(ELET, SLEAF, RLEAF, RA_LEAF, RS_LEAF, RHOO, TC, QC, QS0T) + + + CALL force_restore(CAPB,AKSB,DELT,SB,RB,HB,ELEB,TBLEND,TBP,TB) + CALL force_restore(CAPG,AKSG,DELT,SG,RG,HG,ELEG,TGLEND,TGP,TG) + CALL force_restore_tree(DELT,ST,RT,HT,ELET/(697.7*60),LAI_TREE,TTP,TT) ! to be fixed (Yuqi 01/21/2026) + + TBP=TB + TGP=TG + TTP=TT + TC1 = RW * ALPHAC + RW * FVG * ALPHAVG + RW * (1 - FVG) * ALPHAG + W * ALPHAB + TC2 = RW * ALPHAC * TA + RW * FVG * ALPHAVG * TVGP + RW * (1 - FVG) * ALPHAG * TGP + W * ALPHAB * TBP + 2 * RTREE * LAI_TREE * (HT/100) + TC = TC2 / TC1 + ! Chenghao: HT unit is cgs, keep it as is [RHO - g/cm3, CP - cal/g/K] + + QC1 = W * ALPHAB * BETB + RW * (1 - FVG) * ALPHAG * BETG + RW * ALPHAC + QC2 = W * ALPHAB * BETB * QS0B + RW * (1 - FVG) * ALPHAG * BETG * QS0G + RW * FVG * ETAG *CP / 1000 + RW * ALPHAC * QA + (2 * RTREE * LAI_TREE * CP * (ELET/697.7/60.)/100/EL) + QC=QC2/QC1 + ! Chenghao: ELET - [W/m2], convert it to cgs to be consistent with all other terms (e.g., ALPHAB) + + TCP=TC + QCP=QC + + END IF + END IF FLXTHB=HB/RHO/CP/100. - FLXHUMB=ELEB/RHO/EL/100. + FLXHUMB=ELEB/RHO/EL/100. ! ELEB is cgs unit, final unit m/s FLXTHG=HG/RHO/CP/100. - FLXHUMG=ELEG/RHO/EL/100. - + FLXHUMG=ELEG/RHO/EL/100. ! ELEG is cgs unit, final unit m/s + FLXTHVG=HVG/RHO/CP/100. ! ADD BY (Huang) + FLXHUMVG=ELEVG/RHO/EL/100. ! ELEVG is cgs unit, final unit m/s + FLXTHT=HT/RHO/CP/100. + FLXHUMT=ELET*(1/697.7/60.)/RHO/EL/100. ! ELET is W/m2, final unit m/s !------------------------------------------------------------------------------- ! Total Fluxes from Urban Canopy !------------------------------------------------------------------------------- !===Yang, 2014/10/08, cal. ah. alh. green roof=== - if(groption==1) then + IF (groption==1 .and. TREEOPTION .ne. 1) THEN if(ahoption==1) then FLXTH = ((1.-FGR)*R*FLXTHR + FGR*R*FLXTHGR + W*FLXTHB + RW*FLXTHG)+ AH/RHOO/CPP else @@ -1552,25 +2297,57 @@ SUBROUTINE urban(LSOLAR, & ! L FLXUV = ((1.-FGR)*R*CDR + FGR*R*CDGR + RW*CDC )*UA*UA FLXG = ((1.-FGR)*R*G0R + FGR*R*G0GR+ W*G0B + RW*G0G) LNET = (1.-FGR) * R * RR + FGR *R* RGR + W * RB + RW * RG - else - if(ahoption==1) then - FLXTH = ( R*FLXTHR + W*FLXTHB + RW*FLXTHG ) + AH/RHOO/CPP + + ELSEIF (groption .ne. 1 .and. TREEOPTION == 1) THEN + if (ahoption==1) then + FLXTH = ( R*FLXTHR + W*FLXTHB + (1 - FVG) * RW*FLXTHG + FVG * RW * FLXTHVG ) + AH/RHOO/CPP + FLXTHT*LAI_TREE*2*RTREE else - FLXTH = ( R*FLXTHR + W*FLXTHB + RW*FLXTHG ) + FLXTH = ( R*FLXTHR + W*FLXTHB + (1 - FVG) * RW*FLXTHG + FVG * RW * FLXTHVG + FLXTHT*LAI_TREE*2*RTREE ) endif if(alhoption==1) then - FLXHUM = ( R*FLXHUMR + W*FLXHUMB + RW*FLXHUMG )+ ALH/RHOO/ELL + FLXHUM = ( R*FLXHUMR + W*FLXHUMB + (1 - FVG) * RW*FLXHUMG + FVG * RW * FLXHUMVG )+ ALH/RHOO/ELL + FLXHUMT*LAI_TREE*2*RTREE + else + FLXHUM = ( R*FLXHUMR + W*FLXHUMB + (1 - FVG) * RW*FLXHUMG + FVG * RW * FLXHUMVG + FLXHUMT*LAI_TREE*2*RTREE ) + endif + IF (distributed_aerodynamics_option) THEN + FLXUV = CDC * UA * UA + ELSE + FLXUV = ( R*CDR + RW*CDC )*UA*UA + ENDIF + FLXG = R*G0R + W*G0B + (1 - FVG)*RW*G0G + FVG*RW*G0VG + LNET = R*RR + W*RB + (1 - FVG)*RW*RG + FVG*RW*RVG + RT * 2*PI*RTREE*(1-TAU) + + ELSEIF (groption == 1 .and. TREEOPTION == 1) THEN + if (ahoption==1) then + FLXTH = ( (1-FGR)*R*FLXTHR + FGR*R*FLXTHGR + W*FLXTHB + (1 - FVG) * RW*FLXTHG + FVG * RW * FLXTHVG ) + AH/RHOO/CPP + FLXTHT*LAI_TREE*2*RTREE else - FLXHUM = ( R*FLXHUMR + W*FLXHUMB + RW*FLXHUMG ) + FLXTH = ( (1-FGR)*R*FLXTHR + FGR*R*FLXTHGR + W*FLXTHB + (1 - FVG) * RW*FLXTHG + FVG * RW * FLXTHVG + FLXTHT*LAI_TREE*2*RTREE) + endif + if(alhoption==1) then + FLXHUM = ( (1-FGR)*R*FLXHUMR + FGR*R*FLXHUMGR + W*FLXHUMB + (1 - FVG) * RW*FLXHUMG + FVG * RW * FLXHUMVG )+ ALH/RHOO/ELL + FLXHUMT*LAI_TREE*2*RTREE + else + FLXHUM = ( (1-FGR)*R*FLXHUMR + FGR*R*FLXHUMGR + W*FLXHUMB + (1 - FVG) * RW*FLXHUMG + FVG * RW * FLXHUMVG + FLXHUMT*LAI_TREE*2*RTREE ) endif + FLXUV = ((1-FGR)*R*CDR + FGR*R*CDGR + RW*CDC )*UA*UA + FLXG = (1-FGR)*R*G0R + FGR*R*G0GR+ W*G0B + (1 - FVG)*RW*G0G + FVG*RW*G0VG + LNET = (1-FGR) * R * RR + FGR *R* RGR + W * RB + (1 - FVG)*RW*RG + FVG*RW*RVG + RT * 2*PI*RTREE*(1-TAU) + + ELSE + IF (ahoption==1) THEN + FLXTH = ( R*FLXTHR + W*FLXTHB + RW*FLXTHG ) + AH/RHOO/CPP + FLXHUM = ( R*FLXHUMR + W*FLXHUMB + RW*FLXHUMG )+ ALH/RHOO/ELL + ELSE + FLXTH = ( R*FLXTHR + W*FLXTHB + RW*FLXTHG ) + FLXHUM = ( R*FLXHUMR + W*FLXHUMB + RW*FLXHUMG ) + ENDIF IF (distributed_aerodynamics_option) THEN FLXUV = CDC * UA * UA ELSE FLXUV = ( R*CDR + RW*CDC )*UA*UA - END IF + ENDIF FLXG = ( R*G0R + W*G0B + RW*G0G ) LNET = R*RR + W*RB + RW*RG - endif + ENDIF !---------------------------------------------------------------------------- ! Convert Unit: FLUXES and u* T* q* --> WRF @@ -1609,26 +2386,43 @@ SUBROUTINE urban(LSOLAR, & ! L PSIH = -5. * XXX ELSE X = (1.-16.*XXX)**0.25 +! #ifdef DOUBLE_PRECISION ! newly added in thie version (yuqi) +! Code follows HRLDAS here (2025 summer) (Yuqi) +! PSIM = 2.*DLOG((1.+X)/2.) + DLOG((1.+X*X)/2.) - 2.*ATAN(X) + PI/2. +! PSIH = 2.*DLOG((1.+X*X)/2.) +!#else PSIM = 2.*ALOG((1.+X)/2.) + ALOG((1.+X*X)/2.) - 2.*ATAN(X) + PI/2. PSIH = 2.*ALOG((1.+X*X)/2.) +!#endif END IF +!#ifdef DOUBLE_PRECISION !newly added in this version (yuqi) + +! GZ1OZ0 = DLOG(Z/Z0) +! CD = 0.4**2./(DLOG(Z/Z0)-PSIM)**2. +! +!m CH = 0.4**2./(ALOG(Z/Z0)-PSIM)/(ALOG(Z/Z0H)-PSIH) +! CHS = 0.4*UST/(DLOG(Z/Z0H)-PSIH) ! cenlin 03/09/2023: uncomment to allow CHS calc for offline hrldas-urban +!#else GZ1OZ0 = ALOG(Z/Z0) CD = 0.4**2./(ALOG(Z/Z0)-PSIM)**2. - CHS_LOCAL = 0.4 * UST / (ALOG(Z / Z0H) - PSIH) + CHS_LOCAL = 0.4 * UST / (ALOG(Z / Z0H) - PSIH) ! !m CH = 0.4**2./(ALOG(Z/Z0)-PSIM)/(ALOG(Z/Z0H)-PSIH) -!m CHS = 0.4*UST/(ALOG(Z/Z0H)-PSIH) +! CHS = 0.4*UST/(ALOG(Z/Z0H)-PSIH) ! cenlin 03/09/2023: uncomment to allow CHS calc for offline hrldas-urban + + +!#endif !m TS = TA + FLXTH/CH/UA ! surface potential temp (flux temp) !m QS = QA + FLXHUM/CH/UA ! surface humidity ! - IF (distributed_aerodynamics_option) THEN - TS = TA + FLXTH / (ALPHAC / (RHO * CP)) ! surface potential temp (flux temp) - QS = QA + FLXHUM / (ALPHAC / (RHO * CP)) ! surface humidity - ELSE + !IF (distributed_aerodynamics_option) THEN ! comment this in the new version (yuqi) + ! TS = TA + FLXTH / (ALPHAC / (RHO * CP)) ! surface potential temp (flux temp) + ! QS = QA + FLXHUM / (ALPHAC / (RHO * CP)) ! surface humidity + !ELSE TS = TA + FLXTH/CHS ! surface potential temp (flux temp) QS = QA + FLXHUM/CHS ! surface humidity - END IF + ! END IF !------------------------------------------------------- ! diagnostic GRID AVERAGED U10 V10 TH2 Q2 --> WRF @@ -1643,12 +2437,25 @@ SUBROUTINE urban(LSOLAR, & ! L PSIH2 = -5. * XXX2 ELSE X = (1.-16.*XXX2)**0.25 +!#ifdef DOUBLE_PRECISION + +! PSIM2 = 2.*DLOG((1.+X)/2.) + DLOG((1.+X*X)/2.) - 2.*ATAN(X) + 2.*ATAN(1.) ! newly added in this version (yuqi) +! PSIH2 = 2.*DLOG((1.+X*X)/2.) +!#else PSIM2 = 2.*ALOG((1.+X)/2.) + ALOG((1.+X*X)/2.) - 2.*ATAN(X) + 2.*ATAN(1.) PSIH2 = 2.*ALOG((1.+X*X)/2.) + +!#endif END IF ! -!m CHS2 = 0.4*UST/(ALOG(2./Z0H)-PSIH2) +!#ifdef DOUBLE_PRECISION + +! CHS2 = 0.4*UST/(DLOG(2./Z0H)-PSIH2) ! cenlin 03/09/2023: uncomment to allow CHS2 calc for offline hrldas-urban ! newly commented in this version following WRF v4.7.1 (yuqi) ! +!#else +! CHS2 = 0.4*UST/(ALOG(2./Z0H)-PSIH2) ! cenlin 03/09/2023: uncomment to allow CHS2 calc for offline hrldas-urban + +!#endif XXX10 = (10./Z)*XXX IF ( XXX10 >= 1. ) XXX10 = 1. @@ -1659,10 +2466,26 @@ SUBROUTINE urban(LSOLAR, & ! L PSIH10 = -5. * XXX10 ELSE X = (1.-16.*XXX10)**0.25 +!#ifdef DOUBLE_PRECISION +! PSIM10 = 2.*DLOG((1.+X)/2.) + DLOG((1.+X*X)/2.) - 2.*ATAN(X) + 2.*ATAN(1.) ! newly added in this version (yuqi) +! PSIH10 = 2.*DLOG((1.+X*X)/2.) ! newly added in this version (yuqi) +!#else PSIM10 = 2.*ALOG((1.+X)/2.) + ALOG((1.+X*X)/2.) - 2.*ATAN(X) + 2.*ATAN(1.) PSIH10 = 2.*ALOG((1.+X*X)/2.) +!#endif + END IF +!#ifdef DOUBLE_PRECISION ! newly added below in this version (yuqi) + +! PSIX = DLOG(Z/Z0) - PSIM +! PSIT = DLOG(Z/Z0H) - PSIH +! PSIX2 = DLOG(2./Z0) - PSIM2 +! PSIT2 = DLOG(2./Z0H) - PSIH2 + +! PSIX10 = DLOG(10./Z0) - PSIM10 +! PSIT10 = DLOG(10./Z0H) - PSIH10 +!#else PSIX = ALOG(Z/Z0) - PSIM PSIT = ALOG(Z/Z0H) - PSIH @@ -1672,13 +2495,14 @@ SUBROUTINE urban(LSOLAR, & ! L PSIX10 = ALOG(10./Z0) - PSIM10 PSIT10 = ALOG(10./Z0H) - PSIH10 +!#endif U10 = U1 * (PSIX10/PSIX) ! u at 10 m [m/s] V10 = V1 * (PSIX10/PSIX) ! v at 10 m [m/s] ! TH2 = TS + (TA-TS)*(PSIT2/PSIT) ! potential temp at 2 m [K] ! TH2 = TS + (TA-TS)*(PSIT2/PSIT) ! Fei: this seems to be temp (not potential) at 2 m [K] !Fei: consistant with M-O theory - IF (distributed_aerodynamics_option) THEN + IF (distributed_aerodynamics_option) THEN ! comment this in the new version (yuqi) CHS2_LOCAL = 0.4 * UST / (ALOG(2. / Z0H) - PSIH2) TH2 = TS + (TA - TS) * (CHS_LOCAL / CHS2_LOCAL) Q2 = QS + (QA - QS) * (CHS_LOCAL / CHS2_LOCAL) @@ -1725,17 +2549,29 @@ SUBROUTINE mos(XXX,ALPHA,CD,B1,RIB,Z,Z0,UA,TA,TSF,RHO) X=(1.-16.*XXX)**0.25 X0=(1.-16.*XXX0)**0.25 - +!#ifdef DOUBLE_PRECISION ! newly added in the new version (yuqi) + +! PSIM=DLOG((Z+Z0)/Z0) & +! -DLOG((X+1.)**2.*(X**2.+1.)) & +! +2.*ATAN(X) & +! +DLOG((X+1.)**2.*(X0**2.+1.)) & +! -2.*ATAN(X0) +! FAIH=1./SQRT(1.-16.*XXX) +! PSIH=DLOG((Z+Z0)/Z0)+0.4*B1 & +! -2.*DLOG(SQRT(1.-16.*XXX)+1.) & +! +2.*DLOG(SQRT(1.-16.*XXX0)+1.) +!#else PSIM=ALOG((Z+Z0)/Z0) & -ALOG((X+1.)**2.*(X**2.+1.)) & +2.*ATAN(X) & - +ALOG((X0+1.)**2.*(X0**2.+1.)) & + +ALOG((X0+1.)**2.*(X0**2.+1.)) & ! they replace first X as X0 in here (yuqi) -2.*ATAN(X0) FAIH=1./SQRT(1.-16.*XXX) PSIH=ALOG((Z+Z0)/Z0)+0.4*B1 & -2.*ALOG(SQRT(1.-16.*XXX)+1.) & +2.*ALOG(SQRT(1.-16.*XXX0)+1.) +!#endif DPSIM=(1.-16.*XXX)**(-0.25)/XXX & -(1.-16.*XXX0)**(-0.25)/XXX DPSIH=1./SQRT(1.-16.*XXX)/XXX & @@ -1755,17 +2591,30 @@ SUBROUTINE mos(XXX,ALPHA,CD,B1,RIB,Z,Z0,UA,TA,TSF,RHO) ELSE IF(RIB >= 0.142857) THEN XXX=0.714 +!#ifdef DOUBLE_PRECISION +! PSIM=DLOG((Z+Z0)/Z0)+7.*XXX ! newly added in the new version (yuqi) +!#else PSIM=ALOG((Z+Z0)/Z0)+7.*XXX +!#endif PSIH=PSIM+0.4*B1 ELSE - +!#ifdef DOUBLE_PRECISION +! AL=DLOG((Z+Z0)/Z0) ! newly added in the new version (yuqi) +!#else AL=ALOG((Z+Z0)/Z0) +!#endif XKB=0.4*B1 DD=-4.*RIB*7.*XKB*AL+(AL+XKB)**2. IF(DD <= 0.) DD=0. XXX=(AL+XKB-2.*RIB*7.*AL-SQRT(DD))/(2.*(RIB*7.**2-7.)) +!#ifdef DOUBLE_PRECISION + +! PSIM=DLOG((Z+Z0)/Z0)+7.*MIN(XXX,0.714) ! newly added in the new version (yuqi) +!#else PSIM=ALOG((Z+Z0)/Z0)+7.*MIN(XXX,0.714) + +!#endif PSIH=PSIM+0.4*B1 END IF @@ -1794,8 +2643,13 @@ SUBROUTINE louis79(ALPHA,CD,RIB,Z,Z0,UA,RHO) REAL, INTENT(INOUT) :: RIB REAL :: A2, XX, CH, CMB, CHB +!#ifdef DOUBLE_PRECISION + +! A2=(0.4/DLOG(Z/Z0))**2. ! newly added in the new version (yuqi) +!#else A2=(0.4/ALOG(Z/Z0))**2. +!#endif IF(RIB <= -15.) RIB=-15. IF(RIB >= 0.0) THEN @@ -1832,8 +2686,11 @@ SUBROUTINE louis82(ALPHA,CD,RIB,Z,Z0,UA,RHO) REAL, INTENT(INOUT) :: RIB REAL :: A2, FM, FH, CH, CHH +!#ifdef DOUBLE_PRECISION +! A2=(0.4/DLOG(Z/Z0))**2. ! newly added in the new version (yuqi) +!#else A2=(0.4/ALOG(Z/Z0))**2. - +!#endif IF(RIB <= -15.) RIB=-15. IF(RIB >= 0.0) THEN @@ -1944,6 +2801,8 @@ SUBROUTINE read_param(UTYPE, & ! in CAPR,CAPB,CAPG,AKSR,AKSB,AKSG,ALBR,ALBB,ALBG, & ! out EPSR,EPSB,EPSG,Z0R,Z0B,Z0G,Z0HB,Z0HG, & ! out BETR,BETB,BETG,TRLEND,TBLEND,TGLEND, & ! out + RTREE,RTREE_M,RW_M,HTREE,DTREE,LAI_TREE,LAI_VEG, & ! out ! added by yuqi + Z0VG,Z0HVG,CAPVG,EPSVG,EPST, & ! out ! added by yuqi !for BEP NUMDIR, STREET_DIRECTION, STREET_WIDTH, & ! out BUILDING_WIDTH, NUMHGT, HEIGHT_BIN, & ! out @@ -1958,7 +2817,8 @@ SUBROUTINE read_param(UTYPE, & ! in CAPR,CAPB,CAPG,AKSR,AKSB,AKSG,ALBR,ALBB,ALBG, & SIGMA_ZED, & EPSR,EPSB,EPSG,Z0R,Z0B,Z0G,Z0HB,Z0HG, & - BETR,BETB,BETG,TRLEND,TBLEND,TGLEND + BETR,BETB,BETG,TRLEND,TBLEND,TGLEND,RTREE,RTREE_M,RW_M,HTREE,& + DTREE,LAI_TREE,LAI_VEG,Z0VG,Z0HVG,CAPVG,EPSVG,EPST ! added by yuqi REAL, INTENT(OUT) :: AKANDA_URBAN !for BEP INTEGER, INTENT(OUT) :: NUMDIR @@ -2010,6 +2870,21 @@ SUBROUTINE read_param(UTYPE, & ! in TRLEND= TRLEND_TBL(UTYPE) TBLEND= TBLEND_TBL(UTYPE) TGLEND= TGLEND_TBL(UTYPE) + RTREE= RTREE_TBL(UTYPE) ! added by yuqi + RTREE_M = RTREE_M_TBL(UTYPE) + RW_M = RW_M_TBL(UTYPE) + HTREE= HTREE_TBL(UTYPE) + DTREE= DTREE_TBL(UTYPE) + LAI_TREE=LAI_TREE_TBL(UTYPE) + LAI_VEG= LAI_VEG_TBL(UTYPE) + Z0VG = Z0VG_TBL(UTYPE) + Z0HVG= Z0HVG_TBL(UTYPE) + CAPVG= CAPVG_TBL(UTYPE) + EPSVG= EPSVG_TBL(UTYPE) + EPST = EPST_TBL(UTYPE) + + + BOUNDR= BOUNDR_DATA BOUNDB= BOUNDB_DATA BOUNDG= BOUNDG_DATA @@ -2041,7 +2916,7 @@ END SUBROUTINE read_param ! !=============================================================================== SUBROUTINE urban_param_init(DZR,DZB,DZG,num_soil_layers, & - sf_urban_physics,use_wudapt_lcz, slucm_distributed_drag) + sf_urban_physics,use_wudapt_lcz,slucm_distributed_drag) ! Chenghao Wang change this back to 4.7.1 ! num_roof_layers,num_wall_layers,num_road_layers) IMPLICIT NONE @@ -2065,6 +2940,7 @@ SUBROUTINE urban_param_init(DZR,DZB,DZG,num_soil_layers, & INTEGER :: num_road_layers INTEGER :: dummy REAL :: DHGT, HGT, VFWS, VFGS + REAL :: fvg ! Yuqi REAL, allocatable, dimension(:) :: ROOF_WIDTH REAL, allocatable, dimension(:) :: ROAD_WIDTH @@ -2095,7 +2971,6 @@ SUBROUTINE urban_param_init(DZR,DZB,DZG,num_soil_layers, & ICATE=0 distributed_aerodynamics_option = slucm_distributed_drag - if(USE_WUDAPT_LCZ.eq.0)then !AndreaLCZ OPEN (UNIT=11, & @@ -2210,6 +3085,30 @@ SUBROUTINE urban_param_init(DZR,DZB,DZG,num_soil_layers, & if(allocate_status /= 0) FATAL_ERROR('Error allocating TGLEND_TBL in urban_param_init') ALLOCATE( FRC_URB_TBL(ICATE), stat=allocate_status ) if(allocate_status /= 0) FATAL_ERROR('Error allocating FRC_URB_TBL in urban_param_init') + ALLOCATE( RTREE_TBL(ICATE), stat=allocate_status ) ! added by yuqi + if(allocate_status /= 0) FATAL_ERROR('Error allocating RTREE_TBL in urban_param_init') + ALLOCATE( RTREE_M_TBL(ICATE), stat=allocate_status ) ! added by yuqi + if(allocate_status /= 0) FATAL_ERROR('Error allocating RTREE_M_TBL in urban_param_init') + ALLOCATE( RW_M_TBL(ICATE), stat=allocate_status ) ! added by yuqi + if(allocate_status /= 0) FATAL_ERROR('Error allocating RW_M_TBL in urban_param_init') + ALLOCATE( HTREE_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating HTREE_TBL in urban_param_init') + ALLOCATE( DTREE_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating DTREE_TBL in urban_param_init') + ALLOCATE( LAI_TREE_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating LAI_TREE_TBL in urban_param_init') + ALLOCATE( LAI_VEG_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating LAI_VEG_TBL in urban_param_init') + ALLOCATE( Z0VG_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating Z0VG_TBL in urban_param_init') + ALLOCATE( Z0HVG_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating Z0HVG_TBL in urban_param_init') + ALLOCATE( CAPVG_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating CAPVG_TBL in urban_param_init') + ALLOCATE( EPSVG_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating EPSVG_TBL in urban_param_init') + ALLOCATE( EPST_TBL(ICATE), stat=allocate_status ) + if(allocate_status /= 0) FATAL_ERROR('Error allocating EPST_TBL in urban_param_init') ! ALLOCATE( ROOF_WIDTH(ICATE), stat=allocate_status ) ! if(allocate_status /= 0) FATAL_ERROR('Error allocating ROOF_WIDTH in urban_param_init') ! ALLOCATE( ROAD_WIDTH(ICATE), stat=allocate_status ) @@ -2384,9 +3283,37 @@ SUBROUTINE urban_param_init(DZR,DZB,DZG,num_soil_layers, & else if (name == "GROPTION") then read(string(indx+1:),*) groption else if (name == "FGR") then - read(string(indx+1:),*) fgr + read(string(indx+1:),*) fgr else if (name == "DZGR") then read(string(indx+1:),*) dzgr(1:4) + else if (name == "FVG") then + read(string(indx+1:),*) fvg + fvg_data = fvg + else if (name == "RTREE") then + read(string(indx+1:),*) rtree_tbl(1:icate) + else if (name == "HTREE") then + read(string(indx+1:),*) htree_tbl(1:icate) + else if (name == "DTREE") then + read(string(indx+1:),*) dtree_tbl(1:icate) + else if (name == "LAI_TREE") then + read(string(indx+1:),*) lai_tree_tbl(1:icate) + else if (name == "LAI_VEG") then + read(string(indx+1:),*) lai_veg_tbl(1:icate) + else if (name == "Z0VG") then + read(string(indx+1:),*) z0vg_tbl(1:icate) + else if (name == "Z0HVG") then + read(string(indx+1:),*) z0hvg_tbl(1:icate) + else if (name == "CAPVG") then + read(string(indx+1:),*) capvg_tbl(1:icate) + ! Convert CAPVG_TBL from J m{-3} K{-1} to cal cm{-3} deg{-1} + capvg_tbl = capvg_tbl * ( 1.0 / 4.1868 ) * 1.E-6 + else if (name == "EPSVG") then + read(string(indx+1:),*) epsvg_tbl(1:icate) + ! added by Chenghao Wang + else if (name == "EPST") then + read(string(indx+1:),*) epst_tbl(1:icate) + else if (name == "TREEOPTION") then + read(string(indx+1:),*) treeoption !for BEP else if (name == "STREET PARAMETERS") then @@ -2486,6 +3413,13 @@ SUBROUTINE urban_param_init(DZR,DZB,DZG,num_soil_layers, & ! R: Normalized Roof Width (a.k.a. "building coverage ratio") R_TBL(LC) = ROOF_WIDTH(LC) / ( ROAD_WIDTH(LC) + ROOF_WIDTH(LC) ) + ! normalized rtree_tbl, dtree_tbl and htree_tbl ! added by yuqi to normalize tree dimension + RTREE_M_TBL(LC) = RTREE_TBL(LC) + RTREE_TBL(LC) = RTREE_TBL(LC) / (ROAD_WIDTH(LC) + ROOF_WIDTH(LC)) + DTREE_TBL(LC) = DTREE_TBL(LC) / (ROAD_WIDTH(LC) + ROOF_WIDTH(LC)) + HTREE_TBL(LC) = HTREE_TBL(LC) / (ROAD_WIDTH(LC) + ROOF_WIDTH(LC)) + + RW_M_TBL(LC) = ROAD_WIDTH(LC) RW_TBL(LC) = 1.0 - R_TBL(LC) BETR_TBL(LC) = 0.0 BETB_TBL(LC) = 0.0 @@ -2595,6 +3529,7 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & ! inout DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & ! inout FLXHUMR_URB2D, FLXHUMB_URB2D, FLXHUMG_URB2D, & ! inout + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D,FLXHUMVG_URB2D,FLXHUMT_URB2D, & ! inout (add by Yuqi Huang) A_U_BEP,A_V_BEP,A_T_BEP,A_Q_BEP, & ! inout multi-layer urban A_E_BEP,B_U_BEP,B_V_BEP, & ! inout multi-layer urban B_T_BEP,B_Q_BEP,B_E_BEP,DLG_BEP, & ! inout multi-layer urban @@ -2659,6 +3594,16 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: RN_URB2D REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TS_URB2D +!-----------add by Yuqi Huang ---------------- + REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D + REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D + REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D + REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D + REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D + REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D + REAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: TVGL_URB3D + REAL, DIMENSION(ims:ime, 1:num_soil_layers, jms:jme), INTENT(INOUT) :: SMG_URB3D +!---------------- end ------------------ ! multi-layer UCM variables REAL, DIMENSION(ims:ime, 1:urban_map_zrd, jms:jme), INTENT(INOUT) :: TRB_URB4D REAL, DIMENSION(ims:ime, 1:urban_map_zwd, jms:jme), INTENT(INOUT) :: TW1_URB4D @@ -2744,21 +3689,20 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, !m !FS FRC_URB2D(I,J)=0. UTYPE_URB2D(I,J)=0 - - distributed_aerodynamics_check: IF (distributed_aerodynamics_option) THEN + distributed_aerodynamics_check: IF (distributed_aerodynamics_option) THEN ! comment this in the new version (yuqi) IF (IVGTYP(I, J) == ISURBAN) THEN UTYPE_URB2D(I, J) = 2 ELSE UTYPE_URB2D(I, J) = 0 END IF - ELSE + ELSE SWITCH_URB=1 IF( IVGTYP(I,J) == ISURBAN) THEN IF(use_wudapt_lcz==0) THEN UTYPE_URB2D(I,J) = 2 ! for default. high-intensity ELSE - UTYPE_URB2D(I,J) = 5 ! for default. high-intensity + UTYPE_URB2D(I,J) = 5 ! for default. open mid-rise (Yuqi) ENDIF ELSE IF( IVGTYP(I,J) == LCZ_1) THEN UTYPE_URB2D(I,J) = 1 @@ -2834,7 +3778,7 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, ENDDO ENDIF ENDIF - END IF distributed_aerodynamics_check + END IF distributed_aerodynamics_check QC_URB2D(I,J)=0.01 @@ -2845,6 +3789,7 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, XXXB_URB2D(I,J)=0. XXXG_URB2D(I,J)=0. XXXC_URB2D(I,J)=0. + XXXVG_URB2D(I,J)=0. ! add by huang IF ( sf_urban_physics == 1 ) THEN DRELR_URB2D(I,J) = 0. @@ -2853,8 +3798,13 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, FLXHUMR_URB2D(I,J) = 0. FLXHUMB_URB2D(I,J) = 0. FLXHUMG_URB2D(I,J) = 0. + FLXHUMVG_URB2D(I,J) = 0. ! add by huang + FLXHUMT_URB2D(I,J) = 0. ! add by huang CMCR_URB2D(I,J) = 0. + CMCG_URB2D(I,J) = 0. ! add by huang TGR_URB2D(I,J)=TSURFACE0_URB(I,J)+0. + TVG_URB2D(I,J)=TSURFACE0_URB(I,J)+0. ! add by huang + TT_URB2D(I,J) =TSURFACE0_URB(I,J)+0. ! add by huang ENDIF TC_URB2D(I,J)=TSURFACE0_URB(I,J)+0. @@ -2882,10 +3832,18 @@ SUBROUTINE urban_var_init(ISURBAN, TSURFACE0_URB,TLAYER0_URB,TDEEP0_URB,IVGTYP, TGRL_URB3D(I,3,J)=TLAYER0_URB(I,2,J)+0. TGRL_URB3D(I,4,J)=TLAYER0_URB(I,2,J)+(TLAYER0_URB(I,3,J)-TLAYER0_URB(I,2,J))*0.29 + TVGL_URB3D(I,1,J)=TLAYER0_URB(I,1,J)+0. ! the 4 lines below added by yuqi + TVGL_URB3D(I,2,J)=0.5*(TLAYER0_URB(I,1,J)+TLAYER0_URB(I,2,J)) + TVGL_URB3D(I,3,J)=TLAYER0_URB(I,2,J)+0. + TVGL_URB3D(I,4,J)=TLAYER0_URB(I,2,J)+(TLAYER0_URB(I,3,J)-TLAYER0_URB(I,2,J))*0.29 SMR_URB3D(I,1,J)=0.2 SMR_URB3D(I,2,J)=0.2 SMR_URB3D(I,3,J)=0.2 SMR_URB3D(I,4,J)=0. + SMG_URB3D(I,1,J)=0.2 ! add by huang + SMG_URB3D(I,2,J)=0.2 + SMG_URB3D(I,3,J)=0.2 + SMG_URB3D(I,4,J)=0.0 ENDIF ! END DO @@ -3157,27 +4115,22 @@ SUBROUTINE SFCDIF_URB (ZLM,Z0,THZ0,THLM,SFCSPD,AKANDA,AKMS,AKHS,RLMO,CD,ZT_OUT,V ! ---------------------------------------------------------------------- ! NOTE: THE TWO CODE BLOCKS BELOW DEFINE FUNCTIONS +! THIS ROUTINE SFCDIF CAN HANDLE BOTH OVER OPEN WATER (SEA, OCEAN) AND +! OVER SOLID SURFACE (LAND, SEA-ICE). +! ---------------------------------------------------------------------- ! ---------------------------------------------------------------------- -! LECH'S SURFACE FUNCTIONS +! LECH'S SURFACE FUNCTIONS ! E.q A7&A8 (YUQI) ! ---------------------------------------------------------------------- PSLMU (ZZ)= -0.96* log (1.0-4.5* ZZ) PSLMS (ZZ)= (ZZ/RFC) -2.076* (1. -1./ (ZZ +1.)) PSLHU (ZZ)= -0.96* log (1.0-4.5* ZZ) - -! ---------------------------------------------------------------------- -! PAULSON'S SURFACE FUNCTIONS + PSLHS (ZZ)= ZZ * RFAC -2.076* (1. - exp(-1.2 * ZZ)) ! bug fixed in 4.7.1 (Yuqi) ! ---------------------------------------------------------------------- - PSLHS (ZZ)= ZZ * RFAC -2.076* (1. - exp(-1.2 * ZZ)) - PSPMU (XX)= -2.* log ( (XX +1.)*0.5) - log ( (XX * XX +1.)*0.5) & - & +2.* ATAN (XX) & - &- PIHF +! PAULSON'S SURFACE FUNCTIONS ! E.q A5&A6 (YUQI) +! ---------------------------------------------------------------------- + PSPMU (XX)= -2.* log ( (XX +1.)*0.5) - log ( (XX * XX +1.)*0.5) +2.* ATAN (XX) - PIHF PSPMS (YY)= 5.* YY PSPHU (XX)= -2.* log ( (XX * XX +1.)*0.5) - -! ---------------------------------------------------------------------- -! THIS ROUTINE SFCDIF CAN HANDLE BOTH OVER OPEN WATER (SEA, OCEAN) AND -! OVER SOLID SURFACE (LAND, SEA-ICE). -! ---------------------------------------------------------------------- PSPHS (YY)= 5.* YY ! ---------------------------------------------------------------------- @@ -3190,13 +4143,13 @@ SUBROUTINE SFCDIF_URB (ZLM,Z0,THZ0,THLM,SFCSPD,AKANDA,AKMS,AKHS,RLMO,CD,ZT_OUT,V ! ---------------------------------------------------------------------- ! ZILFC = - CZIL * VKRM * SQVISC ! C.......ZT=Z0*ZTFC - ZU = Z0 - RDZ = 1./ ZLM - CXCH = EXCM * RDZ - DTHV = THLM - THZ0 + ZU = Z0 ! momentum roughness length (yuqi), here set ZU = Z0 to initialize momentum roughness length + RDZ = 1./ ZLM ! ZLM is initial mixing length (yuqi) + CXCH = EXCM * RDZ ! used to limit the AKHS (kinematic heat transfer coefficient) and AKMS (kinematic momentum transfer coefficient) (yuqi) + DTHV = THLM - THZ0 ! Theta_V term in Obukhov Length, which is the potential temperature different of first layer atmosphere and Urban level (yuqi) ! ---------------------------------------------------------------------- -! BELJARS CORRECTION OF USTAR +! BELJARS CORRECTION OF USTAR ! used to correct friction velocity (yuqi) ! ---------------------------------------------------------------------- DU2 = MAX (SFCSPD * SFCSPD,EPSU2) !cc If statements to avoid TANGENT LINEAR problems near zero @@ -3210,38 +4163,39 @@ SUBROUTINE SFCDIF_URB (ZLM,Z0,THZ0,THLM,SFCSPD,AKANDA,AKMS,AKHS,RLMO,CD,ZT_OUT,V ! ---------------------------------------------------------------------- ! ZILITINKEVITCH APPROACH FOR ZT ! ---------------------------------------------------------------------- - USTAR = MAX (SQRT (AKMS * SQRT (DU2+ WSTAR2)),EPSUST) + USTAR = MAX (SQRT (AKMS * SQRT (DU2+ WSTAR2)),EPSUST) ! give an initial value of friction velocity (here AKMS might from last iteration) (yuqi) ! ---------------------------------------------------------------------- ! KCL/TL Try Kanda approach instead (Kanda et al. 2007, JAMC) ! ZT = EXP (ZILFC * SQRT (USTAR * Z0))* Z0 - IF (PRESENT(VEGFRAC)) THEN + IF (PRESENT(VEGFRAC)) THEN ! commented out in HRLDAS (yuqi) ! Kawai et al. (2009) JAMC ZT = EXP (2.0-(AKANDA-0.9*VEGFRAC**0.29)*(SQVISC**2 * USTAR * Z0)**0.25)* Z0 ELSE - ZT = EXP (2.0-AKANDA*(SQVISC**2 * USTAR * Z0)**0.25)* Z0 + ZT = EXP (2.0-AKANDA*(SQVISC**2 * USTAR * Z0)**0.25)* Z0 ! thermal roughness length (yuqi) END IF - ZSLU = ZLM + ZU + ZSLU = ZLM + ZU ! effective momentum surface layer depth (yuqi) - ZSLT = ZLM + ZT + ZSLT = ZLM + ZT ! effective thermal surface layer depth (yuqi) RLOGU = log (ZSLU / ZU) RLOGT = log (ZSLT / ZT) - RLMO = ELFC * AKHS * DTHV / USTAR **3 + RLMO = ELFC * AKHS * DTHV / USTAR **3 ! RLMO: 1/Obukhov length, AKHS is w'theta_v' term which is to be parameterized (yuqi) ! ---------------------------------------------------------------------- ! 1./MONIN-OBUKKHOV LENGTH-SCALE ! ---------------------------------------------------------------------- DO ITR = 1,ITRMX - ZETALT = MAX (ZSLT * RLMO,ZTMIN) + ZETALT = MAX (ZSLT * RLMO,ZTMIN) ! before each iternation, first calculate ZETALT (which is dimensionless stability parameter, which is ζ=z/L) (yuqi) RLMO = ZETALT / ZSLT ZETALU = ZSLU * RLMO - ZETAU = ZU * RLMO + ZETAU = ZU * RLMO ! dimensionless stability parameter for momentum at surface layer, which is ζm=zm/L + ZETAT = ZT * RLMO ! dimensionless stability parameter for heat at surface layer, which is ζh=zh/L + - ZETAT = ZT * RLMO IF (ILECH .eq. 0) THEN - IF (RLMO .lt. 0.0)THEN + IF (RLMO .lt. 0.0)THEN ! unstable condition where ζ<0 (yuqi) XLU4 = 1. -16.* ZETALU XLT4 = 1. -16.* ZETALT XU4 = 1. -16.* ZETAU @@ -3257,7 +4211,7 @@ SUBROUTINE SFCDIF_URB (ZLM,Z0,THZ0,THLM,SFCSPD,AKANDA,AKMS,AKHS,RLMO,CD,ZT_OUT,V SIMM = PSPMU (XLU) - PSMZ + RLOGU PSHZ = PSPHU (XT) SIMH = PSPHU (XLT) - PSHZ + RLOGT - ELSE + ELSE ! stable condition where ζ>0 (yuqi) ZETALU = MIN (ZETALU,ZTMAX) ZETALT = MIN (ZETALT,ZTMAX) PSMZ = PSPMS (ZETAU) @@ -3282,44 +4236,44 @@ SUBROUTINE SFCDIF_URB (ZLM,Z0,THZ0,THLM,SFCSPD,AKANDA,AKMS,AKHS,RLMO,CD,ZT_OUT,V PSHZ = PSLHS (ZETAT) SIMH = PSLHS (ZETALT) - PSHZ + RLOGT END IF + END IF ! ---------------------------------------------------------------------- -! BELJAARS CORRECTION FOR USTAR +! BELJAARS CORRECTION FOR USTAR ! BELJAARS conflict with BelJARS (yuqi) ! ---------------------------------------------------------------------- - END IF - USTAR = MAX (SQRT (AKMS * SQRT (DU2+ WSTAR2)),EPSUST) + + USTAR = MAX (SQRT (AKMS * SQRT (DU2+ WSTAR2)),EPSUST) ! update Ustar since AKMS has been updated by SIMM (yuqi) !KCL/TL !ZT = EXP (ZILFC * SQRT (USTAR * Z0))* Z0 - IF (PRESENT(VEGFRAC)) THEN + IF (PRESENT(VEGFRAC)) THEN ! they comment this in the new version (yuqi) ! Kawai et al. (2009) JAMC ZT = EXP (2.0-(AKANDA-0.9*VEGFRAC**0.29)*(SQVISC**2 * USTAR * Z0)**0.25)* Z0 - ELSE - ZT = EXP (2.0-AKANDA*(SQVISC**2 * USTAR * Z0)**0.25)* Z0 - END IF + ELSE + ZT = EXP (2.0-AKANDA*(SQVISC**2 * USTAR * Z0)**0.25)* Z0 ! update ZT (yuqi) + END IF ZSLT = ZLM + ZT RLOGT = log (ZSLT / ZT) USTARK = USTAR * VKRM - AKMS = MAX (USTARK / SIMM,CXCH) + AKMS = MAX (USTARK / SIMM,CXCH) ! update AKMS and AKHS (yuqi) AKHS = MAX (USTARK / SIMH,CXCH) ! IF (BTGH * AKHS * DTHV .ne. 0.0) THEN - WSTAR2 = WWST2* ABS (BTGH * AKHS * DTHV)** (2./3.) + WSTAR2 = WWST2* ABS (BTGH * AKHS * DTHV)** (2./3.) ! update WSTAR2 (yuqi) ELSE WSTAR2 = 0.0 END IF !----------------------------------------------------------------------- - RLMN = ELFC * AKHS * DTHV / USTAR **3 + RLMN = ELFC * AKHS * DTHV / USTAR **3 ! updata the 1/L (yuqi) !----------------------------------------------------------------------- ! IF(ABS((RLMN-RLMO)/RLMA).LT.EPSIT) GO TO 110 !----------------------------------------------------------------------- - RLMA = RLMO * WOLD+ RLMN * WNEW + RLMA = RLMO * WOLD+ RLMN * WNEW ! performe a weighted average of the previous RLMO and the newly calculated RLMN (yuqi) !----------------------------------------------------------------------- - RLMO = RLMA + RLMO = RLMA ! assgin to the RLMO and finally get inversed MO length which is 1/L (yuqi) END DO - CD = USTAR*USTAR/SFCSPD**2 - - IF (PRESENT(ZT_OUT)) ZT_OUT = ZT + CD = USTAR*USTAR/SFCSPD**2 ! calculate the drag coefficient (yuqi) + IF (PRESENT(ZT_OUT)) ZT_OUT = ZT ! they comment this in the new version (yuqi) ! ---------------------------------------------------------------------- END SUBROUTINE SFCDIF_URB ! ---------------------------------------------------------------------- @@ -3345,7 +4299,6 @@ SUBROUTINE DIREVAP (EDIR,ETP,SMC,SHDFAC,SMCMAX,SMCDRY,FXEXP) FX = 0. ENDIF EDIR = FX * ( 1.0- SHDFAC ) * ETP * 0.001 - END SUBROUTINE DIREVAP !=========================================================================== ! TRANSP @@ -3384,7 +4337,7 @@ SUBROUTINE TRANSP (ETT,ET,EC,SHDFAC,ETP1,CMC,CFACTR,CMCMAX,LAI,RSMIN,RSMAX,RGL,S ! ---------------------------------------------------------------------- ! CONTRIBUTION DUE TO INCOMING SOLAR RADIATION ! ---------------------------------------------------------------------- - FF = 0.55*2.0* SX*697.7 * 60/ (RGL * LAI) + FF = 0.55*2.0* SX*697.7 * 60./ (RGL * LAI) RCS = (FF + RSMIN / RSMAX) / (1.0+ FF) RCS = MAX (RCS,0.0001) ! ---------------------------------------------------------------------- @@ -3421,7 +4374,7 @@ SUBROUTINE TRANSP (ETT,ET,EC,SHDFAC,ETP1,CMC,CFACTR,CMCMAX,LAI,RSMIN,RSMAX,RGL,S RCSOIL = MAX (RCSOIL,0.0001) - RC = RSMIN / (LAI * RCS * RCT * RCQ * RCSOIL) + RC = RSMIN / (LAI * RCS * RCT * RCQ * RCSOIL) ! canopy resistance (yuqi) DESDT = 0.622*SLV*EA/461.51/TA/TA/1013 DELTA = (SLV / CPP)* DESDT RR = (4.* EPSV *SIGMA * 287.04 / CPP)* (TA **4.)/ (TS * CH) + 1.0 @@ -3443,12 +4396,12 @@ SUBROUTINE TRANSP (ETT,ET,EC,SHDFAC,ETP1,CMC,CFACTR,CMCMAX,LAI,RSMIN,RSMAX,RGL,S DO K = 1, NROOT ET(K) = ETT1 * GX (K) / DENOM - ETT = ETT + ET (K) + ETT = ETT + ET (K) ! Evapotranspiration from all the layers (yuqi) END DO IF (CMC > 0.0) THEN - EC = SHDFAC * ( ( CMC / CMCMAX ) ** CFACTR ) * ETP1 * 0.001 + EC = SHDFAC * ( ( CMC / CMCMAX ) ** CFACTR ) * ETP1 * 0.001 ! evaporation of precipitation intercepted by the canopy (yuqi) ELSE EC = 0.0 END IF @@ -3461,7 +4414,7 @@ END SUBROUTINE TRANSP ! ---------------------------------------------------------------------- SUBROUTINE SMFLX (SMCP,SMC,NSOIL,CMCP,CMC,DT,PRCP1,ZSOIL, & - & SMCMAX,BEXP,SMCWLT,DKSAT,DWSAT, & + & SMCMAX,BEXP,SMCWLT,SROOT,DKSAT,DWSAT, & ! added sroot variable (yuqi) & SHDFAC,CMCMAX,RUNOFF1,RUNOFF2,RUNOFF3, & EDIR,EC,ET,DRIP) @@ -3477,7 +4430,7 @@ SUBROUTINE SMFLX (SMCP,SMC,NSOIL,CMCP,CMC,DT,PRCP1,ZSOIL, & REAL, INTENT(OUT) :: DRIP, RUNOFF1, RUNOFF2, RUNOFF3 REAL, INTENT(IN) :: CMCP REAL, INTENT(OUT) :: CMC - REAL, DIMENSION(1:NSOIL), INTENT(IN) :: ZSOIL, ET + REAL, DIMENSION(1:NSOIL), INTENT(IN) :: ZSOIL, ET, SROOT REAL, DIMENSION(1:NSOIL), INTENT(IN) :: SMCP REAL, DIMENSION(1:NSOIL), INTENT(OUT) :: SMC REAL, DIMENSION(1:NSOIL) :: AI, BI, CI, STCF,RHSTS, RHSTT @@ -3488,24 +4441,24 @@ SUBROUTINE SMFLX (SMCP,SMC,NSOIL,CMCP,CMC,DT,PRCP1,ZSOIL, & ! ADD PRECIPITATION TO EXISTING CMC.IF RESULTING AMT EXCEEDS MAX CAPACITY, ! IT BECOMES DRIP AND WILL FALL TO THE GRND. ! ---------------------------------------------------------------------- - RHSCT = SHDFAC * PRCP1 * 0.001 /3600. - EC + RHSCT = SHDFAC * PRCP1 * 0.001 /3600. - EC ! how many water currently in the canopy after rain (gain) and evaporation (loss) (yuqi) DRIP = 0. TRHSCT = DT * RHSCT - EXCESS = CMCP + TRHSCT + EXCESS = CMCP + TRHSCT ! update the current canopy water (yuqi) ! ---------------------------------------------------------------------- ! PCPDRP IS THE COMBINED PRCP1 AND DRIP (FROM CMCP) THAT GOES INTO THE ! SOIL ! ---------------------------------------------------------------------- IF (EXCESS > CMCMAX) DRIP = EXCESS - CMCMAX - PCPDRP = (1. - SHDFAC) * PRCP1 * 0.001 /3600. + DRIP / DT + PCPDRP = (1. - SHDFAC) * PRCP1 * 0.001 /3600. + DRIP / DT ! total surfce water influx (yuqi) ! ---------------------------------------------------------------------- ! CALL SUBROUTINES SRT AND SSTEP TO SOLVE THE SOIL MOISTURE ! TENDENCY EQUATIONS. ! ---------------------------------------------------------------------- CALL SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT,DKSAT, & - SMCMAX,BEXP,RUNOFF1,RUNOFF2,DT,SMCWLT,AI,BI,CI) + SMCMAX,BEXP,RUNOFF1,RUNOFF2,DT,SMCWLT,SROOT,AI,BI,CI) CALL SSTEP (SMCP,SMC,CMCP,CMC,RHSTT,RHSCT,DT,NSOIL,SMCMAX, & CMCMAX,RUNOFF3,ZSOIL,AI,BI,CI) @@ -3515,7 +4468,7 @@ END SUBROUTINE SMFLX SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & DKSAT,SMCMAX,BEXP,RUNOFF1, & - RUNOFF2,DT,SMCWLT,AI,BI,CI) + RUNOFF2,DT,SMCWLT,SROOT,AI,BI,CI) ! ---------------------------------------------------------------------- ! CALCULATE THE RIGHT HAND SIDE OF THE TIME TENDENCY TERM OF THE SOIL @@ -3529,7 +4482,7 @@ SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & REAL, INTENT(IN) :: BEXP, DKSAT, DT, DWSAT, EDIR, & PCPDRP, SMCMAX, SMCWLT REAL, INTENT(OUT) :: RUNOFF1, RUNOFF2 - REAL, DIMENSION(1:NSOIL), INTENT(IN) :: SMCP, ZSOIL, ET + REAL, DIMENSION(1:NSOIL), INTENT(IN) :: SMCP, ZSOIL, ET, SROOT REAL, DIMENSION(1:NSOIL), INTENT(OUT) :: RHSTT REAL, DIMENSION(1:NSOIL), INTENT(OUT) :: AI, BI, CI REAL, DIMENSION(1:NSOIL) :: DDMAX @@ -3558,7 +4511,7 @@ SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & DDMAX (3) = (ZSOIL (2) - ZSOIL (3))* SMCAV DDMAX (3) = DDMAX (3)* (1.0- (SMCP (3) - SMCWLT)/ SMCAV) - DD = DDMAX(1)+DDMAX(2)+DDMAX(3) + DD = DDMAX(1)+DDMAX(2)+DDMAX(3) ! accumulated maximum holdable soil water for all three layers (yuqi) DT1 = DT/86400 KDT = 3.0 * DKSAT / PAR VAL = (1. - EXP ( - KDT * DT1)) @@ -3566,7 +4519,7 @@ SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & PX = PCPDRP * DT IF (PX < 0.0) PX = 0.0 - INFMAX = (PX * (DDT / (PX + DDT)))/ DT + INFMAX = (PX * (DDT / (PX + DDT)))/ DT ! identical to 'InfilRateMax' in Noah_MP schaake scheme (yuqi) MXSMC = SMCP (1) CALL WDFCND (WDF,WCND,MXSMC,SMCMAX,BEXP,DKSAT,DWSAT) INFMAX = MAX (INFMAX,WCND) @@ -3574,7 +4527,7 @@ SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & IF (PCPDRP > INFMAX) THEN - RUNOFF1 = PCPDRP - INFMAX + RUNOFF1 = PCPDRP - INFMAX ! runoff1 is excess infiltration runoff (yuqi) PDDUM = INFMAX END IF END IF @@ -3586,9 +4539,9 @@ SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & AI (1) = 0.0 BI (1) = WDF * DDZ / ( - ZSOIL (1) ) CI (1) = - BI (1) - DSMDZ = (SMCP (1) - SMCP (2) )/( - 0.5 * ZSOIL(2)) - RHSTT (1) = (WDF * DSMDZ + WCND- PDDUM + EDIR + ET(1))/ ZSOIL (1) - SSTT = WDF * DSMDZ + WCND+ EDIR + ET(1) + DSMDZ = (SMCP (1) - SMCP (2) )/( - 0.5 * ZSOIL(2)) ! Eq.3.7.253 (i=1) in noah_mp decument (yuqi) + RHSTT (1) = (WDF * DSMDZ + WCND- PDDUM + EDIR + ET(1)+ SROOT(1))/ ZSOIL (1) ! should minus conductivity between two layers (yuqi) + SSTT = WDF * DSMDZ + WCND+ EDIR + ET(1) ! DON'T KNOW WHAT IS THIS, maybe for testing purpose (yuqi) ! ---------------------------------------------------------------------- ! LOOP THRU THE REMAINING SOIL LAYERS, REPEATING THE ABV PROCESS @@ -3609,12 +4562,12 @@ SUBROUTINE SRT (RHSTT,EDIR,ET,SMCP,NSOIL,PCPDRP,ZSOIL,DWSAT, & CI (K) = 0.0 END IF NUMER = (WDF2 * DSMDZ2) - (WDF * DSMDZ) & - - WCND+ ET(K) + - WCND+ ET(K) +SROOT(K) RHSTT (K) = NUMER / ( - DENOM2) AI (K) = - WDF * DDZ / DENOM2 BI (K) = - ( AI (K) + CI (K) ) IF (K .eq. NSOIL-1) THEN - RUNOFF2 = 0.0 + RUNOFF2 = 0.0 ! subsurface runoff for layer 2 (yuqi) END IF IF (K .ne. NSOIL-1) THEN WDF = WDF2 @@ -3657,8 +4610,8 @@ SUBROUTINE SSTEP (SMCP,SMC,CMCP,CMC,RHSTT,RHSCT,DT, & ! CREATE 'AMOUNT' VALUES OF VARIABLES TO BE INPUT TO THE ! TRI-DIAGONAL MATRIX ROUTINE. ! ---------------------------------------------------------------------- - DO K = 1,NSOIL-1 - RHSTT (K) = RHSTT (K) * DT + DO K = 1,NSOIL-1 ! E.q. 3.7.265 in noah_mp document (yuqi) + RHSTT (K) = RHSTT (K) * DT ! update matric coefficient to solve the saturation excess water for each soil layer (yuqi) AI (K) = AI (K) * DT BI (K) = 1. + BI (K) * DT CI (K) = CI (K) * DT @@ -3687,7 +4640,7 @@ SUBROUTINE SSTEP (SMCP,SMC,CMCP,CMC,RHSTT,RHSCT,DT, & DDZ = - ZSOIL (1) DO K = 1,NSOIL-1 IF (K /= 1) DDZ = ZSOIL (K - 1) - ZSOIL (K) - SMCOUT (K) = SMCP (K) + CI (K) + WPLUS / DDZ + SMCOUT (K) = SMCP (K) + CI (K) + WPLUS / DDZ ! previous soil moisture + updated soil water + soil water surplus from above layer (yuqi) STOT = SMCOUT (K) IF (STOT > SMCMAX) THEN IF (K .eq. 1) THEN @@ -3700,14 +4653,14 @@ SUBROUTINE SSTEP (SMCP,SMC,CMCP,CMC,RHSTT,RHSCT,DT, & ELSE WPLUS = 0. END IF - SMC (K) = MAX ( MIN (STOT,SMCMAX),0.066 ) + SMC (K) = MAX ( MIN (STOT,SMCMAX),0.07 ) ! change 0.066 to 0.07 in order to avoid floating invalid error in root_uptake step (Yuqi) END DO ! ---------------------------------------------------------------------- ! UPDATE CANOPY WATER CONTENT/INTERCEPTION (CMC). CONVERT RHSCT TO ! AN 'AMOUNT' VALUE AND ADD TO PREVIOUS CMC VALUE TO GET NEW CMC. ! ---------------------------------------------------------------------- - RUNOFF3 = WPLUS + RUNOFF3 = WPLUS ! subsurface runoff for layer 3 (yuqi) CMC = CMCP + DT * RHSCT IF (CMC < 1.E-20) CMC = 0.0 CMC = MIN (CMC,CMCMAX) @@ -3783,7 +4736,7 @@ SUBROUTINE ROSR12 (P,A,B,C,D,DELTA,NSOIL) ! ---------------------------------------------------------------------- ! INITIALIZE EQN COEF C FOR THE LOWEST SOIL LAYER ! ---------------------------------------------------------------------- - C (NSOIL) = 0.0 + C (NSOIL) = 0.0 ! follow E.q 3.7.294-3.7.301 in noah_mp document (yuqi) P (1) = - C (1) / B (1) DELTA (1) = D (1) / B (1) DO K = 2,NSOIL @@ -3801,7 +4754,7 @@ SUBROUTINE ROSR12 (P,A,B,C,D,DELTA,NSOIL) ! ---------------------------------------------------------------------- DO K = 2,NSOIL KK = NSOIL - K + 1 - P (KK) = P (KK) * P (KK +1) + DELTA (KK) + P (KK) = P (KK) * P (KK +1) + DELTA (KK) ! E.q 3.7.301 in noah_mp document (yuqi) END DO ! ---------------------------------------------------------------------- END SUBROUTINE ROSR12 @@ -3825,7 +4778,7 @@ SUBROUTINE SHFLX (SSOIL,STC,SMC,SMCMAX,NSOIL,T1,DT,YY,ZZ1,ZSOIL, & REAL, INTENT(IN) :: DF1,DT,SMCMAX, SMCWLT, TBOT,YY, ZBOT,ZZ1, QUARTZ REAL, INTENT(IN) :: CSOIL, CAPR REAL, INTENT(INOUT) :: T1 - REAL, INTENT(OUT) :: SSOIL + REAL, INTENT(OUT) :: SSOIL ! output : soil heat flux, w/m-2 (yuqi) REAL, DIMENSION(1:NSOIL), INTENT(IN) :: SMC,ZSOIL REAL, DIMENSION(1:NSOIL), INTENT(INOUT) :: STC REAL, DIMENSION(1:NSOIL) :: AI, BI, CI, STCF,RHSTS @@ -3959,12 +4912,12 @@ SUBROUTINE HRT (RHSTS,STC,SMC,SMCMAX,NSOIL,ZSOIL,YY,ZZ1, & IF (ITAVG) THEN CALL TBND (STC (K),TBOT,ZSOIL,ZBOT,K,NSOIL,TBK1) END IF - ELSE + ELSE !(k=nsoil, for last layer) (yuqi) ! ---------------------------------------------------------------------- ! SPECIAL CASE OF BOTTOM LAYER (CONCRETE ROOF) ! ---------------------------------------------------------------------- HCPCT = CAPR * 4.1868 * 1.E6 - DF1K = 3.24 + DF1K = 3.24 ! default in NOAH_MP technical notebook page 47 (yuqi) ! ---------------------------------------------------------------------- ! CALC THE VERTICAL TEMP GRADIENT THRU BOTTOM LAYER. ! ---------------------------------------------------------------------- @@ -4175,8 +5128,7 @@ SUBROUTINE TDFCND (DF, SMC, QZ, SMCMAX) ! ---------------------------------------------------------------------- END SUBROUTINE TDFCND ! ---------------------------------------------------------------------- - - FUNCTION kanda_kawai_svf(lp, lf) RESULT (svf) +FUNCTION kanda_kawai_svf(lp, lf) RESULT (svf) IMPLICIT NONE real, intent(in) :: lp, lf real :: hovl, vloc, vmod, svf @@ -4188,4 +5140,447 @@ FUNCTION kanda_kawai_svf(lp, lf) RESULT (svf) END FUNCTION kanda_kawai_svf !=========================================================================== + + +! ---------------------------------------------------------------------- +! SHADOW_TREE : CALCULATE SHADOW CAST BY TREES AND WALLS (Huang) +! ---------------------------------------------------------------------- + SUBROUTINE SHADOW_TREE (XI, H, W, HTREE, RTREE, DTREE, CHI_SHADED, ETA_SHADED, & + CHI_SHADED_TREE, ETA_SHADED_TREE) + + IMPLICIT NONE + + REAL, INTENT(IN) :: XI , H, W, HTREE, RTREE, DTREE + REAL, INTENT(OUT) :: CHI_SHADED, ETA_SHADED, CHI_SHADED_TREE, ETA_SHADED_TREE + REAL :: XI_A, XI_B, X0, Y0, X1, X2, Y1, Y2, CHI_TREE, ETA_TREE + ! CHI: SHADOW ON THE GROUND; ETA: SHADOW ON THE WALL + + XI_A = SQRT(1 + XI**2) + XI_B = SQRT(1 + XI**(-2)) + + X0 = MAX(0.0, W - H * XI) + Y0 = MAX(0.0, H - W / XI) + + X1 = MAX(0.0, DTREE - HTREE * XI - RTREE * XI_A) + X2 = MAX(0.0, DTREE - HTREE * XI + RTREE * XI_A) + + Y1 = MAX(0.0, HTREE - DTREE / XI - RTREE * XI_B) + Y2 = MAX(0.0, HTREE - DTREE / XI + RTREE * XI_B) + + CHI_TREE = X2 - X1 + ETA_TREE = Y2 - Y1 + + !----------------------------------------------------------------- + ! SHADOW LENGTH ON THE GROUND BY WALL2 AND TREE + !----------------------------------------------------------------- + IF (X2 .le. X0) THEN + CHI_SHADED = W - X0 + CHI_TREE + CHI_SHADED_TREE = CHI_TREE + ELSEIF (X1 .le. X0 .and. X0 .lt. X2) THEN + CHI_SHADED = W - X0 + CHI_TREE - (X2 - X0) + CHI_SHADED_TREE = CHI_TREE - (X2 - X0) + ELSE + CHI_SHADED = W - X0 + CHI_SHADED_TREE = 0 + END IF + + !----------------------------------------------------------------- + ! SHADOW LENGTH ON THE WALL BY WALL2 AND TREE + !----------------------------------------------------------------- + IF (Y2 .le. Y0) THEN + ETA_SHADED = Y0 + ETA_SHADED_TREE = 0 + ELSEIF (Y1 .le. Y0 .and. Y0 .lt. Y2) THEN + ETA_SHADED = Y2 + ETA_SHADED_TREE = Y2 - Y0 + ELSE + ETA_SHADED = Y0 + ETA_TREE + ETA_SHADED_TREE = ETA_TREE + END IF + +! ---------------------------------------------------------------------- + END SUBROUTINE SHADOW_TREE +! ---------------------------------------------------------------------- + +! ---------------------------------------------------------------------- +! STOMATAL : CALCULATE LEAF STOMATAL RESISTANCE (Huang) +! ---------------------------------------------------------------------- + SUBROUTINE STOMATAL(RS, RSMIN, SD_FACET, LAI, W2, WR, WS, TA, TS, QA, QSAT) + + IMPLICIT NONE + + REAL, INTENT(IN) :: RSMIN, SD_FACET, LAI, W2, WR, WS, TA, TS, QA, QSAT + REAL, INTENT(OUT) :: RS + REAL :: F, FSR, F_THETA, TSC, FE, FT, LAI_EFF + REAL, PARAMETER :: SD_LIM = 30 + REAL, PARAMETER :: RSMAX = 5000 + REAL, PARAMETER :: HS = 54.53 + + LAI_EFF = LAI + IF (LAI_EFF < 0.01) THEN + LAI_EFF = 0.01 + END IF + + F = 0.55 * (SD_FACET/SD_LIM) * 2/LAI_EFF + FSR = (F + RSMIN/RSMAX)/(1 + F) + FSR = MAX(FSR, 0.0001) + + IF (W2 .gt. 0.75 * WS) THEN + F_THETA = 1 + ELSEIF (W2 .ge. WR .and. W2 .le. 0.75 * WS) THEN + F_THETA = (W2 - WR)/(0.75 * WS - WR) + ELSEIF (W2 .lt. WR) THEN + F_THETA = 0 + ENDIF + + F_THETA= MAX(F_THETA, 0.0001) + + TSC = TS - 273.15 + + FE = 1/(1 + HS * (QSAT - QA)) + FE = MAX(FE, 0.01) + + FT = 1 - 0.0016 * (298 - Ta)**2 + FT = MAX(FT, 0.0001) + + RS = RSMIN/LAI/FSR/F_THETA/FE/FT + +! ---------------------------------------------------------------------- + END SUBROUTINE STOMATAL +! ---------------------------------------------------------------------- + + +! ---------------------------------------------------------------------- +! LELEAF : CALCULATE LATENT HEAT OF TREE LEAF (Huang) +! ---------------------------------------------------------------------- + + SUBROUTINE LELEAF (LE, SW, LW, RA_LEAF, RS_LEAF, RA, TA, QA, QSAT) + + IMPLICIT NONE + + REAL, INTENT(IN) :: SW, LW, RA_LEAF, RS_LEAF, RA, TA, QA, QSAT + REAL, INTENT(OUT) :: LE + REAL :: RN, TC, S, ESAT, RH, EA, D + REAL, PARAMETER :: GAMMA = 66.1 + REAL, PARAMETER :: CP = 1005 + + RN = SW + LW + TC = TA - 273.15 + + S = 2508.3 * 1000 /(TC + 237.3)/(TC + 237.3) * EXP((17.3 * TC)/(TC + 237.3)) + ESAT = 611 * EXP((17.3 * TC)/(TC + 237.3)) + RH = QA/QSAT + EA = ESAT * RH + D = ESAT - EA + + LE = (S * RN + 0.93 * RA * CP * D/RA_LEAF)/(S + 0.93 * GAMMA * (2 + RS_LEAF/RA_LEAF)) + +! ---------------------------------------------------------------------- + END SUBROUTINE LELEAF +! ---------------------------------------------------------------------- + + +! ---------------------------------------------------------------------- +! force_restore_tree (Huang) +! Refer to Sang and Soon, BLM, 2007 +! ---------------------------------------------------------------------- + + SUBROUTINE force_restore_tree(DELT,S,R,H,LE,LAI,TSP,TS) + IMPLICIT NONE + + REAL, INTENT(IN) :: DELT,S,R,H,LE,LAI,TSP + REAL, INTENT(OUT) :: TS + REAL :: C + + ! C = 4186 * LAI + C = 640 !(heat capacity per unit leaf area: 640 J/m2/K) + + TS = TSP + DELT* (S+R-H-LE)/C + +! ---------------------------------------------------------------------- + END SUBROUTINE force_restore_tree +! ---------------------------------------------------------------------- + + +! ---------------------------------------------------------------------- +! ROOT WATER UPTAKE (Huang) +! FOLLOWING NOAH_MP, C. He, P. Valayamkunnath, & refactor team (He et al. 2023) +! ---------------------------------------------------------------------- + + SUBROUTINE ROOT_UPTAKE(SROOT, NLAYER, SMC, SMCMAX, SMCDRY, RTREE, LAI_TREE, DZG, ZSOIL, ELE, FVG, RW) + + INTEGER, INTENT(IN) :: NLAYER + REAL, DIMENSION(1:NLAYER), INTENT(IN) :: SMC, DZG, ZSOIL + REAL, INTENT(IN) :: SMCMAX, SMCDRY, RTREE, LAI_TREE, FVG, RW, ELE + REAL, DIMENSION(1:NLAYER), INTENT(OUT) :: SROOT !(UNIT: M/S) + REAL, DIMENSION(1:NLAYER) :: NORMQ, ALPHAI, ROOT, PART2 + REAL :: ALPHABAR , PART1 + REAL, PARAMETER :: QC1 = 0.6 + REAL, PARAMETER :: QC2 = 1.0 + REAL, PARAMETER :: Lv = 2.26E6 + REAL, PARAMETER :: rWD = 1.E3 ! density of water [kg/m3] + + IF (FVG <= 0.0 .OR. RW <= 0.0 .OR. RTREE <= 0.0 .OR. LAI_TREE <= 0.0) THEN + SROOT(:) = 0.0 + RETURN + END IF + + DO K = 1, NLAYER + NORMQ(K) = (SMC(K) - SMCDRY)/(SMCMAX - SMCDRY) + IF (NORMQ(K) .gt. QC2) THEN + ALPHAI(K) = 1. + ELSEIF (NORMQ(K) .ge. QC1 .and. NORMQ(K) .le. QC2) THEN + ALPHAI(K) = 1. + ELSEIF (NORMQ(K) .lt. QC1 .and. NORMQ(K) .ge. 0) THEN + ALPHAI(K) = NORMQ(K)/QC1 + ELSE + ALPHAI(K) = 0.0 + END IF + END DO + + DO K = 1, NLAYER + ROOT(K) = DZG(K) / (-ZSOIL(NLAYER)) + END DO + + ALPHABAR = 0 + DO K = 1, NLAYER + ALPHABAR = ALPHABAR + ROOT(K)*ALPHAI(K) + END DO + + IF (ALPHABAR <= 1.0E-12) THEN + SROOT(:) = 0.0 + RETURN + END IF + + DO K = 1, NLAYER + PART1 = 2 * RTREE * LAI_TREE * (ELE/Lv)/rWD + PART2(K) = ROOT(K) * ALPHAI(K)/ALPHABAR + SROOT(K) = PART1*PART2(K)/(FVG*RW) + END DO + +! ---------------------------------------------------------------------- + END SUBROUTINE ROOT_UPTAKE +! ---------------------------------------------------------------------- + +! ---------------------------------------------------------------------- + SUBROUTINE VF_TREE_ANALYTICAL(W, H, ht, rt, trans, & + FGS, FGW, FGT, FWS, FWG, FWW, FWT, FTS, FTG, FTW) +! ---------------------------------------------------------------------- + ! This subroutine calculates the view factors in a street canyon with a tree, based on the semi-analytical method + ! + IMPLICIT NONE + + ! Input arguments + REAL, INTENT(IN) :: W, H, ht, rt, trans + + ! Output arguments + REAL, INTENT(OUT) :: FGS, FGW, FGT, FWS, FWG, FWW, FWT, FTS, FTG, FTW + + ! Local variables + REAL :: dx, dy, tau + REAL :: FWW_emp, FWG_emp, FWS_emp, FSG_emp, FSW_emp, FGS_emp, FGW_emp + REAL :: FSW, FSG, FST + REAL :: FWW_cf1, FWS_cf1, FWG_cf1, FWW_cf2, FWS_cf2, FWG_cf2 + REAL :: FGS_cf1, FGW_cf1, FGS_cf2, FGW_cf2 + REAL :: FSW_cf1, FSG_cf1, FSW_cf2, FSG_cf2 + REAL :: y, d1, theta_blocked_ww, theta_range_ww, theta_blocked_ws, theta_range_ws, theta_blocked_wg, theta_range_wg + REAL :: x, d2, theta_blocked_gs, theta_range_gs, theta_blocked_gw, theta_range_gw + REAL :: theta_blocked_sw, theta_range_sw, theta_blocked_sg, theta_range_sg + REAL :: A_S, A_G, A_W, A_T + REAL :: sum_T, resid_T, A_sum_T + REAL :: sum_W, resid_W, A_sum_W + REAL :: sum_G, resid_G, A_sum_G + REAL :: sum_S, resid_S, A_sum_S + REAL, PARAMETER :: PI = 3.141592653589793 + INTEGER :: i + + ! Check constraints + IF ((2.*rt > W) .OR. (ht + rt > H)) THEN + CALL wrf_error_fatal('Invalid tree geometry in VF_TREE_ANALYTICAL: 2*rt must be <= W and ht + rt <= H') + END IF + + ! Spatial integration step + dx = W / 20.0 + dy = H / 20.0 + + tau = trans + + ! Empty canyon view factors (each wall) + FWW_emp = SQRT(1.+(W/H)**2) - W/H ! Wall->Wall + FWG_emp = (1.-FWW_emp)/2. ! Wall->Ground + FWS_emp = FWG_emp ! Wall->Sky + FSG_emp = SQRT(1.+(H/W)**2) - H/W ! Sky->Ground + FSW_emp = (1.-FSG_emp)/2. ! Sky->Wall + FGS_emp = FSG_emp ! Ground->Sky + FGW_emp = (1.-FGS_emp)/2. ! Ground->Wall + + ! analytical solutions + ! Tree-to-surface view factors + FTW = (1./PI) * ATAN(H / W) + FTS = (1./PI) * ATAN(W / (2. * (H - ht))) + FTG = (1./PI) * ATAN(W / (2. * ht)) + + ! Reciprocal + FWT = (2. * rt / H) * ATAN(H / W) + FGT = (2. * rt / W) * ATAN(W / (2. * ht)) + FST = (2. * rt / W) * ATAN(W / (2. * (H - ht))) + + ! transmissivity + FWT = FWT * (1. - tau) + FST = FST * (1. - tau) + FGT = FGT * (1. - tau) + + ! wall-to-surface view factors + ! correction factor + FWW_cf1 = 0.0; FWS_cf1 = 0.0; FWG_cf1 = 0.0 + FWW_cf2 = 0.0; FWS_cf2 = 0.0; FWG_cf2 = 0.0 + + DO i = 1, NINT(H/dy) + y = dy * i - dy/2. + d1 = SQRT((W/2.)**2 + (y - ht)**2) + theta_blocked_ww = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((ht - y)/(W/2.)) + ASIN(rt / d1), PI/2. + ATAN((H - y)/W))) - & + cdf2D_VF(MAX(PI/2. + ATAN((ht - y)/(W/2.)) - ASIN(rt / d1), ATAN(W/y))) & + ) + theta_range_ww = cdf2D_VF(PI/2. + ATAN((H - y)/W)) - cdf2D_VF(ATAN(W/y)) + theta_blocked_ww = theta_blocked_ww*(1.-tau) + FWW_cf1 = FWW_cf1 + dy * (theta_range_ww-theta_blocked_ww) + FWW_cf2 = FWW_cf2 + dy * theta_range_ww + + theta_blocked_ws = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((ht - y)/(W/2.)) + ASIN(rt / d1), PI)) - & + cdf2D_VF(MAX(PI/2. + ATAN((ht - y)/(W/2.)) - ASIN(rt / d1), PI/2. + ATAN((H - y)/W))) & + ) + theta_range_ws = cdf2D_VF(PI) - cdf2D_VF(PI/2. + ATAN((H - y)/W)) + theta_blocked_ws = theta_blocked_ws*(1.-tau) + FWS_cf1 = FWS_cf1 + dy * (theta_range_ws-theta_blocked_ws) + FWS_cf2 = FWS_cf2 + dy * theta_range_ws + + theta_blocked_wg = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((ht - y)/(W/2.)) + ASIN(rt / d1), ATAN(W/y))) - & + cdf2D_VF(MAX(PI/2. + ATAN((ht - y)/(W/2.)) - ASIN(rt / d1), 0.0)) & + ) + theta_range_wg = cdf2D_VF(ATAN(W/y))-cdf2D_VF(0.0) + theta_blocked_wg = theta_blocked_wg*(1.-tau) + FWG_cf1 = FWG_cf1 + dy * (theta_range_wg-theta_blocked_wg) + FWG_cf2 = FWG_cf2 + dy * theta_range_wg + END DO + + ! average across all intervals + IF (FWW_cf2 > 0.0) FWW = FWW_emp * FWW_cf1 / FWW_cf2 + IF (FWS_cf2 > 0.0) FWS = FWS_emp * FWS_cf1 / FWS_cf2 + IF (FWG_cf2 > 0.0) FWG = FWG_emp * FWG_cf1 / FWG_cf2 + + ! ground-to-surface view factors + FGS_cf1 = 0.0; FGW_cf1 = 0.0 + FGS_cf2 = 0.0; FGW_cf2 = 0.0 + + DO i = 1, NINT(W/dx) + x = dx * i - dx/2. + d2 = SQRT((W/2. - x)**2 + ht**2) + theta_blocked_gs = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((x - W/2.)/ht) + ASIN(rt / d2), PI/2. + ATAN(x/H))) - & + cdf2D_VF(MAX(PI/2. + ATAN((x - W/2.)/ht) - ASIN(rt / d2), ATAN(H/(W - x)))) & + ) + theta_range_gs = cdf2D_VF(PI/2. + ATAN(x/H)) - cdf2D_VF(ATAN(H/(W - x))) + theta_blocked_gs = theta_blocked_gs*(1.-tau) + FGS_cf1 = FGS_cf1 + dx * (theta_range_gs-theta_blocked_gs) + FGS_cf2 = FGS_cf2 + dx * theta_range_gs + + theta_blocked_gw = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((x - W/2.)/ht) + ASIN(rt / d2), ATAN(H/(W - x)))) - & + cdf2D_VF(MAX(PI/2. + ATAN((x - W/2.)/ht) - ASIN(rt / d2), 0.0)) & + ) + theta_range_gw = cdf2D_VF(ATAN(H/(W - x)))-cdf2D_VF(0.0) + theta_blocked_gw = theta_blocked_gw*(1.-tau) + FGW_cf1 = FGW_cf1 + dx * (theta_range_gw-theta_blocked_gw) + FGW_cf2 = FGW_cf2 + dx * theta_range_gw + END DO + + ! average across all intervals + IF (FGW_cf2 > 0.0) FGW = FGW_emp*FGW_cf1/FGW_cf2 + IF (FGS_cf2 > 0.0) FGS = FGS_emp*FGS_cf1/FGS_cf2 + + ! sky-to-surface view factor + FSW_cf1 = 0.0; FSG_cf1 = 0.0 + FSW_cf2 = 0.0; FSG_cf2 = 0.0 + + DO i=1, NINT(W/dx) + x = dx*i-dx/2. + d2 = SQRT((W/2. - x)**2 + (H-ht)**2) + theta_blocked_sw = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((x - W/2.) / (H-ht)) + ASIN(rt / d2), ATAN(H/(W-x)))) - & + cdf2D_VF(MAX(PI/2. + ATAN((x - W/2.) / (H-ht)) - ASIN(rt / d2), 0.0)) & + ) + theta_range_sw = cdf2D_VF(ATAN(H/(W-x)))-cdf2D_VF(0.0) + theta_blocked_sw = theta_blocked_sw*(1.-tau) + FSW_cf1 = FSW_cf1 + dx * (theta_range_sw-theta_blocked_sw) + FSW_cf2 = FSW_cf2 + dx * theta_range_sw + + theta_blocked_sg = MAX(0.0, & + cdf2D_VF(MIN(PI/2. + ATAN((x - W/2.) / (H-ht)) + ASIN(rt / d2), PI/2. + ATAN(x/H))) - & + cdf2D_VF(MAX(PI/2. + ATAN((x - W/2.) / (H-ht)) - ASIN(rt / d2), ATAN(H/(W-x)))) & + ) + + theta_range_sg = cdf2D_VF(PI/2. + ATAN(x/H)) - cdf2D_VF(ATAN(H/(W-x))) + theta_blocked_sg = theta_blocked_sg*(1.-tau) + FSG_cf1 = FSG_cf1 + dx * (theta_range_sg-theta_blocked_sg) + FSG_cf2 = FSG_cf2 + dx * theta_range_sg + + END DO + + IF (FSW_cf2 > 0.0) FSW = FSW_emp*FSW_cf1/FSW_cf2 + IF (FSG_cf2 > 0.0) FSG = FSG_emp*FSG_cf1/FSG_cf2 + + ! post-correction for residuals + ! Areas + A_S = W ! Sky + A_G = W ! Ground + A_W = H ! Each wall + A_T = 2.*PI*rt ! Tree surface area + + ! TREE surface + sum_T = FTS + FTG + 2.*FTW + resid_T = 1. - sum_T + A_sum_T = A_S + A_G + 2.*A_W + FTS = FTS + resid_T * (A_S / A_sum_T) + FTG = FTG + resid_T * (A_G / A_sum_T) + FTW = FTW + resid_T * (A_W / A_sum_T) ! per wall + + ! WALL surface + sum_W = FWS + FWG + FWW + FWT + resid_W = 1. - sum_W + A_sum_W = A_S + A_G + A_W + A_T + FWS = FWS + resid_W * (A_S / A_sum_W) + FWG = FWG + resid_W * (A_G / A_sum_W) + FWW = FWW + resid_W * (A_W / A_sum_W) + FWT = FWT + resid_W * (A_T / A_sum_W) + + ! GROUND surface + sum_G = FGS + 2.*FGW + FGT + resid_G = 1. - sum_G + A_sum_G = A_S + 2.*A_W + A_T + FGS = FGS + resid_G * (A_S / A_sum_G) + FGW = FGW + resid_G * (A_W / A_sum_G) ! per wall + FGT = FGT + resid_G * (A_T / A_sum_G) + + ! SKY surface + sum_S = 2.*FSW + FSG + FST + resid_S = 1. - sum_S + A_sum_S = 2.*A_W + A_G + A_T + FSW = FSW + resid_S * (A_W / A_sum_S) ! per wall + FSG = FSG + resid_S * (A_G / A_sum_S) + FST = FST + resid_S * (A_T / A_sum_S) + + CONTAINS + ELEMENTAL PURE FUNCTION cdf2D_VF(theta) RESULT(angleCDF) + REAL :: angleCDF + REAL, INTENT(IN) :: theta + angleCDF = 0.5 * (1. - COS(theta)) + END FUNCTION cdf2D_VF + + ! ---------------------------------------------------------------------- + END SUBROUTINE VF_TREE_ANALYTICAL + ! ---------------------------------------------------------------------- + END MODULE module_sf_urban diff --git a/phys/module_surface_driver.F b/phys/module_surface_driver.F index a951af5998..1eb5a95eb2 100644 --- a/phys/module_surface_driver.F +++ b/phys/module_surface_driver.F @@ -178,7 +178,7 @@ SUBROUTINE surface_driver( & & ,dwt_livecrootn_to_cwdn,dwt_deadcrootn_to_cwdn,retransn & #endif !sw++ - ,pct_pft_input,num_pft_input,input_pft_flag & + & ,pct_pft_input,num_pft_input,input_pft_flag & !sw-- ! Optional urban & ,slope_rad,topo_shading,shadowmask & !I solar @@ -191,7 +191,9 @@ SUBROUTINE surface_driver( & & ,xxxr_urb2d,xxxb_urb2d,xxxg_urb2d,xxxc_urb2d & !H urban & ,cmcr_urb2d,tgr_urb2d,tgrl_urb3d,smr_urb3d & !H urban & ,julian,julyr,drelr_urb2d,drelb_urb2d,drelg_urb2d & !H urban - & ,flxhumr_urb2d,flxhumb_urb2d,flxhumg_urb2d & !H urban + & ,flxhumr_urb2d,flxhumb_urb2d,flxhumg_urb2d & !H urban, added by Chenghao Wang + & ,tvg_urb2d,xxxvg_urb2d,tvgl_urb3d,smg_urb3d,tt_urb2d & !H urban + & ,cmcg_urb2d,flxhumvg_urb2d,flxhumt_urb2d & !H urban & ,trl_urb3d,tbl_urb3d,tgl_urb3d & !H urban & ,sh_urb2d,lh_urb2d,g_urb2d,rn_urb2d,ts_urb2d & !H urban & ,frc_urb2d, utype_urb2d & !H urban @@ -1301,11 +1303,22 @@ SUBROUTINE surface_driver( & REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMG_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCR_URB2D REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TGR_URB2D + ! added by Chenghao Wang + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: TT_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: XXXVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: CMCG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMVG_URB2D + REAL, OPTIONAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: FLXHUMT_URB2D REAL, OPTIONAL, DIMENSION( ims:ime , 1:num_soil_layers, jms:jme ), & !urban INTENT(INOUT) :: TGRL_URB3D !urban REAL, OPTIONAL, DIMENSION( ims:ime , 1:num_soil_layers, jms:jme ), & !urban INTENT(INOUT) :: SMR_URB3D !urban + REAL, OPTIONAL, DIMENSION( ims:ime , 1:num_soil_layers, jms:jme ), & !urban + INTENT(INOUT) :: TVGL_URB3D !urban + REAL, OPTIONAL, DIMENSION( ims:ime , 1:num_soil_layers, jms:jme ), & !urban + INTENT(INOUT) :: SMG_URB3D !urban REAL, OPTIONAL, DIMENSION( ims:ime , 1:num_soil_layers, jms:jme ), & !urban INTENT(INOUT) :: TRL_URB3D !urban REAL, OPTIONAL, DIMENSION( ims:ime , 1:num_soil_layers, jms:jme ), & !urban @@ -2752,6 +2765,9 @@ SUBROUTINE surface_driver( & julian,julyr, & !H urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !H urban FLXHUMR_URB2D,FLXHUMB_URB2D,FLXHUMG_URB2D, & !H urban + ! added by Chenghao Wang + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & !H urban + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !H urban FRC_URB2D, UTYPE_URB2D, & !I urban num_urban_ndm, & !I multi-layer urban urban_map_zrd, & !I multi-layer urban @@ -2886,6 +2902,8 @@ SUBROUTINE surface_driver( & CMCR_URB2D,TGR_URB2D,TGRL_URB3D,SMR_URB3D, & !H urban DRELR_URB2D,DRELB_URB2D,DRELG_URB2D, & !H urban FLXHUMR_URB2D,FLXHUMB_URB2D,FLXHUMG_URB2D, & !H urban + TVG_URB2D,XXXVG_URB2D,TVGL_URB3D,SMG_URB3D,TT_URB2D,CMCG_URB2D, & !H urban + FLXHUMVG_URB2D,FLXHUMT_URB2D, & !H urban julian, julyr, & !H urban FRC_URB2D, UTYPE_URB2D, & !I urban num_urban_ndm, & !I multi-layer urban @@ -3232,6 +3250,8 @@ SUBROUTINE surface_driver( & cmcr_urb2d, tgr_urb2d, tgrl_urb3d, smr_urb3d, & !H urban drelr_urb2d, drelb_urb2d, drelg_urb2d, & !H urban flxhumr_urb2d, flxhumb_urb2d, flxhumg_urb2d, & !H urban + tvg_urb2d, xxxvg_urb2d, tvgl_urb3d, smg_urb3d, tt_urb2d, & !H urban + cmcg_urb2d, flxhumvg_urb2d, flxhumt_urb2d, & !H urban julian, julyr, & !H urban frc_urb2d, utype_urb2d, & !I urban chs, chs2, cqs2, & !H @@ -3828,6 +3848,8 @@ SUBROUTINE surface_driver( & cmcr_urb2d,tgr_urb2d,tgrl_urb3d,smr_urb3d, & ! urban drelr_urb2d,drelb_urb2d,drelg_urb2d, & ! urban flxhumr_urb2d,flxhumb_urb2d,flxhumg_urb2d, & + tvg_urb2d,xxxvg_urb2d,tvgl_urb3d,smg_urb3d,tt_urb2d, & + cmcg_urb2d,flxhumvg_urb2d,flxhumt_urb2d, & ! CLM subgrids numc,nump,sabv,sabg,lwup,snl, & snowdp,wtc,wtp,h2osno,t_grnd,t_veg, & diff --git a/phys/noahmp b/phys/noahmp index e5c0859874..1d4d953f56 160000 --- a/phys/noahmp +++ b/phys/noahmp @@ -1 +1 @@ -Subproject commit e5c0859874407859936739e8be8741f9aed369ee +Subproject commit 1d4d953f562b149724441ce1f4479dfdbd70dd01 diff --git a/run/URBPARM.TBL b/run/URBPARM.TBL index dab006d86c..74894e0791 100644 --- a/run/URBPARM.TBL +++ b/run/URBPARM.TBL @@ -227,6 +227,45 @@ FGR: 0.0 DZGR: 0.05 0.10 0.15 0.20 +# +# FVG: Fraction of vegetated ground in the urban canyon (0-1) +# (sf_urban_physics=1) +# + +FVG: 0.1 + +# +# TREEOPTION [ 0: No urban trees - default, 1: Enable urban trees ] +# (sf_urban_physics=1) +# + +TREEOPTION: 0 + +# +# RTREE: Tree crown radius [ m ] +# HTREE: Tree crown center height [ m ] +# DTREE: Tree crown center distance from wall [ m ] +# LAI_TREE: Tree leaf area index [ - ] +# LAI_VEG: Vegetated ground leaf area index [ - ] +# Z0VG: Roughness length for momentum of vegetated ground [ m ] +# Z0HVG: Roughness length for heat of vegetated ground [ m ] +# CAPVG: Heat capacity of vegetated ground [ J m{-3} K{-1} ] +# EPSVG: Emissivity of vegetated ground [ - ] +# EPST: Emissivity of tree canopy [ - ] +# (sf_urban_physics=1, TREEOPTION=1) +# + +RTREE: 1, 1.5, 2.0 +HTREE: 3.0, 3.6, 4.2 +DTREE: 4.15, 4.7, 5.0 +LAI_TREE: 2.0, 2.0, 2.0 +LAI_VEG: 2.0, 2.0, 2.0 +Z0VG: 0.01, 0.01, 0.01 +Z0HVG: 0.001, 0.001, 0.001 +CAPVG: 1.3E6, 1.3E6, 1.3E6 +EPSVG: 0.93, 0.93, 0.93 +EPST: 0.9, 0.9, 0.9 + # # FRC_URB: Fraction of the urban landscape which does not have natural # vegetation. [ Fraction ] diff --git a/run/URBPARM_LCZ.TBL b/run/URBPARM_LCZ.TBL index 450d765f9d..629f97bcbb 100644 --- a/run/URBPARM_LCZ.TBL +++ b/run/URBPARM_LCZ.TBL @@ -226,6 +226,47 @@ FGR: 0.0 DZGR: 0.05 0.10 0.15 0.20 +# +# FVG: Fraction of vegetated ground in the urban canyon (0-1) +# (sf_urban_physics=1) +# + +FVG: 0.1 + +# +# TREEOPTION [ 0: No urban trees - default, 1: Enable urban trees ] +# (sf_urban_physics=1) +# + +TREEOPTION: 0 + +# +# RTREE: Tree crown radius [ m ] +# HTREE: Tree crown center height [ m ] +# DTREE: Tree crown center distance from wall [ m ] +# LAI_TREE: Tree leaf area index [ - ] +# LAI_VEG: Vegetated ground leaf area index [ - ] +# Z0VG: Roughness length for momentum of vegetated ground [ m ] +# Z0HVG: Roughness length for heat of vegetated ground [ m ] +# CAPVG: Heat capacity of vegetated ground [ J m{-3} K{-1} ] +# EPSVG: Emissivity of vegetated ground [ - ] +# EPST: Emissivity of tree canopy [ - ] +# (sf_urban_physics=1, TREEOPTION=1) +# + +37.5, 17.5, 6.5, 37.5, 17.5, 6.5, 3., 6.5, 6.5, 10., 10. + +RTREE: 1.5, 1., 0.8, 1.5, 1.1, 0.8, 0.3, 0.8, 0.8, 1.1, 1.1 +HTREE: 5.0, 4.2, 2., 5., 3.5, 1.9, 0.5, 1.9, 1.9, 3.5, 3.7 +DTREE: 10., 7., 2.6, 25., 17.5, 6.5, 1.66, 16.3, 21.6, 14.3, 50. +LAI_TREE: 2.0, 2.0, 2.0,2.0, 2.0, 2.0,2.0, 2.0, 2.0,2.0, 2.0 +LAI_VEG: 2.0, 2.0, 2.0,2.0, 2.0, 2.0,2.0, 2.0, 2.0,2.0, 2.0 +Z0VG: 0.01, 0.01, 0.01,0.01, 0.01, 0.01,0.01, 0.01, 0.01,0.01, 0.01 +Z0HVG: 0.001, 0.001, 0.001,0.001, 0.001, 0.001,0.001, 0.001, 0.001,0.001, 0.001 +CAPVG: 1.3E6, 1.3E6, 1.3E6,1.3E6, 1.3E6, 1.3E6,1.3E6, 1.3E6, 1.3E6,1.3E6, 1.3E6 +EPSVG: 0.93, 0.93, 0.93,0.93, 0.93, 0.93,0.93, 0.93, 0.93,0.93, 0.93 +EPST: 0.9, 0.9, 0.9,0.9, 0.9, 0.9,0.9, 0.9, 0.9,0.9, 0.9 + # # FRC_URB: Fraction of the urban landscape which does not have natural # vegetation. [ Fraction ] @@ -644,4 +685,3 @@ BUILDING HEIGHTS: 11 # [m] [%] 5.0 100.0 END BUILDING HEIGHTS - diff --git a/run/URBPARM_UZE.TBL b/run/URBPARM_UZE.TBL index e1ea2643e2..27534fb34f 100644 --- a/run/URBPARM_UZE.TBL +++ b/run/URBPARM_UZE.TBL @@ -57,6 +57,45 @@ AH: 20.0, 50.0, 90.0 FRC_URB: 0.5, 0.6, 0.75 +# +# FVG: Fraction of vegetated ground in the urban canyon (0-1) +# (sf_urban_physics=1) +# + +FVG: 0.1 + +# +# TREEOPTION [ 0: No urban trees - default, 1: Enable urban trees ] +# (sf_urban_physics=1) +# + +TREEOPTION: 0 + +# +# RTREE: Tree crown radius [ m ] +# HTREE: Tree crown center height [ m ] +# DTREE: Tree crown center distance from wall [ m ] +# LAI_TREE: Tree leaf area index [ - ] +# LAI_VEG: Vegetated ground leaf area index [ - ] +# Z0VG: Roughness length for momentum of vegetated ground [ m ] +# Z0HVG: Roughness length for heat of vegetated ground [ m ] +# CAPVG: Heat capacity of vegetated ground [ J m{-3} K{-1} ] +# EPSVG: Emissivity of vegetated ground [ - ] +# EPST: Emissivity of tree canopy [ - ] +# (sf_urban_physics=1, TREEOPTION=1) +# + +RTREE: 1, 1.5, 2.0 +HTREE: 3.0, 3.6, 4.2 +DTREE: 7.5, 5.0, 4.0 +LAI_TREE: 2.0, 2.0, 2.0 +LAI_VEG: 2.0, 2.0, 2.0 +Z0VG: 0.01, 0.01, 0.01 +Z0HVG: 0.001, 0.001, 0.001 +CAPVG: 1.3E6, 1.3E6, 1.3E6 +EPSVG: 0.93, 0.93, 0.93 +EPST: 0.9, 0.9, 0.9 + # # CAPR: Heat capacity of roof [ J m{-3} K{-1} ] # (sf_urban_physics=1,2,3) diff --git a/wrftladj/module_physics_init_ad.F b/wrftladj/module_physics_init_ad.F index a8920f6df6..34729ed18e 100644 --- a/wrftladj/module_physics_init_ad.F +++ b/wrftladj/module_physics_init_ad.F @@ -71,7 +71,8 @@ SUBROUTINE A_PHY_INIT(id, config_flags, dt, restart, zfull, zhalf, & & , tr_urb2d, tb_urb2d, tg_urb2d, tc_urb2d, qc_urb2d, xxxr_urb2d, & & xxxb_urb2d, xxxg_urb2d, xxxc_urb2d, trl_urb3d, tbl_urb3d, tgl_urb3d& & , sh_urb2d, lh_urb2d, g_urb2d, rn_urb2d, ts_urb2d, frc_urb2d, & -& utype_urb2d, trb_urb4d, tw1_urb4d, tw2_urb4d, tgb_urb4d, tlev_urb3d& +& utype_urb2d, tvg_urb2d, xxxvg_urb2d, tvgl_urb3d, smg_urb3d, tt_urb2d, & +& cmcg_urb2d, flxhumvg_urb2d, flxhumt_urb2d, trb_urb4d, tw1_urb4d, tw2_urb4d, tgb_urb4d, tlev_urb3d& & , qlev_urb3d, tw1lev_urb3d, tw2lev_urb3d, tglev_urb3d, tflev_urb3d, & & sf_ac_urb3d, lf_ac_urb3d, cm_ac_urb3d, sfvent_urb3d, lfvent_urb3d, & & sfwin1_urb3d, sfwin2_urb3d, sfw1_urb3d, sfw2_urb3d, sfr_urb3d, & @@ -276,6 +277,24 @@ SUBROUTINE A_PHY_INIT(id, config_flags, dt, restart, zfull, zhalf, & !urban REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & & xxxc_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& tvg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& tt_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& xxxvg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& cmcg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& flxhumvg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& flxhumt_urb2d ! REAL, DIMENSION(ims:ime, 1:num_roof_layers, jms:jme), INTENT(INOUT) :: TRL_URB3D !urban ! REAL, DIMENSION(ims:ime, 1:num_wall_layers, jms:jme), INTENT(INOUT) :: TBL_URB3D !urban ! REAL, DIMENSION(ims:ime, 1:num_road_layers, jms:jme), INTENT(INOUT) :: TGL_URB3D !urban @@ -288,6 +307,12 @@ SUBROUTINE A_PHY_INIT(id, config_flags, dt, restart, zfull, zhalf, & !urban REAL, DIMENSION(ims:ime, num_soil_layers, jms:jme), OPTIONAL, & & INTENT(INOUT) :: tgl_urb3d +!urban + REAL, DIMENSION(ims:ime, num_soil_layers, jms:jme), OPTIONAL, & +& INTENT(INOUT) :: tvgl_urb3d +!urban + REAL, DIMENSION(ims:ime, num_soil_layers, jms:jme), OPTIONAL, & +& INTENT(INOUT) :: smg_urb3d !urban REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & & sh_urb2d diff --git a/wrftladj/module_physics_init_tl.F b/wrftladj/module_physics_init_tl.F index 1ff4edd5db..47619c7fa5 100644 --- a/wrftladj/module_physics_init_tl.F +++ b/wrftladj/module_physics_init_tl.F @@ -74,7 +74,8 @@ SUBROUTINE G_PHY_INIT(id, config_flags, dt, restart, zfull, zhalf, & & , tr_urb2d, tb_urb2d, tg_urb2d, tc_urb2d, qc_urb2d, xxxr_urb2d, & & xxxb_urb2d, xxxg_urb2d, xxxc_urb2d, trl_urb3d, tbl_urb3d, tgl_urb3d& & , sh_urb2d, lh_urb2d, g_urb2d, rn_urb2d, ts_urb2d, frc_urb2d, & -& utype_urb2d, trb_urb4d, tw1_urb4d, tw2_urb4d, tgb_urb4d, tlev_urb3d& +& utype_urb2d, tvg_urb2d, xxxvg_urb2d, tvgl_urb3d, smg_urb3d, tt_urb2d, & +& cmcg_urb2d, flxhumvg_urb2d, flxhumt_urb2d, trb_urb4d, tw1_urb4d, tw2_urb4d, tgb_urb4d, tlev_urb3d& & , qlev_urb3d, tw1lev_urb3d, tw2lev_urb3d, tglev_urb3d, tflev_urb3d, & & sf_ac_urb3d, lf_ac_urb3d, cm_ac_urb3d, sfvent_urb3d, lfvent_urb3d, & & sfwin1_urb3d, sfwin2_urb3d, sfw1_urb3d, sfw2_urb3d, sfr_urb3d, & @@ -279,6 +280,24 @@ SUBROUTINE G_PHY_INIT(id, config_flags, dt, restart, zfull, zhalf, & !urban REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & & xxxc_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& tvg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& tt_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& xxxvg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& cmcg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& flxhumvg_urb2d +!urban + REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & +& flxhumt_urb2d ! REAL, DIMENSION(ims:ime, 1:num_roof_layers, jms:jme), INTENT(INOUT) :: TRL_URB3D !urban ! REAL, DIMENSION(ims:ime, 1:num_wall_layers, jms:jme), INTENT(INOUT) :: TBL_URB3D !urban ! REAL, DIMENSION(ims:ime, 1:num_road_layers, jms:jme), INTENT(INOUT) :: TGL_URB3D !urban @@ -291,6 +310,12 @@ SUBROUTINE G_PHY_INIT(id, config_flags, dt, restart, zfull, zhalf, & !urban REAL, DIMENSION(ims:ime, num_soil_layers, jms:jme), OPTIONAL, & & INTENT(INOUT) :: tgl_urb3d +!urban + REAL, DIMENSION(ims:ime, num_soil_layers, jms:jme), OPTIONAL, & +& INTENT(INOUT) :: tvgl_urb3d +!urban + REAL, DIMENSION(ims:ime, num_soil_layers, jms:jme), OPTIONAL, & +& INTENT(INOUT) :: smg_urb3d !urban REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(INOUT) :: & & sh_urb2d diff --git a/wrftladj/start_em_ad.F b/wrftladj/start_em_ad.F index c492b5a64e..eb4aa34466 100644 --- a/wrftladj/start_em_ad.F +++ b/wrftladj/start_em_ad.F @@ -603,6 +603,8 @@ SUBROUTINE a_start_domain_em ( grid, allowed_to_read & grid%TRL_URB3D, grid%TBL_URB3D, grid%TGL_URB3D, & !Optional urban grid%SH_URB2D, grid%LH_URB2D, grid%G_URB2D, grid%RN_URB2D, & !Optional urban grid%TS_URB2D, grid%FRC_URB2D, grid%UTYPE_URB2D, & !Optional urban + grid%TVG_URB2D,grid%XXXVG_URB2D,grid%TVGL_URB3D,grid%SMG_URB3D,grid%TT_URB2D, & !Optional urban + grid%CMCG_URB2D,grid%FLXHUMVG_URB2D,grid%FLXHUMT_URB2D, & !Optional urban grid%TRB_URB4D,grid%TW1_URB4D,grid%TW2_URB4D,grid%TGB_URB4D,grid%TLEV_URB3D, & !multi-layer urban grid%QLEV_URB3D,grid%TW1LEV_URB3D,grid%TW2LEV_URB3D, & !multi-layer urban grid%TGLEV_URB3D,grid%TFLEV_URB3D,grid%SF_AC_URB3D, & !multi-layer urban @@ -836,4 +838,3 @@ SUBROUTINE a_start_domain_em ( grid, allowed_to_read & RETURN END SUBROUTINE a_start_domain_em - diff --git a/wrftladj/start_em_tl.F b/wrftladj/start_em_tl.F index 817f37fac9..3254315041 100644 --- a/wrftladj/start_em_tl.F +++ b/wrftladj/start_em_tl.F @@ -475,6 +475,8 @@ SUBROUTINE g_start_domain_em ( grid, allowed_to_read & grid%TRL_URB3D, grid%TBL_URB3D, grid%TGL_URB3D, & !Optional urban grid%SH_URB2D, grid%LH_URB2D, grid%G_URB2D, grid%RN_URB2D, & !Optional urban grid%TS_URB2D, grid%FRC_URB2D, grid%UTYPE_URB2D, & !Optional urban + grid%TVG_URB2D,grid%XXXVG_URB2D,grid%TVGL_URB3D,grid%SMG_URB3D,grid%TT_URB2D, & !Optional urban + grid%CMCG_URB2D,grid%FLXHUMVG_URB2D,grid%FLXHUMT_URB2D, & !Optional urban grid%TRB_URB4D,grid%TW1_URB4D,grid%TW2_URB4D,grid%TGB_URB4D,grid%TLEV_URB3D, & !multi-layer urban grid%QLEV_URB3D,grid%TW1LEV_URB3D,grid%TW2LEV_URB3D, & !multi-layer urban grid%TGLEV_URB3D,grid%TFLEV_URB3D,grid%SF_AC_URB3D, & !multi-layer urban @@ -829,4 +831,3 @@ SUBROUTINE g_start_domain_em ( grid, allowed_to_read & RETURN END SUBROUTINE g_start_domain_em -