Skip to content

Commit

Permalink
Merge branch 'cropresidues3' into tillage-and-residues3
Browse files Browse the repository at this point in the history
  • Loading branch information
samsrabin committed Sep 11, 2023
2 parents c5171fe + 1ec3f62 commit ac63671
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 27 deletions.
7 changes: 6 additions & 1 deletion bld/CLMBuildNamelist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2182,8 +2182,13 @@ sub setup_logic_crop_inparm {
}
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "initial_seed_at_planting",
'use_crop'=>$nl->get_value('use_crop') );

my $crop_residue_removal_frac = $nl->get_value('crop_residue_removal_frac');
if ( $crop_residue_removal_frac < 0.0 or $crop_residue_removal_frac > 1.0 ) {
$log->fatal_error("crop_residue_removal_frac must be in range [0, 1]");
}
} else {
error_if_set( $nl, "Can NOT be set without crop on", "baset_mapping", "baset_latvary_slope", "baset_latvary_intercept" );
error_if_set( $nl, "Can NOT be set without crop on", "baset_mapping", "baset_latvary_slope", "baset_latvary_intercept", "crop_residue_removal_frac" );
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'crop_fsat_equals_zero' );
}
}
Expand Down
2 changes: 2 additions & 0 deletions bld/namelist_files/namelist_defaults_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
<use_grainproduct use_crop=".true." phys="clm5_0" >.true.</use_grainproduct> <!-- 1-year grain product pool default to on for clm50 if crop is turned on -->
<use_grainproduct use_crop=".true." phys="clm5_1" >.true.</use_grainproduct> <!-- 1-year grain product pool default to on for clm50 if crop is turned on -->

<crop_residue_removal_frac>0.d+0</crop_residue_removal_frac>

<!-- Crop model options -->
<baset_mapping use_crop=".true." phys="clm4_5" >constant</baset_mapping>
<baset_mapping use_crop=".true." phys="clm5_0" >varytropicsbylat</baset_mapping>
Expand Down
7 changes: 7 additions & 0 deletions bld/namelist_files/namelist_definition_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,13 @@ Toggle to turn on the prognostic fertilizer for crop model
Toggle to turn on the 1-year grain product pool in the crop model
</entry>

<entry id="crop_residue_removal_frac" type="real" category="physics"
group="clm_inparm" valid_values="" value="0.0d00">
Fraction of post-harvest crop residues (leaf and stem) to move to
1-year product pool instead of letting them fall as litter.
<default>Default: 0.0</default>
</entry>

<entry id="baset_mapping" type="char*20" category="physics"
group="crop_inparm" valid_values="constant,varytropicsbylat" value="constant">
Type of mapping to use for base temperature for prognostic crop model
Expand Down
14 changes: 13 additions & 1 deletion src/biogeochem/CNCIsoFluxMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,16 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
iso_cnveg_cs%livestemc_patch , cnveg_cs%livestemc_patch, &
num_soilp , filter_soilp, 1._r8, 0, isotope)

call CIsoFluxCalc(&
iso_cnveg_cf%leafc_to_removedresiduec_patch , cnveg_cf%leafc_to_removedresiduec_patch, &
iso_cnveg_cs%leafc_patch , cnveg_cs%leafc_patch, &
num_soilp , filter_soilp, 1._r8, 0, isotope)

call CIsoFluxCalc(&
iso_cnveg_cf%livestemc_to_removedresiduec_patch, cnveg_cf%livestemc_to_removedresiduec_patch, &
iso_cnveg_cs%livestemc_patch , cnveg_cs%livestemc_patch, &
num_soilp , filter_soilp, 1._r8, 0, isotope)

call CIsoFluxCalc(&
iso_cnveg_cf%repr_grainc_to_seed_patch , cnveg_cf%repr_grainc_to_seed_patch, &
iso_cnveg_cs%reproductivec_patch , cnveg_cs%reproductivec_patch, &
Expand Down Expand Up @@ -497,7 +507,9 @@ subroutine CIsoFlux1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
p = filter_soilp(fp)
iso_cnveg_cf%crop_harvestc_to_cropprodc_patch(p) = &
iso_cnveg_cf%leafc_to_biofuelc_patch(p) + &
iso_cnveg_cf%livestemc_to_biofuelc_patch(p)
iso_cnveg_cf%livestemc_to_biofuelc_patch(p) + &
iso_cnveg_cf%leafc_to_removedresiduec_patch(p) + &
iso_cnveg_cf%livestemc_to_removedresiduec_patch(p)
end do

if (use_grainproduct) then
Expand Down
6 changes: 4 additions & 2 deletions src/biogeochem/CNCStateUpdate1Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,10 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
end if
if (ivt(p) >= npcropmin) then ! skip 2 generic crops
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_litter_patch(p)*dt
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_biofuelc_patch(p)*dt
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_biofuelc_patch(p)*dt
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - &
(cf_veg%livestemc_to_biofuelc_patch(p) + cf_veg%livestemc_to_removedresiduec_patch(p))*dt
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - &
(cf_veg%leafc_to_biofuelc_patch(p) + cf_veg%leafc_to_removedresiduec_patch(p))*dt
cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) &
- cf_veg%crop_seedc_to_leaf_patch(p) * dt
do k = repr_grain_min, repr_grain_max
Expand Down
6 changes: 4 additions & 2 deletions src/biogeochem/CNNStateUpdate1Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,10 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) - nf_veg%frootn_to_retransn_patch(p)*dt
ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%frootn_to_retransn_patch(p)*dt
ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_litter_patch(p)*dt
ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_biofueln_patch(p)*dt
ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - nf_veg%leafn_to_biofueln_patch(p)*dt
ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - &
(nf_veg%livestemn_to_biofueln_patch(p) + nf_veg%livestemn_to_removedresiduen_patch(p))*dt
ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) - &
(nf_veg%leafn_to_biofueln_patch(p) + nf_veg%leafn_to_removedresiduen_patch(p))*dt
ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_retransn_patch(p)*dt
ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%livestemn_to_retransn_patch(p)*dt
!
Expand Down
57 changes: 37 additions & 20 deletions src/biogeochem/CNPhenologyMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2983,7 +2983,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
use pftconMod , only : nmiscanthus, nirrig_miscanthus, nswitchgrass, nirrig_switchgrass

use CNSharedParamsMod, only : use_fun
use clm_varctl , only : CNratio_floating
use clm_varctl , only : CNratio_floating, crop_residue_removal_frac
!
! !ARGUMENTS:
integer , intent(in) :: num_soilp ! number of soil patches in filter
Expand All @@ -3008,6 +3008,9 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
real(r8) :: cropseedc_deficit_to_restore ! amount of crop seed C deficit that will be restored from this grain pool (gC/m2)
real(r8) :: cropseedn_deficit_to_restore ! amount of crop seed N deficit that will be restored from this grain pool (gN/m2)
real(r8) :: repr_grainc_to_food_thispool ! amount added to / subtracted from repr_grainc_to_food for the pool in question (gC/m2/s)
real(r8) :: leafc_remaining, livestemc_remaining
real(r8) :: leafn_remaining, livestemn_remaining
real(r8) :: removedresidue_fraction
!-----------------------------------------------------------------------

associate( &
Expand Down Expand Up @@ -3052,6 +3055,8 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
repr_structurec_to_litter => cnveg_carbonflux_inst%repr_structurec_to_litter_patch, & ! Output: [real(r8) (:,:) ] reproductive structure C to litter (gC/m2/s)
leafc_to_biofuelc => cnveg_carbonflux_inst%leafc_to_biofuelc_patch , & ! Output: [real(r8) (:) ] leaf C to biofuel C (gC/m2/s)
livestemc_to_biofuelc => cnveg_carbonflux_inst%livestemc_to_biofuelc_patch , & ! Output: [real(r8) (:) ] livestem C to biofuel C (gC/m2/s)
leafc_to_removedresiduec => cnveg_carbonflux_inst%leafc_to_removedresiduec_patch , & ! Output: [real(r8) (:) ] leaf C to removed residue C (gC/m2/s)
livestemc_to_removedresiduec => cnveg_carbonflux_inst%livestemc_to_removedresiduec_patch , & ! Output: [real(r8) (:) ] livestem C to removed residue C (gC/m2/s)
leafn => cnveg_nitrogenstate_inst%leafn_patch , & ! Input: [real(r8) (:) ] (gN/m2) leaf N
frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) fine root N

Expand All @@ -3062,6 +3067,8 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
repr_structuren_to_litter => cnveg_nitrogenflux_inst%repr_structuren_to_litter_patch, & ! Output: [real(r8) (:,:) ] reproductive structure N to litter (gN/m2/s)
leafn_to_biofueln => cnveg_nitrogenflux_inst%leafn_to_biofueln_patch , & ! Output: [real(r8) (:) ] leaf N to biofuel N (gN/m2/s)
livestemn_to_biofueln => cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch, & ! Output: [real(r8) (:) ] livestem N to biofuel N (gN/m2/s)
leafn_to_removedresiduen => cnveg_nitrogenflux_inst%leafn_to_removedresiduen_patch , & ! Output: [real(r8) (:) ] leaf N to removed residue N (gN/m2/s)
livestemn_to_removedresiduen => cnveg_nitrogenflux_inst%livestemn_to_removedresiduen_patch, & ! Output: [real(r8) (:) ] livestem N to removed residue N (gN/m2/s)
leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s)
leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Input: [real(r8) (:) ] leaf N to retranslocated N pool (gN/m2/s)
free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
Expand All @@ -3074,7 +3081,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &

! The litterfall transfer rate starts at 0.0 and increases linearly
! over time, with displayed growth going to 0.0 on the last day of litterfall

do fp = 1,num_soilp
p = filter_soilp(fp)

Expand All @@ -3085,9 +3092,6 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
t1 = 1.0_r8 / dt
frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p)

! biofuel_harvfrac is only non-zero for prognostic crops.
leafc_to_litter(p) = t1 * leafc(p)*(1._r8-biofuel_harvfrac(ivt(p))) + cpool_to_leafc(p)

! leafc_litter and frootc_to_litter for matrix
if (use_matrixcn) then
else
Expand Down Expand Up @@ -3152,13 +3156,34 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
! Cut a certain fraction (i.e., biofuel_harvfrac(ivt(p))) (e.g., biofuel_harvfrac(ivt(p)=70% for bioenergy crops) of leaf C
! and move this fration of leaf C to biofuel C, rather than move it to litter
leafc_to_biofuelc(p) = t1 * leafc(p) * biofuel_harvfrac(ivt(p))
leafc_remaining = leafc(p)*(1._r8-biofuel_harvfrac(ivt(p)))
leafn_to_biofueln(p) = t1 * leafn(p) * biofuel_harvfrac(ivt(p))
leafn_remaining = leafn(p)*(1._r8-biofuel_harvfrac(ivt(p)))

! Cut a certain fraction (i.e., biofuel_harvfrac(ivt(p))) (e.g., biofuel_harvfrac(ivt(p)=70% for bioenergy crops) of livestem C
! and move this fration of leaf C to biofuel C, rather than move it to litter
livestemc_to_litter(p) = t1 * livestemc(p)*(1._r8-biofuel_harvfrac(ivt(p))) + cpool_to_livestemc(p)
livestemc_to_biofuelc(p) = t1 * livestemc(p) * biofuel_harvfrac(ivt(p))
livestemn_to_biofueln(p) = t1 * livestemn(p) * biofuel_harvfrac(ivt(p))
livestemc_remaining = livestemc(p)*(1._r8-biofuel_harvfrac(ivt(p)))
livestemn_remaining = livestemn(p)*(1._r8-biofuel_harvfrac(ivt(p)))

! Remove residues
leafc_to_removedresiduec(p) = t1 * leafc_remaining * crop_residue_removal_frac
leafn_to_removedresiduen(p) = t1 * leafn_remaining * crop_residue_removal_frac
livestemc_to_removedresiduec(p) = t1 * livestemc_remaining * crop_residue_removal_frac
livestemn_to_removedresiduen(p) = t1 * livestemn_remaining * crop_residue_removal_frac
leafc_remaining = leafc_remaining * (1._r8 - crop_residue_removal_frac)
leafn_remaining = leafn_remaining * (1._r8 - crop_residue_removal_frac)
livestemc_remaining = livestemc_remaining * (1._r8 - crop_residue_removal_frac)
livestemn_remaining = livestemn_remaining * (1._r8 - crop_residue_removal_frac)

leafc_to_litter(p) = t1 * leafc_remaining + cpool_to_leafc(p)
livestemc_to_litter(p) = t1 * livestemc_remaining + cpool_to_livestemc(p)
livestemn_to_litter(p) = t1 * livestemn_remaining
! Sam Rabin 2023-09-11:
! leafn_to_litter is calculated below based on leafc_to_litter (updated above)
! as well as leaf C:N ratio (unaffected by biofuel harvest). It thus does not
! need to be updated here.

! Matrix for grain, livestem to litter and biofuel
if(use_matrixcn)then
Expand Down Expand Up @@ -3296,18 +3321,6 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
endif
end if

if (ivt(p) >= npcropmin) then
! NOTE(slevis, 2014-12) results in -ve livestemn and -ve totpftn
!X! livestemn_to_litter(p) = livestemc_to_litter(p) / livewdcn(ivt(p))
! NOTE(slevis, 2014-12) Beth Drewniak suggested this instead
livestemn_to_litter(p) = livestemn(p) / dt * (1._r8 - biofuel_harvfrac(ivt(p)))

! Matrix update for livestemn to litter
if(use_matrixcn)then
else
end if
end if

! save the current litterfall fluxes
prev_leafc_to_litter(p) = leafc_to_litter(p)
prev_frootc_to_litter(p) = frootc_to_litter(p)
Expand Down Expand Up @@ -3650,10 +3663,14 @@ subroutine CNCropHarvestToProductPools(bounds, num_soilp, filter_soilp, num_soil
p = filter_soilp(fp)
cnveg_carbonflux_inst%crop_harvestc_to_cropprodc_patch(p) = &
cnveg_carbonflux_inst%leafc_to_biofuelc_patch(p) + &
cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p)
cnveg_carbonflux_inst%livestemc_to_biofuelc_patch(p) + &
cnveg_carbonflux_inst%leafc_to_removedresiduec_patch(p) + &
cnveg_carbonflux_inst%livestemc_to_removedresiduec_patch(p)
cnveg_nitrogenflux_inst%crop_harvestn_to_cropprodn_patch(p) = &
cnveg_nitrogenflux_inst%leafn_to_biofueln_patch(p) + &
cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p)
cnveg_nitrogenflux_inst%livestemn_to_biofueln_patch(p) + &
cnveg_nitrogenflux_inst%leafn_to_removedresiduen_patch(p) + &
cnveg_nitrogenflux_inst%livestemn_to_removedresiduen_patch(p)
end do

if (use_grainproduct) then
Expand Down
16 changes: 16 additions & 0 deletions src/biogeochem/CNVegCarbonFluxType.F90
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ module CNVegCarbonFluxType

real(r8), pointer :: leafc_to_biofuelc_patch (:) ! leaf C to biofuel C (gC/m2/s)
real(r8), pointer :: livestemc_to_biofuelc_patch (:) ! livestem C to biofuel C (gC/m2/s)
real(r8), pointer :: leafc_to_removedresiduec_patch (:) ! leaf C to removed residues C (gC/m2/s)
real(r8), pointer :: livestemc_to_removedresiduec_patch (:) ! livestem C to removed residues C (gC/m2/s)
real(r8), pointer :: repr_grainc_to_seed_patch (:,:) ! grain C to seed for prognostic crop(gC/m2/s) [patch, repr_grain_min:repr_grain_max]

! maintenance respiration fluxes
Expand Down Expand Up @@ -662,6 +664,8 @@ subroutine InitAllocate(this, bounds, carbon_type)
this%repr_structurec_to_litter_patch(:,:) = nan
allocate(this%leafc_to_biofuelc_patch (begp:endp)) ; this%leafc_to_biofuelc_patch (:) = nan
allocate(this%livestemc_to_biofuelc_patch (begp:endp)) ; this%livestemc_to_biofuelc_patch (:) = nan
allocate(this%leafc_to_removedresiduec_patch (begp:endp)) ; this%leafc_to_removedresiduec_patch (:) = nan
allocate(this%livestemc_to_removedresiduec_patch (begp:endp)) ; this%livestemc_to_removedresiduec_patch (:) = nan
allocate(this%repr_grainc_to_seed_patch(begp:endp, repr_grain_min:repr_grain_max)) ; this%repr_grainc_to_seed_patch (:,:) = nan
allocate(this%reproductivec_xfer_to_reproductivec_patch(begp:endp, nrepr))
this%reproductivec_xfer_to_reproductivec_patch(:,:) = nan
Expand Down Expand Up @@ -967,6 +971,16 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='livestem C to biofuel C', &
ptr_patch=this%livestemc_to_biofuelc_patch)

this%leafc_to_removedresiduec_patch(begp:endp) = spval
call hist_addfld1d (fname='LEAFC_TO_REMOVEDRESIDUEC', units='gC/m^2/s', &
avgflag='A', long_name='leaf C to removed residue C', &
ptr_patch=this%leafc_to_removedresiduec_patch)

this%livestemc_to_removedresiduec_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVESTEMC_TO_REMOVEDRESIDUEC', units='gC/m^2/s', &
avgflag='A', long_name='livestem C to removed residue C', &
ptr_patch=this%livestemc_to_removedresiduec_patch)

this%repr_grainc_to_seed_patch(begp:endp,:) = spval
do k = repr_grain_min, repr_grain_max
data1dptr => this%repr_grainc_to_seed_patch(:,k)
Expand Down Expand Up @@ -4143,6 +4157,8 @@ subroutine SetValues ( this, nvegcpool, &
this%livestemc_to_litter_patch(i) = value_patch
this%leafc_to_biofuelc_patch(i) = value_patch
this%livestemc_to_biofuelc_patch(i) = value_patch
this%leafc_to_removedresiduec_patch(i) = value_patch
this%livestemc_to_removedresiduec_patch(i) = value_patch
end do

do k = 1, nrepr
Expand Down
Loading

0 comments on commit ac63671

Please sign in to comment.