Skip to content

Conversation

@samsrabin
Copy link
Member

@samsrabin samsrabin commented Nov 26, 2025

Description of changes

Adds a bunch of history outputs with the mxharvests dimension (max number of crop harvests per year; 2).

MAX_TLAI_PERHARV gives the maximum total LAI seen across the growing season.

20 other outputs give the biomass for five C pools (leaf, grain, stem, fine root, coarse root) at three crop phase transitions (emergence, anthesis, maturity) and harvest (which may not happen at maturity).

Also adds an option to suppress a warning about low gddmaturity, which I used during the CRU-JRA crop calendar work.

Specific notes

Contributors other than yourself, if any: None

CTSM Issues Fixed (include github issue #): None

Are answers expected to change (and if so in what way)? No

Any User Interface Changes (namelist or namelist defaults changes)? No

Does this create a need to change or add documentation? Did you do so? Will need to update non-FATES output list; no.

Testing performed

✅ aux_clm

aux_clm reveals what seem to be threading problems with MAX_TLAI_PERHARV, which fails COMPARE_base_rest in ER[PS]_Ly3_P64x2 tests but not an ERS_Ly3 test. Resolved with a7e66aa.

✅ Nonsense check: Correct relative number of negative biomass pool outputs

The biomass pool outputs should be negative when a valid harvest doesn't occur (i.e., we're harvesting, and not a "fake harvest" or when the crop doesn't make it to the given phase transition.

  1. Because these values are only ever written at the time of valid harvest, the AT_HARVEST values should never be negative when a valid harvest occurs.
  2. Because anthesis can't occur before emergence, the number of negative AT_ANTHESIS values should always be ≥ the number of negative AT_EMERGENCE values.

This check passes in my CUPiD notebook for case clm6_crops_omni05_unsimgeneric, run with a version up-to-date with commit 319be76:

['FROOTC_AT_EMERGENCE_PERHARV', 'LIVECROOTC_AT_EMERGENCE_PERHARV']: 12 negative at valid harvest
['FROOTC_AT_ANTHESIS_PERHARV', 'LIVECROOTC_AT_ANTHESIS_PERHARV']: 6498 negative at valid harvest
['FROOTC_AT_MATURITY_PERHARV', 'LIVECROOTC_AT_MATURITY_PERHARV']: 0 negative at valid harvest
['FROOTC_AT_EMERGENCE_PERHARV', 'LIVECROOTC_AT_EMERGENCE_PERHARV']: 2 negative at valid harvest
['FROOTC_AT_ANTHESIS_PERHARV', 'LIVECROOTC_AT_ANTHESIS_PERHARV']: 2880 negative at valid harvest
['FROOTC_AT_MATURITY_PERHARV', 'LIVECROOTC_AT_MATURITY_PERHARV']: 0 negative at valid harvest
['LEAFC_AT_EMERGENCE_PERHARV', 'LIVESTEMC_AT_EMERGENCE_PERHARV', 'REPRC_AT_EMERGENCE_PERHARV']: 3 negative at valid harvest
['LEAFC_AT_ANTHESIS_PERHARV', 'LIVESTEMC_AT_ANTHESIS_PERHARV', 'REPRC_AT_ANTHESIS_PERHARV']: 4304 negative at valid harvest
['LEAFC_AT_MATURITY_PERHARV', 'LIVESTEMC_AT_MATURITY_PERHARV', 'REPRC_AT_MATURITY_PERHARV']: 0 negative at valid harvest
['FROOTC_AT_EMERGENCE_PERHARV', 'LIVECROOTC_AT_EMERGENCE_PERHARV']: 2 negative at valid harvest
['FROOTC_AT_ANTHESIS_PERHARV', 'LIVECROOTC_AT_ANTHESIS_PERHARV']: 2882 negative at valid harvest
['FROOTC_AT_MATURITY_PERHARV', 'LIVECROOTC_AT_MATURITY_PERHARV']: 0 negative at valid harvest

To do

  • Fix threading issue.
  • Add HARVORGANC equivalent but JUST for grain. Will match what I have there for now, because grain is all CLM simulates by default. But it'll differ with the options underneath. (Do not name GRAIN unless you fix LPREPRSTRUCT test to handle this.) People should just use existing GRAINC_TO_(FOOD|SEED)_PERHARV outputs.
  • Add support for for_testing_use_second_grain_pool and/or for_testing_use_repr_structure_pool true (or throw error in that case). See above.

@samsrabin samsrabin self-assigned this Nov 26, 2025
@samsrabin samsrabin added enhancement new capability or improved behavior of existing capability bfb bit-for-bit science Enhancement to or bug impacting science next this should get some attention in the next week or two. Normally each Thursday SE meeting. labels Nov 26, 2025
Was using repr_grainc_to_food_patch + repr_grainc_to_seed_patch, but those don't get updated until after the harvest in CropPhenology, which is where the last CropPhaseTransitionBiomass() is called. They also, obviously, only include grain. Now using reproductivec_patch.
@samsrabin samsrabin removed the next this should get some attention in the next week or two. Normally each Thursday SE meeting. label Jan 8, 2026
@samsrabin samsrabin added this to the ctsm6.0.0 (code freeze) milestone Jan 8, 2026
@samsrabin samsrabin marked this pull request as ready for review January 8, 2026 22:25
@samsrabin samsrabin added the next this should get some attention in the next week or two. Normally each Thursday SE meeting. label Jan 8, 2026
@samsrabin
Copy link
Member Author

Adding "next" label until we get a reviewer.

@samsrabin samsrabin added the PR status: awaiting review Work on this PR is paused while waiting for review. label Jan 8, 2026
@wwieder
Copy link
Contributor

wwieder commented Jan 8, 2026

@slevis-lmwg can you take this one one, I think you have the most familiarity with the crop model. Is it helpful to go through the PR with @samsrabin ?

@wwieder wwieder requested review from slevis-lmwg and wwieder and removed request for wwieder January 8, 2026 22:31
@samsrabin samsrabin removed the next this should get some attention in the next week or two. Normally each Thursday SE meeting. label Jan 9, 2026
Copy link
Contributor

@slevis-lmwg slevis-lmwg left a comment

Choose a reason for hiding this comment

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

@samsrabin thank you for going over this work with me. I'm interested in looking again when you resolve the comment that you posted: https://github.com/ESCOMP/CTSM/pull/3633/changes#r2677039517

Also we agreed that this is fine in b4b-dev because it changes field-lists and not answers.


else if (do_harvest) then
cphase(p) = cphase_harvest
call crop_inst%CropPhaseTransitionBiomass(p, cnveg_carbonstate_inst)
Copy link
Contributor

Choose a reason for hiding this comment

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

In other phases you include
if (cphase(p) /= cphase_orig) then before calling CropPhaseTransitionBiomass.
Here do you not because harvest occurs in one tstep always?

Copy link
Member Author

@samsrabin samsrabin Jan 9, 2026

Choose a reason for hiding this comment

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

More like: By definition, if we're harvesting, then it wasn't in cphase_harvest at the beginning of the subroutine.

Copy link
Member Author

Choose a reason for hiding this comment

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

Another way of saying this: do_harvest means "cphase(p) isn't cphase_harvest but now it should be."

Copy link
Contributor

Choose a reason for hiding this comment

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

I recommend a simple comment in the code to explain that.

@samsrabin samsrabin requested a review from slevis-lmwg January 9, 2026 22:58
Comment on lines +1079 to +1103
call restartvar(ncid=ncid, flag=flag, varname='frootc_maturity_thisyr_patch', xtype=ncd_double, &
dim1name='pft', dim2name='mxharvests', switchdim=.true., &
long_name='Fine root C at maturity for harvests in this patch this year', units='unitless', &
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=this%frootc_maturity_thisyr_patch)
call restartvar(ncid=ncid, flag=flag, varname='livecrootc_maturity_thisyr_patch', xtype=ncd_double, &
dim1name='pft', dim2name='mxharvests', switchdim=.true., &
long_name='Live coarse root C at maturity for harvests in this patch this year', units='unitless', &
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_maturity_thisyr_patch)
call restartvar(ncid=ncid, flag=flag, varname='livestemc_maturity_thisyr_patch', xtype=ncd_double, &
dim1name='pft', dim2name='mxharvests', switchdim=.true., &
long_name='Live stem C at maturity for harvests in this patch this year', units='unitless', &
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_maturity_thisyr_patch)
call restartvar(ncid=ncid, flag=flag, varname='leafc_maturity_thisyr_patch', xtype=ncd_double, &
dim1name='pft', dim2name='mxharvests', switchdim=.true., &
long_name='Leaf C at maturity for harvests in this patch this year', units='unitless', &
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=this%leafc_maturity_thisyr_patch)
call restartvar(ncid=ncid, flag=flag, varname='reprc_maturity_thisyr_patch', xtype=ncd_double, &
dim1name='pft', dim2name='mxharvests', switchdim=.true., &
long_name='Reproductive C at maturity for harvests in this patch this year', units='unitless', &
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=this%reprc_maturity_thisyr_patch)
Copy link
Contributor

Choose a reason for hiding this comment

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

should these have been "harvest" rather than maturity?

Copy link
Contributor

Choose a reason for hiding this comment

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

For now I will wait for successful aux_clm testing before I hit "approve" if you don't mind @samsrabin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bfb bit-for-bit enhancement new capability or improved behavior of existing capability PR status: awaiting review Work on this PR is paused while waiting for review. science Enhancement to or bug impacting science

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants