ESCOMP / CTSM

Community Terrestrial Systems Model (includes the Community Land Model of CESM)
http://www.cesm.ucar.edu/models/cesm2.0/land/
Other
308 stars 311 forks source link

Incorrect Dec. 31 sowing prevents sowing in first year #2190

Open samsrabin opened 1 year ago

samsrabin commented 1 year ago

Brief summary of bug

In older versions of CLM, the use of get_curr_calday() instead of get_prev_calday() would sometimes cause crops to be sown in the last timestep of Dec. 31 when their sowing window didn't actually start until Jan. 1. Newer versions are supposed to handle this by detecting such incorrect sowings and harvesting immediately, but they don't.

General bug information

CTSM version you are using: ctsm5.1.dev142

Does this bug cause significantly incorrect results in the model's science? Only in the first year after resuming from an old restart.

Configurations affected: All crop compsets.

Details of bug

This is the code that tells CLM to harvest when an "incorrectly sown on Dec. 31" patch is detected (idop = day of planting, jday = day of year today, sowing_count = number of sowings this calendar year, sdates_thisyr_patch = list of sowing dates this calendar year): https://github.com/ESCOMP/CTSM/blob/2e2434d10e35404be5284022270f474d50d2db26/src/biogeochem/CNPhenologyMod.F90#L2153-L2157

(Note that when a crop was incorrectly sown in the last timestep of Dec. 31, its idop would be set misleadingly to 1.)

This harvest never happens because, earlier in CropPhenology(), such patches get their sowing_count set to 1: https://github.com/ESCOMP/CTSM/blob/2e2434d10e35404be5284022270f474d50d2db26/src/biogeochem/CNPhenologyMod.F90#L1928-L1931

I suggest changing that as follows:

if (croplive(p) .and. idop(p) <= jday .and. sowing_count(p) == 0) then
    ! Special handling for incorrect Dec. 31 plantings
    if (is_beg_curr_year() .and. idop(p) == 1) then
        crop_inst%sdates_thisyr_patch(p,1) = avg_dayspyr
    else
        sowing_count(p) = 1
        crop_inst%sdates_thisyr_patch(p,1) = real(idop(p), r8)
    end if
end if

These criteria for special handling are intentionally strict. We only know that a planting was incorrectly on Dec. 31 if its idop says it was planted Jan. 1 (i.e., day 1) but right now it's the first timestep of the year and we haven't yet reached the "should we plant today" checks.

Ideally I would set sdate to the number of days in the previous year, but I haven't looked into how to do that yet, so for now I just put avg_dayspyr. (There is no difference for calendars that don't include leap years.)

Important details of your setup / configuration so we can reproduce the bug

I'm seeing this behavior in a startup run with a 2-degree IHIST compset starting 1850-01-01.

samsrabin commented 1 year ago

This might allow reducing RXCROPMATURITY test length by at least one year in each of the two runs, making #2166 more feasible.

samsrabin commented 7 months ago

Steps to address this:

  1. Generate a baseline with a test run evidencing the misbehavior.
  2. Functionize lines 1928-1931 and unit-test them, ensuring unit test fails.
  3. Check that it's b4b with the previous commit.
  4. Fix the logic, ensuring unit test passes.
  5. Redo test run, ensuring that sowing dates only differ in the first year.