ESCOMP / CTSM

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

Additional "annual" (per growing season) crop outputs #1649

Open samsrabin opened 2 years ago

samsrabin commented 2 years ago

Over email, @danicalombardozzi, @billsacks, and I talked about how it might be a good idea to use the "annual" (technically, per growing season) crop output infrastructure I'm developing for #1537 (PR #1616) for additional crop output variables. This would reduce the data storage/transfer requirements and postprocessing overhead needed (as well as probability of postprocessing mistakes) for people working with crop outputs.

For example, currently, the only way to get crop yield is to sum up the daily grain C addition over the course of a growing season. It would be much easier and less storage-intensive to simply output yield once per harvest, on my new mxharvests dimension.

I thought we could use this issue to discuss the various variables that should have such output enabled, as well as implementation details such as in what data structure(s) the values should be stored.

As a starting point, I took the list of output variables requested for GGCMI phase 3. I've included the units specified by the GGCMI protocol, but these could be changed for consistency with standard CLM output units as desired.

Done? Variable units comment (GGCMI) comment (for CLM)
Yield t ha-1 gs-1 (dry matter) crop failures or harvest events before physiological maturity should assigned 0 t ha -1 and grid cells not simulated should be assigned NA
Total above ground biomass t ha-1 gs-1 (dry matter) total biomass minus roots Value at harvest.
C:N ratio of harvested organ - dimensionless (ratio) Value at harvest.
Actual planting day day of year Already implemented in #1616 as SDATES (taken from crop_inst%sdates_thisyr).
Actual planting year calendar year
Anthesis "date" days from planting year not necessary as computed as day from planting for which the year is recorded, 0-based index, i.e. day of planting is day 0
Maturity "date" days from planting year not necessary as computed as day from planting for which the year is recorded, 0-based index, i.e. day of planting is day 0 NOT the same as #1616's HDATES (taken from crop_inst%hdates_thisyr), which has units "day of year" like SDATES.[^1]
Actual harvest year calendar year
Potential irrigation requirements kg m-2 gs-1 Soil water demand required to avoid water stress, excluding any water losses associated with application or transport and without constraints due to water availability Cumulative over growing season; value saved at harvest.
Actual Evapotranspiration (growing season sum) kg m-2 gs-1 AET = evaporation + transpiration + interception Cumulative over growing season; value saved at harvest.
Soil moisture of upper 1m (monthly) kg m-3 monthly average actual absolute available soil water content of the upper 1m soil column (above wilting point); This was nontrivial to implement in LPJ-GUESS; I suggest just offloading it to postprocessing.
Soil moisture at maturity kg m-2 absolute extractable soil water content at maturity (above wilting point)
Transpiration (growing season sum) kg m-2 gs-1 Cumulative over growing season; value saved at harvest.
Evaporation (growing season sum) kg m-2 gs-1 Cumulative over growing season; value saved at harvest.
Runoff (total growing season sum, subsurface + surface) kg m-2 gs-1 Cumulative over growing season; value saved at harvest.
Total root biomass t ha-1 gs-1 (dry matter) Value at harvest.
Total Nr uptake (total growing season sum) kgN ha-1 gs-1 Cumulative over growing season; value saved at harvest.
Total Nr inputs (total growing season sum) kgN ha-1 gs-1 organic and inorganic nitrogen Cumulative over growing season; value saved at harvest.
Total Nr losses (total growing season sum) kgN ha-1 gs-1 organic and inorganic nitrogen Cumulative over growing season; value saved at harvest.
N2O emissions gN m-2 gs-1 Cumulative over growing season; value saved at harvest.
N2 emissions gN m-2 gs-1 Cumulative over growing season; value saved at harvest.
N leaching gN m-2 gs-1 organic and inorganic nitrogen Cumulative over growing season; value saved at harvest.
C emissions gC m-2 gs-1 all gaseous losses of C to the atmosphere. Cumulative over growing season; value saved at harvest.
CH4 emissions gC m-2 gs-1 methane losses to the atmosphere. Cumulative over growing season; value saved at harvest.
Maturity status - fraction of heat units accumulated
Maturity index - 1: full maturity reached at harvest; crop failures: -1: maturity reached, but not full maturity (harvested); -2: maturity not reached (not harvested = crop failure); -3: crop failure due to temperature stress (too hot or too cold); -4: crop failure due to water stress; -5: crop failure due to frost

[^1]: Instead, we could think about a "growing season length" variable for this, with HDATES remaining as the actual "harvest date."

All of these could be output on the mxharvests dimension. Currently, sowing date (SDATES) is output on the mxsowings dimension, but because by definition mxharvests > mxsowings, it could go on mxharvests too.

As far as implementation goes, right now I have SDATES and HDATES being set up in the CropType module:

this%sdates_thisyr(begp:endp,:) = spval
call hist_addfld2d (fname='SDATES', units='day of year', type2d='mxsowings', &
     avgflag='I', long_name='actual crop sowing dates; should only be output annually', &
     ptr_patch=this%sdates_thisyr, default='inactive')

this%hdates_thisyr(begp:endp,:) = spval
call hist_addfld2d (fname='HDATES', units='day of year', type2d='mxharvests', &
     avgflag='I', long_name='actual crop harvest dates; should only be output annually', &
     ptr_patch=this%hdates_thisyr, default='inactive')

(Note the avgflag='I', as these are instantaneous variables.) I could see an argument being made either way: to put all the new variables into CropType, or to put them into more thematically related structures (water, C, etc.).

samsrabin commented 2 years ago

Here is an example of how this works for SDATES and HDATES. Ignore the first timestep in the file, as that's from the year before my run started.

billsacks commented 2 years ago

This seems great – thanks for the writeup and for the discussion at today's CLM science meeting. Just recording a few thoughts from there:

  1. Before you get too far into implementation, it might be good for a few of us to get together and talk about a good way to do this in a general way. What I'm picturing ideally is that there would be infrastructure in histFileMod (maybe delegating out to some other module) to implement the logic in a general-purpose way, so that adding a new variable that is averaged over the growing season is as easy as making a hist_addfld call with appropriate arguments. (There would probably still need to be special purpose logic for the variables that handle the timings of different phenological triggers, but ideally there would be general-purpose logic for all of the variables that you want averaged over the growing season.)

  2. @dlawrenncar suggested that it could be helpful to do something similar for natural vegetation if it isn't too difficult. If (1) is done in a general way, I wondered if we could have a patch-level variable that marks the beginning and end of the growing season which is leveraged by (1). Then there could be logic in CNPhenology to populate that variable appropriately for crops vs. natural vegetation, and the infrastructure for (1) would then work effectively the same for crops and natural vegetation. As @samsrabin pointed out, though, one piece of complexity with trying to be too general about this is the max number of growing seasons for a given vegetation type.