Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grazing #1140

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open

Grazing #1140

wants to merge 25 commits into from

Conversation

ckoven
Copy link
Contributor

@ckoven ckoven commented Dec 19, 2023

An initial implementation to allow herbivores to graze and browse plants, with different grazing rates on different land use classes.

Description:

This PR adds the basic capability to have grazers and browsers eat plants. The basic idea is to specify this as a rate of consumption in units of 1/time. I.e. grazers and browsers eat X% of all accessible leaves of edible plants per day on columns of land-use type Y, as controlled by the parameter fates_landuse_grazing_rate(fates_landuseclass). The specification of what is considered edible plants is parametric and controlled by a PFT-level trait fates_landuse_grazing_palatability(fates_pft), so e.g. this can be specified to include grazers (who eat herbaceous plants only) and/or browsers (who eat the leaves of woody plants). And then all leaves of that PFT on columns of that land use type that are below a height of parameter fates_landuse_grazing_maxheight can be subject to herbivory.

The fate of the eaten material is controlled by three "use-efficiency" parameters: fates_landuse_grazing_carbon_use_eff', fates_landuse_grazing_nitrogen_use_eff, 'fates_landuse_grazing_phosphorus_use_eff'. So some mass can be lost from the ecosystem and some can be added to the litter pools via manure (and, I suppose, mortality of grazers).

Default parameter values that are there now (all of which extremely subject to change) are to make this only apply on pasture and rangeland, with a rate of 4% per day based on https://doi.org/10.5194/gmd-11-815-2018 by @samsrabin et al., and currently only grazers (i.e. only applies to nonwoody PFTs). I couldn't find a whole lot of data on the use-efficiency parameters, but those shouldn't be too important until we are running nutrient cycles at large scale under transient change.

fixes #936

Collaborators:

Expectation of Answer Changes:

This will be answer changing if the parameters are set to allow grazing.

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

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:

@ckoven ckoven added the draft label Dec 19, 2023
@glemieux glemieux requested a review from samsrabin May 28, 2024 18:44
@glemieux glemieux requested a review from jenniferholm June 17, 2024 19:24
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.

Not sure if this was actually ready for review, as it has the "draft" tag but isn't a Draft in the Github sense. Anyway, I've made some (initial?) comments. Also: Where are the new parameters actually read?


currentSite%mass_balance(element_id)%herbivory_flux_out = &
currentSite%mass_balance(element_id)%herbivory_flux_out + &
leaf_herbivory * (1._r8 - herbivory_element_use_efficiency) * currentCohort%n
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guessing herbivory_flux_out is actually sent to the atmosphere by the HLM, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it isn't yet, but will be in a future update.


function GetHerbivory(this, organ_id, element_id, position_id) result(herbivory_val)

! This function is very very similar to GetBurned
Copy link
Contributor

Choose a reason for hiding this comment

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

In fact it looks identical, aside from herbivory replacing burned. Could these be replaced with a single function? Named, e.g., GetDisturbed.

do i_pos = 1,prt_global%state_descriptor(i_var)%num_pos

! The mass that is leaving the plant
consumed_mass = mass_fraction * prt%variables(i_var)%val(i_pos)
Copy link
Contributor

Choose a reason for hiding this comment

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

consumed_mass should presumably be herbivore_consumed_mass?

@ckoven
Copy link
Contributor Author

ckoven commented Jul 8, 2024

Not sure if this was actually ready for review, as it has the "draft" tag but isn't a Draft in the Github sense. Anyway, I've made some (initial?) comments. Also: Where are the new parameters actually read?

Thanks @samsrabin! Yes, this is draft in the sense that it wasn't done or tested. And yes, one of the things that isn't done yet is the code to actually read the new parameters. But better to get eyes on it sooner rather than later.

@glemieux glemieux added the parameter file Pertaining to changes to the FATES parameter file label Jul 22, 2024
@ckoven ckoven removed the draft label Oct 31, 2024
@rgknox
Copy link
Contributor

rgknox commented Nov 18, 2024

We need to bump this value up to something bigger, we are hitting our limit on maximum parameters already:

https://github.com/NGEET/fates/blob/main/main/FatesParametersInterface.F90#L12

Maybe 400?

Copy link
Contributor

@glemieux glemieux left a comment

Choose a reason for hiding this comment

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

I had some minor suggested name changes and one question. I'll push an update to add the xml patch file for the cdl update.

biogeochem/FatesLandUseChangeMod.F90 Outdated Show resolved Hide resolved
main/EDMainMod.F90 Outdated Show resolved Hide resolved
main/FatesHistoryInterfaceMod.F90 Show resolved Hide resolved
Bug fix for issue NGEET#1301

Corrects when the fraction of burnt fuel is zero'd and how the litter
mass is updated based on that fraction.
@glemieux
Copy link
Contributor

glemieux commented Jan 21, 2025

Preliminary regression testing against sci.1.80.6_api.37.0.0-ctsm5.3.018 baseline shows expected FIELDLIST differences due to the new FATES_GRAZING history output not being available in the baselines. Almost all other tests are B4B, with the exception of the FatesColdPRT2 test:

  525 dec1212.hsn.de.hpc.ucar.edu 622: forrtl: severe (408): fort: (2): Subscript #1 of the array MASS_BALANCE has value 4 which is greater than the upper bound of 3
  526 dec1212.hsn.de.hpc.ucar.edu 622:
  527 dec1212.hsn.de.hpc.ucar.edu 622: Image              PC                Routine            Line        Source
  528 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001D15A0B  edphysiologymod_m        2964  EDPhysiologyMod.F90
  529 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001CD062B  edphysiologymod_m         485  EDPhysiologyMod.F90
  530 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001BFE5BB  edmainmod_mp_ed_i         785  EDMainMod.F90
  531 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001BF7DB2  edmainmod_mp_ed_e         223  EDMainMod.F90
  532 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000000B13944  clmfatesinterface        1250  clmfates_interfaceMod.F90
  533 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000000A89E08  clm_driver_mp_clm        1143  clm_driver.F90

I haven't dug into this yet. Any initial thoughts @rgknox?

Results: /glade/u/home/glemieux/scratch/ctsm-tests/tests_pr1140-fates-woodyfix

@ckoven
Copy link
Contributor Author

ckoven commented Jan 22, 2025

Preliminary regression testing against sci.1.80.6_api.37.0.0-ctsm5.3.018 baseline shows expected FIELDLIST differences due to the new FATES_GRAZING history output not being available in the baselines. Almost all other tests are B4B, with the exception of the FatesColdPRT2 test:

  525 dec1212.hsn.de.hpc.ucar.edu 622: forrtl: severe (408): fort: (2): Subscript #1 of the array MASS_BALANCE has value 4 which is greater than the upper bound of 3
  526 dec1212.hsn.de.hpc.ucar.edu 622:
  527 dec1212.hsn.de.hpc.ucar.edu 622: Image              PC                Routine            Line        Source
  528 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001D15A0B  edphysiologymod_m        2964  EDPhysiologyMod.F90
  529 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001CD062B  edphysiologymod_m         485  EDPhysiologyMod.F90
  530 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001BFE5BB  edmainmod_mp_ed_i         785  EDMainMod.F90
  531 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000001BF7DB2  edmainmod_mp_ed_e         223  EDMainMod.F90
  532 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000000B13944  clmfatesinterface        1250  clmfates_interfaceMod.F90
  533 dec1212.hsn.de.hpc.ucar.edu 622: cesm.exe           0000000000A89E08  clm_driver_mp_clm        1143  clm_driver.F90

I haven't dug into this yet. Any initial thoughts @rgknox?

Results: /glade/u/home/glemieux/scratch/ctsm-tests/tests_pr1140-fates-woodyfix

I think I see the error that caused this, will fix.

main/EDMainMod.F90 Outdated Show resolved Hide resolved
CamelCase! (camels are grazers too)

Co-authored-by: Gregory Lemieux <[email protected]>
Copy link
Contributor

@jenniferholm jenniferholm left a comment

Choose a reason for hiding this comment

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

Thanks Charlie this is really cool work. My biggest question was just some confusion around if mass can be loss from the ecosystem via both food/consumption pathway and to the litter flux to the atmosphere, and added to the litter via manure. Are all three pathways occurring, and is the order correct? Plus does litter from natural litter fluxes plus manure equal the total litter in the history outputs? I'm not sure that made sense, but wondering if we could separate those out? Thanks!

@@ -2849,6 +2851,8 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
integer :: numlevsoil ! Actual number of soil layers

real(r8) :: SF_val_CWD_frac_adj(4) !SF_val_CWD_frac adjusted based on cohort dbh
real(r8) :: leaf_herbivory
real(r8) :: herbivory_element_use_efficiency
!----------------------------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe give a short definition of these two? leaf_herbivory and herbivory_element_use_efficiency

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

@@ -2928,7 +2943,9 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
do dcmpy=1,ndcmpy
dcmpy_frac = GetDecompyFrac(pft,leaf_organ,dcmpy)
litt%leaf_fines_in(dcmpy) = litt%leaf_fines_in(dcmpy) + &
(leaf_m_turnover+repro_m_turnover) * plant_dens * dcmpy_frac
(leaf_m_turnover+repro_m_turnover + &
leaf_herbivory * herbivory_element_use_efficiency) * &
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to help me understand the steps, will the leaf litter here already take into account the leaf mass that is consumed and "stays" in the animal as food, and only a portion returning to the litter as "manure"? Is that the herbivory_element_use_efficiency parameter, or something else? Because I'm also confused about what portion of the litter is food, is manure, and/or to the atmosphere, and if all 3 paths are tracked?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The actual grazing animals here (as with all heterotrophs in the soil BGC code) aren't tracked, they only exist as a transformation of leaf biomass to either litter (proportional to herbivory_element_use_efficiency) or the atmosphere (proportional to 1- herbivory_element_use_efficiency) . So this pathway here is the fraction that is returned to litter. In principle this is via manure (and I guess some fraction of animals die while grazing), but for simplicity we are just tracking it as flux into the leaf litter pool, so that it gets a shallow vertical profile like other sources of leaf litter.


site_mass%herbivory_flux_out = &
site_mass%herbivory_flux_out + &
leaf_herbivory * (1._r8 - herbivory_element_use_efficiency) * currentCohort%n
Copy link
Contributor

Choose a reason for hiding this comment

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

Since it looks like 1._r8 - herbivory_element_use_efficiency is the portion that goes to the atmosphere, is the other portion only going to manure, food diet consumption, or both? My bad if I'm not following

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no food diet here. I guess all trophic levels above the grazers (i.e. including humans) should be considered lumped into the herbivory_element_use_efficiency term.

@@ -6764,6 +6770,12 @@ subroutine define_history_vars(this, initialize_variables)
upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, &
index = ih_npp_stor_si)

call this%set_history_var(vname='FATES_GRAZING', units='kg m-2 s-1', &
long='grazing by herbivores of leaves 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.

This is great to have this FATES_GRAZING output and know the mass of leaves eaten. In the future could we also have a FATES_GRAZING_LITTER_OUT type output, that gives us an idea of the amount of manure output. Or helps to differentiate how much litter is natural from turnover vs. litter from herbivores. And maybe useful later for CH4 tracking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes good idea. Will add to to-do list.


fates_landuse_grazing_nitrogen_use_eff = 0.25 ;

fates_landuse_grazing_phosphorus_use_eff = 0.5 ;
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these _use_eff values just placeholders, or from literature (Sam's paper)? Why again is the carbon_use_eff = 0 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These values are fairly arbitrary right now. I am only testing the simplest value, which is carbon-only and where all grazed carbon is lost to the atmosphere. Will parametrically test the consequences of adding these other pathways and nutrients in time.

! with herbivory. There is only one destiny for eaten mass within
! the organ, and that is outside the plant.
! It is also assumed that non PARTEH parts of the code (ie the grazing-model)
! will decide what to do with the consumed mass (i.e. sent it to the litter
Copy link
Contributor

Choose a reason for hiding this comment

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

Just for clarity and ease of understanding, maybe explicitly say where the “grazing-model” is for tracking and clarity. Is this “subroutine FatesGrazing” you mean or something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor Author

@ckoven ckoven left a comment

Choose a reason for hiding this comment

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

Thanks @jenniferholm for these questions. Tried to update the documentation to capture these points.

biogeochem/EDPhysiologyMod.F90 Outdated Show resolved Hide resolved
biogeochem/EDPhysiologyMod.F90 Outdated Show resolved Hide resolved
@@ -2928,7 +2943,9 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
do dcmpy=1,ndcmpy
dcmpy_frac = GetDecompyFrac(pft,leaf_organ,dcmpy)
litt%leaf_fines_in(dcmpy) = litt%leaf_fines_in(dcmpy) + &
(leaf_m_turnover+repro_m_turnover) * plant_dens * dcmpy_frac
(leaf_m_turnover+repro_m_turnover + &
leaf_herbivory * herbivory_element_use_efficiency) * &
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The actual grazing animals here (as with all heterotrophs in the soil BGC code) aren't tracked, they only exist as a transformation of leaf biomass to either litter (proportional to herbivory_element_use_efficiency) or the atmosphere (proportional to 1- herbivory_element_use_efficiency) . So this pathway here is the fraction that is returned to litter. In principle this is via manure (and I guess some fraction of animals die while grazing), but for simplicity we are just tracking it as flux into the leaf litter pool, so that it gets a shallow vertical profile like other sources of leaf litter.

@@ -2849,6 +2851,8 @@ subroutine CWDInput( currentSite, currentPatch, litt, bc_in)
integer :: numlevsoil ! Actual number of soil layers

real(r8) :: SF_val_CWD_frac_adj(4) !SF_val_CWD_frac adjusted based on cohort dbh
real(r8) :: leaf_herbivory
real(r8) :: herbivory_element_use_efficiency
!----------------------------------------------------------------------
Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.


currentSite%mass_balance(element_id)%herbivory_flux_out = &
currentSite%mass_balance(element_id)%herbivory_flux_out + &
leaf_herbivory * (1._r8 - herbivory_element_use_efficiency) * currentCohort%n
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it isn't yet, but will be in a future update.


site_mass%herbivory_flux_out = &
site_mass%herbivory_flux_out + &
leaf_herbivory * (1._r8 - herbivory_element_use_efficiency) * currentCohort%n
Copy link
Contributor Author

Choose a reason for hiding this comment

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

no food diet here. I guess all trophic levels above the grazers (i.e. including humans) should be considered lumped into the herbivory_element_use_efficiency term.

@@ -6764,6 +6770,12 @@ subroutine define_history_vars(this, initialize_variables)
upfreq=group_dyna_simple, ivar=ivar, initialize=initialize_variables, &
index = ih_npp_stor_si)

call this%set_history_var(vname='FATES_GRAZING', units='kg m-2 s-1', &
long='grazing by herbivores of leaves in kg carbon per m2 per second', &
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes good idea. Will add to to-do list.


fates_landuse_grazing_nitrogen_use_eff = 0.25 ;

fates_landuse_grazing_phosphorus_use_eff = 0.5 ;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These values are fairly arbitrary right now. I am only testing the simplest value, which is carbon-only and where all grazed carbon is lost to the atmosphere. Will parametrically test the consequences of adding these other pathways and nutrients in time.

! with herbivory. There is only one destiny for eaten mass within
! the organ, and that is outside the plant.
! It is also assumed that non PARTEH parts of the code (ie the grazing-model)
! will decide what to do with the consumed mass (i.e. sent it to the litter
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

parteh/PRTLossFluxesMod.F90 Outdated Show resolved Hide resolved
@glemieux
Copy link
Contributor

Preliminary regression testing against sci.1.80.6_api.37.0.0-ctsm5.3.018 baseline shows expected FIELDLIST differences due to the new FATES_GRAZING history output not being available in the baselines. Almost all other tests are B4B, with the exception of the FatesColdPRT2 test:

Rerunning the full fates regression tests results in all passing now. Note that these were not tested against a baseline as these are intended as preliminary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
parameter file Pertaining to changes to the FATES parameter file
Projects
Status: Under Review
Development

Successfully merging this pull request may close these issues.

5 participants