NGEET / fates

repository for the Functionally Assembled Terrestrial Ecosystem Simulator (FATES)
Other
105 stars 92 forks source link

Refactor and standardize per-ageclass history #1252

Open samsrabin opened 2 months ago

samsrabin commented 2 months ago

Description:

As noted in Issue #1205, some per-ageclass history variables are weighted based on a patch's area (or a cohort's density) relative to age class area, whereas others are weighted based on that relative to total site area. To avoid confusion, this should be standardized. Discussion led us to decide on standardizing to the latter to avoid order-of-operations issues.

During development, I discovered and fixed two other bugs:

Supersedes PR #1225, where I had made the opposite change (standardizing all to use per-ageclass area).

Collaborators:

@ckoven, @rgknox

Expectation of Answer Changes:

These variables are changed to be weighted relative to site area (rather than age-class area):

These variables are changed to be weighted relative to site-wide canopy area (rather than age-class canopy area):

These variables are affected by bug fixes:

Other per-ageclass variables see roundoff-level changes as a result of refactoring (absolute RMSE < 1e-12, relative RMSE < 1e-13). In my testing (SMS_Lm49.f10_f10_mg37.I2000Clm60Fates.derecho_intel.clm-FatesColdAllVarsMonthly), the following were affected:

Answers from that test (at 1aff666) compared to baseline can be found here. Note that FATES_NPLANT_SZAPPF was not tested to see if it sums correctly across the age-class axis because I don't have a way to handle triplexed variables; however, it was only affected at roundoff level by this work.

Checklist

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

Contributor

Integrator

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:

samsrabin commented 1 month ago

Just discovered some more per-ageclass variables to move out of update_history_dyn2().

samsrabin commented 1 month ago

This is ready for review. The bulk of the refactoring was moving the age-class variable calculations from update_history_dyn2() and update_history_hifrq2() to update_history_dyn2_ageclass() and update_history_hifrq2_ageclass(), respectively. However, I'm now thinking that it would be better for there to be a bunch of subroutines, each focused on a single theme (e.g. biomass, C fluxes, fire, etc.). The history update subroutines—especially update_history_dyn2()—are so huge that it's easy to lose track of where one is, which may have led to mistakes like #1261, where some variables were incorrectly in a very large if block.

That said, I wouldn't want to turn this PR into that. I would rather merge this as-is, then file an issue for someone to tackle the bigger refactor in the future.

samsrabin commented 1 month ago
samsrabin commented 3 weeks ago

@rgknox @ckoven This is ready for re-review. The only remaining thing I need to ask about (marked by TODOs in the code) is that the reproductive biomass seems to not be included in total biomass in some parts of the history code, whereas it is included in others. Do you think there's a reason for that?