-
Notifications
You must be signed in to change notification settings - Fork 821
New option for SLUCM to consider global distributed urban parameters #1881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -754,6 +754,7 @@ state real slope ij misc 1 - rdu "SLOP | |
| state real slp_azi ij misc 1 - rdu "SLP_AZI" "ELEVATION SLOPE AZIMUTH" "rad" | ||
| state real shdmax ij misc 1 - i012rhd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "SHDMAX" "ANNUAL MAX VEG FRACTION" "" | ||
| state real shdmin ij misc 1 - i012rhd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "SHDMIN" "ANNUAL MIN VEG FRACTION" "" | ||
| state real shdavg ij misc 1 - i012rhd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "SHDAVG" "ANNUAL AVG VEG FRACTION" "" | ||
| state real snoalb ij misc 1 - i012rhd "SNOALB" "ANNUAL MAX SNOW ALBEDO IN FRACTION" "" | ||
| state real toposoil ij misc 1 - i12 "SOILHGT" "ELEVATION OF LSM DATA" "m" | ||
| state real landusef iuj misc 1 Z i012rdu "LANDUSEF" "LANDUSE FRACTION BY CATEGORY" "" | ||
|
|
@@ -807,14 +808,20 @@ state real DZR l em - Z r "DZR" | |
| state real DZB l em - Z r "DZB" "THICKNESSES OF WALL LAYERS" "m" | ||
| state real DZG l em - Z r "DZG" "THICKNESSES OF ROAD LAYERS" "m" | ||
| state real URB_PARAM i{urb}j misc 1 - i1 "URB_PARAM" "NUDAPT_NBSD Urban Parameters" "parameter" | ||
| state real LP_URB2D ij misc 1 - ir "BUILD_AREA_FRACTION" "BUILDING PLAN AREA DENSITY" "dimensionless" | ||
| state real LP_URB2D ij misc 1 - i01r "BUILD_AREA_FRACTION" "BUILDING PLAN AREA DENSITY" "dimensionless" | ||
| state real HI_URB2D i{uhi}j misc 1 Z ir "HEIGHT_HISTOGRAMS" "DISTRIBUTION OF BUILDING HEIGHTS" "dimensionless" | ||
| state real LB_URB2D ij misc 1 - ir "BUILD_SURF_RATIO" "BUILDING SURFACE AREA TO PLAN AREA RATIO" "dimensionless" | ||
| state real HGT_URB2D ij misc 1 - ir "BUILD_HEIGHT" "AVERAGE BUILDING HEIGHT WEIGHTED BY BUILDING PLAN AREA" "m" | ||
| state real MH_URB2D ij misc 1 - ir "MH_URB2D" "Mean Building Height" "m" | ||
| state real MH_URB2D ij misc 1 - i01r "MH_URB2D" "Mean Building Height" "m" | ||
| state real STDH_URB2D ij misc 1 - ir "STDH_URB2D" "Standard Deviation of Building Height" "m2" | ||
| state real LF_URB2D i{udr}j misc 1 Z ir "LF_URB2D" "Frontal Area Index" "dimensionless" | ||
|
|
||
| state real ZD_URB2D ij misc 1 - i1 "ZD_URB2D" "Zero-plane Displacement" "m" | ||
| state real Z0_URB2D ij misc 1 - i01r "Z0_URB2D" "Roughness length for momentum" "m" | ||
| state real LF_URB2D_S ij misc 1 - i01r "LF_URB2D_S" "Frontal area index (no wind directional dependency)" "" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epn09 what is the difference between LF_URB2D_S and LF_URB2D? Why do you need to create this new variable instead of using the existing LF_URB2D?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cenlinhe
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I see. This makes sense. |
||
| # AHE with month and hour dimension flattened to one dimension, Jan = (0:23), Feb = (24:47) | ||
| state real AHE i{m_hr}j misc 1 - i01r "AHE" "Anthropogenic heat emission" "W m-2" | ||
|
|
||
| # lsm State Variables | ||
|
|
||
| state real SMOIS ilj - 1 Z i02rhd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "SMOIS" "SOIL MOISTURE" "m3 m-3" | ||
|
|
@@ -2515,6 +2522,8 @@ rconfig integer ishallow namelist,physics 1 0 | |
| rconfig real convtrans_avglen_m namelist,physics 1 30 rh "convtrans_avglen_m" "averaging time for convective transport output variables (minutes)" "" | ||
| rconfig integer num_land_cat namelist,physics 1 21 - "num_land_cat" "" "" | ||
| rconfig integer use_wudapt_lcz namelist,physics 1 0 - "use_wudapt_lcz" "" "" | ||
| rconfig logical use_distributed_aerodynamics namelist,physics 1 .false. rh "use_distributed_aerodynamics" "" "" | ||
| rconfig integer distributed_ahe_opt namelist,physics 1 1 rh "distributed_ahe_opt" "AHE handling: 1=add to first level temperature tendency, 2=add to surface sensible heat flux" "" | ||
| rconfig integer num_soil_cat namelist,physics 1 16 - "num_soil_cat" "" "" | ||
| rconfig integer mp_zero_out namelist,physics 1 0 - "mp_zero_out" "microphysics fields set to zero 0=no action taken, 1=all fields but Qv, 2=all fields including Qv" "flag" | ||
| rconfig real mp_zero_out_thresh namelist,physics 1 1.e-8 - "mp_zero_out_thresh" "minimum threshold for non-Qv moist fields, below are set to zero" "kg/kg" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -617,6 +617,15 @@ SUBROUTINE init_domain_rk ( grid & | |
| END IF | ||
| END IF | ||
|
|
||
| IF (config_flags%use_distributed_aerodynamics) THEN | ||
| CALL wrf_message('Adding zero-plane displacement height to topography') | ||
| DO j = jts, MIN(jde - 1, jte) | ||
| DO i = its, MIN(ide - 1, ite) | ||
| IF (grid%zd_urb2d(i, j) > 0) grid%ht_gc(i, j) = grid%ht_gc(i, j) + grid%zd_urb2d(i, j) | ||
| END DO | ||
| END DO | ||
| END IF | ||
|
|
||
| ! Is there any vertical interpolation to do? The "old" data comes in on the correct | ||
| ! vertical locations already. | ||
|
|
||
|
|
@@ -1330,6 +1339,11 @@ SUBROUTINE init_domain_rk ( grid & | |
| ims , ime , jms , jme , kms , kme , & | ||
| its , ite , jts , jte , kts , kte ) | ||
|
|
||
| CALL monthly_avg ( grid%greenfrac , grid%shdavg , & | ||
| ids , ide , jds , jde , kds , kde , & | ||
| ims , ime , jms , jme , kms , kme , & | ||
| its , ite , jts , jte , kts , kte ) | ||
|
|
||
| ! The model expects the green-ness and vegetation fraction values to be in percent, not fraction. | ||
|
|
||
| DO j = jts, MIN(jte,jde-1) | ||
|
|
@@ -1338,6 +1352,7 @@ SUBROUTINE init_domain_rk ( grid & | |
| grid%vegfra(i,j) = grid%vegfra(i,j) * 100. | ||
| grid%shdmax(i,j) = grid%shdmax(i,j) * 100. | ||
| grid%shdmin(i,j) = grid%shdmin(i,j) * 100. | ||
| grid%shdavg(i,j) = grid%shdavg(i,j) * 100. | ||
| END DO | ||
| END DO | ||
|
|
||
|
|
@@ -3089,6 +3104,16 @@ SUBROUTINE init_domain_rk ( grid & | |
|
|
||
| ! Split NUDAPT Urban Parameters | ||
|
|
||
| distributed_aerodynamics_if: IF (config_flags%sf_urban_physics == 1 .AND. config_flags%use_distributed_aerodynamics) THEN | ||
| DO j = jts , MIN(jde-1,jte) | ||
| DO i = its , MIN(ide-1,ite) | ||
| IF (grid%ivgtyp(i, j) == model_config_rec%isurban(grid%id)) THEN | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need to also include a treatment for urban LCZ type so that the model will not produce weird values for LCZ pixels. If this scheme does not work with LCZ, then add a if-statement here to show error message for this incompatibility.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cenlinhe This is fixed.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cenlinhe I added if-statement and error messages to |
||
| grid%frc_urb2d(i, j) = MAX(0.1, MIN(0.9, 1 - grid%shdavg(i, j) / 100.)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epn09 not sure if this is a good way to estimate urban fraction (=1-vegfrac), why not using the LAND_USE_F variable to read in the urban fraction? Also, I think the shdmax should be used instead of shdavg.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cenlinhe Please correct me if I'm wrong but LANDUSEF is not so good because it's derived from land use map (for example, MODIS). If a WRF grid will all MODIS grids classified as urban, the WRF grid will have LANDUSEF(urban) = 100. But from our experience and from reality, 100% urban cover is really rare. So we assume that urban fraction + vegetation fraction = 1, because even in 100% urban cover grid there is still some vegetation fraction in the input data. As for the shdmax, I think if we do that urban fraction might be a little bit small because trees in its growth season can cover very high fraction of the ground. On the other hand, shdmin may make urban fraction too big. Hence, I use the value in the middle shdavg.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, this makes sense, at least for now. more tests with the impact of shdavg vs shdmax are needed in the future.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tslin2 @epn09 OK, let me comment here since this is probably the first place where it showed up. I think I understood what Khanh is trying to do here. If there is no other data source for FRC_URB2D, one can come up with a few ways to assign FRC_URB2D values. It used to be that FRC_URB2D is prescribed in the URBPARM.TBL (e.g., 0.5 for low intensity residential urban etc). With NLCD data, FRC_URB2D is actually estimated from NLCD and is no longer using prescribed values from URBPARM.TBL. Now this part of code is trying to assign FRC_URB2D based on vegetation fraction, which is not a terrible idea. But this will limit the compatibility of this code with potentially new land use/land cover data that can provide FRC_URB2D. Khanh (first of all, congratulations on becoming a doctor, way to go), regarding
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DanLi-BU Thanks for your note about NLCD. Well-noted. |
||
| END IF | ||
| END DO | ||
| END DO | ||
| ELSE | ||
|
|
||
| IF ( ( config_flags%sf_urban_physics == 1 ) .OR. ( config_flags%sf_urban_physics == 2 ) .OR. ( config_flags%sf_urban_physics == 3 ) ) THEN | ||
| DO j = jts , MIN(jde-1,jte) | ||
| DO i = its , MIN(ide-1,ite) | ||
|
|
@@ -3145,6 +3170,8 @@ SUBROUTINE init_domain_rk ( grid & | |
| END DO | ||
| END DO | ||
|
|
||
| END IF distributed_aerodynamics_if | ||
|
|
||
| END IF | ||
|
|
||
| ! Adjustments for the seaice field PRIOR to the grid%tslb computations. This is | ||
|
|
@@ -7922,6 +7949,34 @@ SUBROUTINE monthly_min_max ( field_in , field_min , field_max , & | |
|
|
||
| END SUBROUTINE monthly_min_max | ||
|
|
||
| !--------------------------------------------------------------------- | ||
|
|
||
| SUBROUTINE monthly_avg ( field_in , field_avg , & | ||
| ids , ide , jds , jde , kds , kde , & | ||
| ims , ime , jms , jme , kms , kme , & | ||
| its , ite , jts , jte , kts , kte ) | ||
|
|
||
| IMPLICIT NONE | ||
|
|
||
| INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , & | ||
| ims , ime , jms , jme , kms , kme , & | ||
| its , ite , jts , jte , kts , kte | ||
|
|
||
| REAL , DIMENSION(ims:ime,12,jms:jme) , INTENT(IN) :: field_in | ||
| REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: field_avg | ||
|
|
||
| ! Local vars | ||
|
|
||
| INTEGER :: i , j | ||
|
|
||
| DO j = jts , MIN(jde-1,jte) | ||
| DO i = its , MIN(ide-1,ite) | ||
| field_avg(i, j) = SUM(field_in(i, :, j)) / 12 | ||
| END DO | ||
| END DO | ||
|
|
||
| END SUBROUTINE monthly_avg | ||
|
|
||
| !--------------------------------------------------------------------- | ||
|
|
||
| SUBROUTINE monthly_interp_to_date ( field_in , date_str , field_out , & | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,6 +103,9 @@ SUBROUTINE pbl_driver( & | |
| ,tke_adv,diss_adv,tpe_adv & | ||
| ,pr_pbl,el_pbl & | ||
| ,wu_tur,wv_tur,wt_tur,wq_tur & | ||
| ! variables added for AHE | ||
| , gmt, xtime, julday, julyr, ahe & | ||
| , distributed_ahe_opt & | ||
| ! variables for GBM PBL | ||
| ,exch_tke, rthraten & | ||
| ,a_e_bep,b_e_bep,dlg_bep,dl_u_bep & | ||
|
|
@@ -199,6 +202,7 @@ SUBROUTINE pbl_driver( & | |
| USE module_bl_fogdes | ||
| USE module_wind_fitch | ||
| #endif | ||
| use module_ra_gfdleta, only: cal_mon_day | ||
|
|
||
| ! This driver calls subroutines for the PBL parameterizations. | ||
| ! | ||
|
|
@@ -610,6 +614,11 @@ SUBROUTINE pbl_driver( & | |
| REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), & | ||
| INTENT(OUT) :: EL_PBL | ||
|
|
||
| REAL, INTENT(IN) :: gmt, xtime | ||
| INTEGER, INTENT(IN) :: julday, julyr | ||
| REAL, OPTIONAL, DIMENSION( ims:ime, 0:287, jms:jme ), INTENT(IN) :: ahe | ||
| INTEGER, INTENT(IN) :: distributed_ahe_opt | ||
|
|
||
| REAL , INTENT(IN ) :: u_frame, & | ||
| v_frame | ||
| ! | ||
|
|
@@ -820,6 +829,7 @@ SUBROUTINE pbl_driver( & | |
| integer iu_bep,iurb,idiff | ||
| real seamask,thsk,zzz,unew,vnew,tnew,qnew,umom,vmom | ||
| REAL :: z0,z1,z2,w1,w2 | ||
| INTEGER :: ihour, jmonth, jday | ||
| ! | ||
| ! FASDAS | ||
| ! | ||
|
|
@@ -2203,6 +2213,26 @@ SUBROUTINE pbl_driver( & | |
| ,ITS=its,ITE=ite,JTS=jts,JTE=jte,KTS=kts,KTE=kte) | ||
| ENDIF | ||
|
|
||
|
|
||
| IF (PRESENT(ahe)) THEN | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epn09 This may not be the best place to add this anthropogenic heating flux. First, if putting it in this pbl driver module, should it be added to a place after land surface model and urban scheme is called? Second, it may be better to include this to the SLUCM code module instead of pbl driver to avoid messing up with other physics.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cenlinhe The reason we didn't add AH flux to the urban scheme is because the construction of the AH dataset did not assume that AH comes from only urban.
What's your opinion on this? The full paper is available here (https://www.nature.com/articles/s41597-021-00850-w).
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I see. This makes sense to me, as the AH is not only for urban AH. power station may also belong to urban?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cenlinhe Power station may be in either rural or urban. When constructing the AH dataset we did not make that distinction. |
||
| call cal_mon_day(julday, julyr, jmonth, jday) | ||
| ihour = (jmonth - 1) * 24 + MOD(INT(gmt + xtime / 60.0), 24) | ||
| IF (distributed_ahe_opt == 1) THEN | ||
| DO j = jts, jte | ||
| DO i = its, ite | ||
| ! Volumetric heat capacity of air = 1200 J/(K m3) | ||
| RTHBLTEN(i, 1, j) = RTHBLTEN(i, 1, j) + ahe(i, ihour, j) / 1200 / DZ8W(i, 1, j) | ||
| END DO | ||
| END DO | ||
| ELSE IF (distributed_ahe_opt == 2) THEN | ||
| DO j = jts, jte | ||
| DO i = its, ite | ||
| HFX(i, j) = HFX(i, j) + ahe(i, ihour, j) | ||
| END DO | ||
| END DO | ||
| END IF | ||
| END IF | ||
|
|
||
| ENDDO | ||
| !$OMP END PARALLEL DO | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dudhia What is the difference between "i" and "i01"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cenlinhe Here letter i represents input data. The number 0 means it is part of wrfinput, output from real, and input to the model, and 1 is the input to real program or the met_em output data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weiwangncar If we do not specify "0" and/or "1" after "i", does it mean it can be in any input files or by default assume it is from wrfinput? For example, for variables like HGT_URB2D, they are only specified as "i" instead of "i01".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weiwangncar @dudhia Since these variables are optional (i.e., users may not provide these in their geo_em input file), I think it should be set to "i" instead of "i01". Otherwise, WRF will look for these variables in wrfinput or met_em files, and report errors? Is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cenlinhe Sorry I missed these comments. If you just have an 'i', that variable is only appearing in wrfinput - whether it has value will depend on what real does. If there is no input to real, the array may be all zero. If the data comes from geogrid and metgrid, it should be set to i01.