Scheduled Downtime
On Tuesday 24 October 2023 @ 5pm MT the forums will be in read only mode in preparation for the downtime. On Wednesday 25 October 2023 @ 5am MT, this website will be down for maintenance and expected to return online later in the morning.
Normal Operations
The forums are back online with normal operations. If you notice any issues or errors related to the forums, please reach out to help@ucar.edu

Calculate urban energy flux from its pft-level output

Status
Not open for further replies.

KeerZ

Member
Hello, I am learning how to derive landunit-level results from pft-level (finest-level) output. I practiced by calculating the urban, rural (bare soil+veg+crop) and grid-mean air temperature & latent heat flux from pft-level output, and then compare my results with CLM output (TSA_U, TSA, EFLX_LH_TOT_R ect.).

I can correctly get urban,rural and grid-mean air temperature by calculating the area-weighted average values of corresponding pft-level (finest-level) TSA - I knew my results were correct because my calculated urban,rural and grid-mean air temperature were exactly the same with TSA_U, TSA_R and TSA at grid-level.

However, the same area-weighted average algorithm got wrong urban energy flux results. For example, my calculated urban EFLX_LH_TOT from pft-level output were very different from EFLX_LH_TOT_U that CLM output directly. Maybe here urban energy flux should not be calculated as the area-weighted average of pft-level energy flux?

How can we get correct urban and grid-mean energy flux from the pft-level output? Any suggestions are appreciated. Thank you!
 

oleson

Keith Oleson
CSEG and Liaisons
Staff member
There is some scaling of urban components (sunlit wall, shaded wall, roof, pervious and impervious canyon floor) within the code to convert from pft or column-level to landunit level for certain variables.

You can tell what kind of scaling is used for each variable by looking at c2l_scale_type in the call to hist_addfld1d.
For example, EFLX_LH_TOT_U uses c2l_scale_type='urbanf':

call hist_addfld1d (fname='EFLX_LH_TOT_U', units='W/m^2', &
avgflag='A', long_name='Urban total evaporation', &
ptr_patch=this%eflx_lh_tot_u_patch, c2l_scale_type='urbanf', set_nourb=spval, default='inactive')

From comments in subgridAveMod.F90: "In general, urbanf should be used for variables that are expressed as something-per-m^2 ('extensive' state or flux variables), whereas urbans should be used for variables that are not expressed as per-m^2 ('intensive' state variables; an example is surface temperature). The urbanf scaling converts from per-m^2 of vertical wall area to per-m^2 of ground area. One way to think about this is: In the extreme case of a near-infinite canyon_hwr due to massively tall walls, do you want a near-infinite multiplier for the walls for the variable in question? If so, you want urbanf; if not, you want urbans."

The subroutine subgridAveMod.F90 uses c2l_scale_type to determine scaling factors for urban landunits, e.g, for urbanf:

else if (c2l_scale_type == 'urbanf') then
do c = bounds%begc,bounds%endc
l = col%landunit(c)
if (lun%urbpoi(l)) then
if (col%itype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * lun%canyon_hwr(l)
else if (col%itype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * lun%canyon_hwr(l)
else if (col%itype(c) == icol_road_perv .or. col%itype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (col%itype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if

So you need to apply this same scaling to your pft-level (column-level) output.
Alternatively, if you don't want/need to do the scaling yourself as a postprocessing step, you can simply "request" landunit-level output for the variables you are interested in. For example, to get landunit-level EFLX_LH_TOT, you could add this to your user_nl_clm:

hist_dov2xy(1) = .true.
hist_dov2xy(2) = .false.
hist_fincl2 = 'EFLX_LH_TOT'
hist_mfilt(1) = 1
hist_mfilt(2) = 1
hist_nhtfrq(1) = 0
hist_nhtfrq(2) = 0
hist_type1d_pertape(1) = ' '
hist_type1d_pertape(2) = 'LAND'

This would give you the regular h0 monthly history files, plus a landunit-level h1 history file for EFLX_LH_TOT. You can use the indexes within the file to get EFLX_LH_TOT for each vegetated, urban, crop, etc. landunit within each gridcell.
 

KeerZ

Member
There is some scaling of urban components (sunlit wall, shaded wall, roof, pervious and impervious canyon floor) within the code to convert from pft or column-level to landunit level for certain variables.

You can tell what kind of scaling is used for each variable by looking at c2l_scale_type in the call to hist_addfld1d.
For example, EFLX_LH_TOT_U uses c2l_scale_type='urbanf':

call hist_addfld1d (fname='EFLX_LH_TOT_U', units='W/m^2', &
avgflag='A', long_name='Urban total evaporation', &
ptr_patch=this%eflx_lh_tot_u_patch, c2l_scale_type='urbanf', set_nourb=spval, default='inactive')

From comments in subgridAveMod.F90: "In general, urbanf should be used for variables that are expressed as something-per-m^2 ('extensive' state or flux variables), whereas urbans should be used for variables that are not expressed as per-m^2 ('intensive' state variables; an example is surface temperature). The urbanf scaling converts from per-m^2 of vertical wall area to per-m^2 of ground area. One way to think about this is: In the extreme case of a near-infinite canyon_hwr due to massively tall walls, do you want a near-infinite multiplier for the walls for the variable in question? If so, you want urbanf; if not, you want urbans."

The subroutine subgridAveMod.F90 uses c2l_scale_type to determine scaling factors for urban landunits, e.g, for urbanf:

else if (c2l_scale_type == 'urbanf') then
do c = bounds%begc,bounds%endc
l = col%landunit(c)
if (lun%urbpoi(l)) then
if (col%itype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * lun%canyon_hwr(l)
else if (col%itype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * lun%canyon_hwr(l)
else if (col%itype(c) == icol_road_perv .or. col%itype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (col%itype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if

So you need to apply this same scaling to your pft-level (column-level) output.
Alternatively, if you don't want/need to do the scaling yourself as a postprocessing step, you can simply "request" landunit-level output for the variables you are interested in. For example, to get landunit-level EFLX_LH_TOT, you could add this to your user_nl_clm:

hist_dov2xy(1) = .true.
hist_dov2xy(2) = .false.
hist_fincl2 = 'EFLX_LH_TOT'
hist_mfilt(1) = 1
hist_mfilt(2) = 1
hist_nhtfrq(1) = 0
hist_nhtfrq(2) = 0
hist_type1d_pertape(1) = ' '
hist_type1d_pertape(2) = 'LAND'

This would give you the regular h0 monthly history files, plus a landunit-level h1 history file for EFLX_LH_TOT. You can use the indexes within the file to get EFLX_LH_TOT for each vegetated, urban, crop, etc. landunit within each gridcell.
Yes. Outputting at landunit level is much easier to get the urban energy fluxes (of TBD, HD and MD urban). This is exactly what I am looking for. And it is also helpful to know how the scaling is done when some variables are converted from pft level to landunit level. Thanks!!
 

KeerZ

Member
There is some scaling of urban components (sunlit wall, shaded wall, roof, pervious and impervious canyon floor) within the code to convert from pft or column-level to landunit level for certain variables.

You can tell what kind of scaling is used for each variable by looking at c2l_scale_type in the call to hist_addfld1d.
For example, EFLX_LH_TOT_U uses c2l_scale_type='urbanf':

call hist_addfld1d (fname='EFLX_LH_TOT_U', units='W/m^2', &
avgflag='A', long_name='Urban total evaporation', &
ptr_patch=this%eflx_lh_tot_u_patch, c2l_scale_type='urbanf', set_nourb=spval, default='inactive')

From comments in subgridAveMod.F90: "In general, urbanf should be used for variables that are expressed as something-per-m^2 ('extensive' state or flux variables), whereas urbans should be used for variables that are not expressed as per-m^2 ('intensive' state variables; an example is surface temperature). The urbanf scaling converts from per-m^2 of vertical wall area to per-m^2 of ground area. One way to think about this is: In the extreme case of a near-infinite canyon_hwr due to massively tall walls, do you want a near-infinite multiplier for the walls for the variable in question? If so, you want urbanf; if not, you want urbans."

The subroutine subgridAveMod.F90 uses c2l_scale_type to determine scaling factors for urban landunits, e.g, for urbanf:

else if (c2l_scale_type == 'urbanf') then
do c = bounds%begc,bounds%endc
l = col%landunit(c)
if (lun%urbpoi(l)) then
if (col%itype(c) == icol_sunwall) then
scale_c2l(c) = 3.0 * lun%canyon_hwr(l)
else if (col%itype(c) == icol_shadewall) then
scale_c2l(c) = 3.0 * lun%canyon_hwr(l)
else if (col%itype(c) == icol_road_perv .or. col%itype(c) == icol_road_imperv) then
scale_c2l(c) = 3.0_r8
else if (col%itype(c) == icol_roof) then
scale_c2l(c) = 1.0_r8
end if

So you need to apply this same scaling to your pft-level (column-level) output.
Alternatively, if you don't want/need to do the scaling yourself as a postprocessing step, you can simply "request" landunit-level output for the variables you are interested in. For example, to get landunit-level EFLX_LH_TOT, you could add this to your user_nl_clm:

hist_dov2xy(1) = .true.
hist_dov2xy(2) = .false.
hist_fincl2 = 'EFLX_LH_TOT'
hist_mfilt(1) = 1
hist_mfilt(2) = 1
hist_nhtfrq(1) = 0
hist_nhtfrq(2) = 0
hist_type1d_pertape(1) = ' '
hist_type1d_pertape(2) = 'LAND'

This would give you the regular h0 monthly history files, plus a landunit-level h1 history file for EFLX_LH_TOT. You can use the indexes within the file to get EFLX_LH_TOT for each vegetated, urban, crop, etc. landunit within each gridcell.
Hello Keith, I've got another question about calculating the QRUNOFF of tree, grass, and bare soil from their pft-level output. I used the cesm2.1.2 and BSSP585 compset for this simulation.

To make sure that I can calculate tree and grass QRUNOFF correctly, I first calculated the rural QRUNOFF by calculating the area-weighted average QRUNOFF values of all bare soil, vegetated, and crop pft-level results. And then I compared my calculated rural QRUNOFF with the QRUNOFF_R I output. I think my calculation results at most grids are correct because the error (calculated rural QRUNOFF - QRUNOFF_R) is smaller than 1e-20 for most areas (a figure is attached).

However, in the polar regions, the model output QRUNOFF_R is near 0, but my calculated rural QRUNOFF can be 1e-5 mm/s larger than the QRUNOFF_R, which is a very large error because the QRUNOFF itself is very small.

Among all rural pfts, only the bare soil exists in the polar regions. The bare soil pft takes up only 0.01-0.03 of the grid cell but has pretty high QRUNOFF(1e-5 mm/s). That's why my calculated rural QRUNOFF is 1e-5 mm/s larger than the QRUNOFF_R. But I am not sure why the output QRUNOFF_R is so small... Do you have any idea what possibly lead to this large error in the polar regions? Should the pft-level QRUNOFF be aggregated differently in the polar regions?

I can provide the data I used if needed. Thank you!
 

Attachments

  • Figure1.png
    Figure1.png
    340 KB · Views: 9

oleson

Keith Oleson
CSEG and Liaisons
Staff member
The QRUNOFF_R is a flux for the entire gridcell, not just the bare+veg+crop fraction. So to reconstruct it with your pft-level QRUNOFF, you'd need to multiply it by the bare soil fraction. If the bare soil fraction is 0.01, then 0.01 X 1.e-5 = 1.e-7. Hopefully that would then agree with the QRUNOFF_R.
 

KeerZ

Member
The QRUNOFF_R is a flux for the entire gridcell, not just the bare+veg+crop fraction. So to reconstruct it with your pft-level QRUNOFF, you'd need to multiply it by the bare soil fraction. If the bare soil fraction is 0.01, then 0.01 X 1.e-5 = 1.e-7. Hopefully that would then agree with the QRUNOFF_R.
Yes, I eventually calculated the grid mean QRUNOFF correctly (just for testing purpose) using the landunit-level and pft-level QRUNOFF output. This means that my algorithm to aggregate pft-level or landunit-level results should be correct.

I think the QRUNOFF_R results at the polar regions are somewhat suspicious. In my simulation, there are some grids (0.01 bare soil pft +0.99 land ice) having QRUNOFF=1e-7mm/s but QRUNOFF_R=0. My aggregated results agree with QRUNOFF.
Anyway, thank you for the help!!
 
Status
Not open for further replies.
Top