Skip to content

Conversation

ckoven
Copy link
Contributor

@ckoven ckoven commented May 12, 2025

In order to look at biophysical effects of land use, it's useful to have a small number of relevant variables indexed by land use type. This PR allows that, so that you can look at: vegetation temperature, surface air temperature, and a basic set of energy fluxes (SW, LW, SH, LH) separately for each land use type. I.e., they are output on the fates_levlanduse history dimension for each gridcell.

This requires HLM-side logic. I have a commit on E3SM that handles this at ckoven/E3SM@5fd137b (PR forthcoming)

Currently these are all output when the hi frequency history flag is set to 1; in principle this should actually be when the flag is set to 2, so that should probably change before bringing this PR in. (for the purpose of the experiments I am currently running, I want these and only these subgridscale high-frequency variables though.)

Also, the logic that averages in bare-ground-patch properties will only work for nocomp configurations. Further work is needed to be correct for full-FATES configurations as well, but I got lost in how to index a given site's bare-ground patch when nocomp isn't on, so I need to come back to that.

Also, the patch-weighting logic for these variables is slightly different than for other patch-level variables (e.g., the `fates_levage' -indexed ones). This is for two reasons: (1) we need to average in some of the bare ground patch properties to weight things correctly, because the FATES and HLM patch areas mean different things, and (2) the land use areas are less generally dynamic than the age binned logic, and so there is less chance of weirdness when the averaging denominator changes abruptly. So the upshot is that less postprocessing is needed for these (i.e they are simpler to work with), but also that they might not sum perfectly to the total site values because of changing denominators over time.

Description:

fixes #1404.

Collaborators:

discussed with @glemieux, @rgknox, @aswann

Expectation of Answer Changes:

This only adds new diagnostic variables, so should be bit for bit otherwise.

Checklist

If this is your first time contributing, please read the CONTRIBUTING document.

All checklist items must be checked to enable merging this pull request:

Contributor

  • The in-code documentation has been updated with descriptive comments
  • The documentation has been assessed to determine if updates are necessary

Integrator

  • FATES PASS/FAIL regression tests were run
  • Evaluation of test results for answer changes was performed and results provided
  • FATES-CLM6 Code Freeze: satellite phenology regression tests are b4b

If satellite phenology regressions are not b4b, please hold merge and notify the FATES development team.

Documentation

Test Results:

CTSM (or) E3SM (specify which) test hash-tag:

CTSM (or) E3SM (specify which) baseline hash-tag:

FATES baseline hash-tag:

Test Output:

Copy link
Contributor

@samsrabin samsrabin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, Charlie! Just a few suggestions.

Also, a question: I'm having trouble understanding why and under what circumstances these should fail to sum to the site value. Could you explain that in a bit more detail?


! for the rest of these, first weight by the vegetated area of each patch over the total patch area for each land use type
hio_tsa_si_landuse(io_si,cpatch%land_use_label) = hio_tsa_si_landuse(io_si,cpatch%land_use_label) + &
bc_in(s)%t2m_pa(cpatch%patchno) * cpatch%total_canopy_area/landuse_statevector(cpatch%land_use_label)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For normalization factors like cpatch%total_canopy_area/landuse_statevector(cpatch%land_use_label) that are repeated a bunch, it'd be good to create a variable for them with a useful name. E.g., what I did in update_history_dyn_subsite_ageclass() with patch_area_div_site_area.

cpatch => cpatch%younger
end do

! for all the land-use indexed variables, excpet for TVEG, also add in the component for the unvegetated area of each land use
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"excpet" typo.

real(r8) :: landuse_statevector(n_landuse_cats)
real(r8) :: canopy_area_bylanduse(n_landuse_cats)
integer :: i_lu
logical :: foundbaregroundpatch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foundbaregroundpatch appears to be set but unused.

if (cpatch%land_use_label .eq. nocomp_bareground_land .and. .not. foundbaregroundpatch) then
foundbaregroundpatch = .true.
do i_lu = 1, n_landuse_cats
if ( landuse_statevector(i_lu) .gt. rsnbl_math_prec ) then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reduce indentation and thus readability, this if ( landuse_statevector(i_lu) .gt. rsnbl_math_prec ) then ... could be replaced by cycling on its inverse—if ( landuse_statevector(i_lu) .le. rsnbl_math_prec ) then cycle.



cpatch => sites(s)%oldest_patch
do while(associated(cpatch))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this do loop separate from the others? Is it because GPP is the only one with the ccohort%n * dt_tstep_inv normalization factor? A comment would be useful to explain this.

ccohort => cpatch%shortest
do while(associated(ccohort))
if ( .not. ccohort%isnew ) then
if (cpatch%land_use_label .gt. nocomp_bareground_land) then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if statement could be combined with the one above to reduce indentation.

ivar=ivar, initialize=initialize_variables, index = ih_lhflux_si_landuse )

call this%set_history_var(vname='FATES_GPP_LU', units='kg m-2 s-1', &
long='gross primary productivity by age bin in kg carbon per m2 per second', &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"age bin" should be "land use type".

@github-project-automation github-project-automation bot moved this from Finding Reviewers to Under Review in FATES Pull Request Planning and Status May 13, 2025
@glemieux
Copy link
Contributor

glemieux commented Jun 5, 2025

@ckoven where is this on the priority queue for the CLM6 code freeze?

@glemieux glemieux added the software: API Pertaining to specific API updates with any host land model label Aug 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
science: land use Pertaining to land use software: API Pertaining to specific API updates with any host land model software: history output Pertaining to FATES history output variables type: enhancement
Projects
Status: Under Review
Development

Successfully merging this pull request may close these issues.

Biophysical variables by land use type?
3 participants