Skip to content

Commit

Permalink
Merge branch 'qzhu-lbl/lnd/leaf-cn-phys' (PR #393)
Browse files Browse the repository at this point in the history
Adds soil nutrient competition in ALM

- soil nitrogen phosphorus competition, with relative demand approach,
  ECA approach and MIC outcompete plant approach
- root nutrient uptake is based on uptake kinetics
- leaf level N/P control GPP
- prognostic plant CNP stoichiometry
- add option to use dynamic carbon allocation under different nutrient stress
- add option to use energy based N2 fixation
- add option to use new phosphatase activity
- add namelist capacity for ECA
- ECA mode compatible with BGC cascade mode
- ECA mode compatible with nitrification/denitrification enabled mode
- ECA mode mineral surface P adsorption is treated a potential competitor

[BFB]
[FCC]
[NML]
LG-45

Conflicts:
	components/clm/src/biogeochem/CNAllocationMod.F90
	components/clm/src/biogeochem/CNCarbonFluxType.F90
	components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90
	components/clm/src/biogeochem/CNDecompMod.F90
	components/clm/src/biogeochem/CNEcosystemDynMod.F90
	components/clm/src/biogeochem/CNNitrogenFluxType.F90
	components/clm/src/biogeochem/CNNitrogenStateType.F90
	components/clm/src/biogeochem/CNStateType.F90
	components/clm/src/biogeochem/PStateUpdate1Mod.F90
	components/clm/src/biogeochem/PStateUpdate3Mod.F90
	components/clm/src/biogeochem/PhosphorusFluxType.F90
	components/clm/src/main/controlMod.F90
  • Loading branch information
Gautam Bisht committed Dec 4, 2015
2 parents 7025f2d + e05d9b5 commit ba5010f
Show file tree
Hide file tree
Showing 25 changed files with 3,935 additions and 1,171 deletions.
21 changes: 21 additions & 0 deletions components/clm/bld/namelist_files/namelist_definition_clm4_5.xml
Expand Up @@ -96,6 +96,27 @@ over-productive.
ALL = Supplemental Phosphorus is active for all vegetation types
</entry>


<entry id="nu_com" type="char*15" category="clm_physics"
group="clm_inparm" valid_values="RD,ECA,MIC" >
Nutrient competition mode. In each specific mode, plants/soil microbes have the different
priority to access soil nitrogen and phosphorus.
RD = competition scaled by relative nutrient demand
ECA = competition scaled by equilibrium chemical approximation theory
MIC = always assume that soil microbes out-compete plants
</entry>

<entry id="nu_com_phosphatase" type="logical" category="clm_physics"
group="clm_inparm" valid_values="" >
If TRUE, use new phosphatase activity algorithm that comes with nu_com module
</entry>

<entry id="nu_com_nfix" type="logical" category="clm_physics"
group="clm_inparm" valid_values="" >
If TRUE, use new N2 fixation algorithm that comes with nu_com module
</entry>


<entry id="create_crop_landunit" type="logical" category="clm_physics"
group="clm_inparm" valid_values="" >
If TRUE, separate the vegetated landunit into a crop landunit and a natural vegetation landunit
Expand Down
2,934 changes: 2,190 additions & 744 deletions components/clm/src/biogeochem/CNAllocationMod.F90

Large diffs are not rendered by default.

71 changes: 52 additions & 19 deletions components/clm/src/biogeochem/CNCarbonFluxType.F90
Expand Up @@ -383,7 +383,11 @@ module CNCarbonFluxType
real(r8), pointer :: annsum_litfall_patch (:) ! annual sum of litfall (gC/m2/yr) (CNDV)
real(r8), pointer :: annsum_npp_patch (:) ! patch annual sum of NPP (gC/m2/yr)
real(r8), pointer :: annsum_npp_col (:) ! col annual sum of NPP, averaged from pft-level (gC/m2/yr)
real(r8), pointer :: lag_npp_col (:) ! col lagged net primary production (gC/m2/s)
real(r8), pointer :: lag_npp_col (:) ! col lagged net primary production (gC/m2/s)

! debug
real(r8), pointer :: plant_to_litter_cflux (:) ! for the purpose of mass balance check
real(r8), pointer :: plant_to_cwd_cflux (:) ! for the purpose of mass balance check

! new variables for clm_bgc_interface & pflotran
!------------------------------------------------------------------------
Expand Down Expand Up @@ -764,6 +768,10 @@ subroutine InitAllocate(this, bounds)
allocate(this%annsum_litfall_patch (begp:endp)) ; this%annsum_litfall_patch (:) = nan
allocate(this%annsum_npp_col (begc:endc)) ; this%annsum_npp_col (:) = nan
allocate(this%lag_npp_col (begc:endc)) ; this%lag_npp_col (:) = spval

! debug
allocate(this%plant_to_litter_cflux (begc:endc)) ; this%plant_to_litter_cflux (:) = nan
allocate(this%plant_to_cwd_cflux (begc:endc)) ; this%plant_to_cwd_cflux (:) = nan

! clm_bgc_interface & pflotran
!------------------------------------------------------------------------
Expand Down Expand Up @@ -826,7 +834,7 @@ subroutine InitHistory(this, bounds, carbon_type)
this%grainc_to_food_patch(begp:endp) = spval
call hist_addfld1d (fname='GRAINC_TO_FOOD', units='gC/m^2/s', &
avgflag='A', long_name='grain C to food', &
ptr_patch=this%grainc_to_food_patch)
ptr_patch=this%grainc_to_food_patch, default='inactive')
end if

this%woodc_alloc_patch(begp:endp) = spval
Expand Down Expand Up @@ -1214,7 +1222,7 @@ subroutine InitHistory(this, bounds, carbon_type)
this%leafc_to_litter_patch(begp:endp) = spval
call hist_addfld1d (fname='LEAFC_TO_LITTER', units='gC/m^2/s', &
avgflag='A', long_name='leaf C litterfall', &
ptr_patch=this%leafc_to_litter_patch, default='inactive')
ptr_patch=this%leafc_to_litter_patch, default='active')

this%frootc_to_litter_patch(begp:endp) = spval
call hist_addfld1d (fname='FROOTC_TO_LITTER', units='gC/m^2/s', &
Expand Down Expand Up @@ -1534,12 +1542,12 @@ subroutine InitHistory(this, bounds, carbon_type)
this%availc_patch(begp:endp) = spval
call hist_addfld1d (fname='AVAILC', units='gC/m^2/s', &
avgflag='A', long_name='C flux available for allocation', &
ptr_patch=this%availc_patch, default='inactive')
ptr_patch=this%availc_patch, default='active')

this%plant_calloc_patch(begp:endp) = spval
call hist_addfld1d (fname='PLANT_CALLOC', units='gC/m^2/s', &
avgflag='A', long_name='total allocated C flux', &
ptr_patch=this%plant_calloc_patch, default='inactive')
ptr_patch=this%plant_calloc_patch, default='active')

this%excess_cflux_patch(begp:endp) = spval
call hist_addfld1d (fname='EXCESS_CFLUX', units='gC/m^2/s', &
Expand All @@ -1559,7 +1567,7 @@ subroutine InitHistory(this, bounds, carbon_type)
this%xsmrpool_recover_patch(begp:endp) = spval
call hist_addfld1d (fname='XSMRPOOL_RECOVER', units='gC/m^2/s', &
avgflag='A', long_name='C flux assigned to recovery of negative xsmrpool', &
ptr_patch=this%xsmrpool_recover_patch)
ptr_patch=this%xsmrpool_recover_patch, default='inactive')

end if ! end of if-c12

Expand Down Expand Up @@ -2724,12 +2732,12 @@ subroutine InitHistory(this, bounds, carbon_type)
this%lf_conv_cflux_col(begc:endc) = spval
call hist_addfld1d (fname='LF_CONV_CFLUX', units='gC/m^2/s', &
avgflag='A', long_name='conversion carbon due to BET and BDT area decreasing', &
ptr_col=this%lf_conv_cflux_col)
ptr_col=this%lf_conv_cflux_col, default='inactive')

this%somc_fire_col(begc:endc) = spval
call hist_addfld1d (fname='SOMC_FIRE', units='gC/m^2/s', &
avgflag='A', long_name='C loss due to peat burning', &
ptr_col=this%somc_fire_col)
ptr_col=this%somc_fire_col, default='inactive')


this%m_decomp_cpools_to_fire_col(begc:endc,:) = spval
Expand Down Expand Up @@ -2967,47 +2975,47 @@ subroutine InitHistory(this, bounds, carbon_type)
this%fire_closs_col(begc:endc) = spval
call hist_addfld1d (fname='COL_FIRE_CLOSS', units='gC/m^2/s', &
avgflag='A', long_name='total column-level fire C loss for non-peat fires outside land-type converted region', &
ptr_col=this%fire_closs_col)
ptr_col=this%fire_closs_col, default='inactive')

this%dwt_seedc_to_leaf_col(begc:endc) = spval
call hist_addfld1d (fname='DWT_SEEDC_TO_LEAF', units='gC/m^2/s', &
avgflag='A', long_name='seed source to patch-level leaf', &
ptr_col=this%dwt_seedc_to_leaf_col)
ptr_col=this%dwt_seedc_to_leaf_col, default='inactive')

this%dwt_seedc_to_deadstem_col(begc:endc) = spval
call hist_addfld1d (fname='DWT_SEEDC_TO_DEADSTEM', units='gC/m^2/s', &
avgflag='A', long_name='seed source to patch-level deadstem', &
ptr_col=this%dwt_seedc_to_deadstem_col)
ptr_col=this%dwt_seedc_to_deadstem_col, default='inactive')

this%dwt_conv_cflux_col(begc:endc) = spval
call hist_addfld1d (fname='DWT_CONV_CFLUX', units='gC/m^2/s', &
avgflag='A', long_name='conversion C flux (immediate loss to atm)', &
ptr_col=this%dwt_conv_cflux_col)
ptr_col=this%dwt_conv_cflux_col, default='inactive')

this%dwt_prod10c_gain_col(begc:endc) = spval
call hist_addfld1d (fname='DWT_PROD10C_GAIN', units='gC/m^2/s', &
avgflag='A', long_name='landcover change-driven addition to 10-yr wood product pool', &
ptr_col=this%dwt_prod10c_gain_col)
ptr_col=this%dwt_prod10c_gain_col, default='inactive')

this%prod10c_loss_col(begc:endc) = spval
call hist_addfld1d (fname='PROD10C_LOSS', units='gC/m^2/s', &
avgflag='A', long_name='loss from 10-yr wood product pool', &
ptr_col=this%prod10c_loss_col)
ptr_col=this%prod10c_loss_col, default='inactive')

this%dwt_prod100c_gain_col(begc:endc) = spval
call hist_addfld1d (fname='DWT_PROD100C_GAIN', units='gC/m^2/s', &
avgflag='A', long_name='landcover change-driven addition to 100-yr wood product pool', &
ptr_col=this%dwt_prod100c_gain_col)
ptr_col=this%dwt_prod100c_gain_col, default='inactive')

this%prod100c_loss_col(begc:endc) = spval
call hist_addfld1d (fname='PROD100C_LOSS', units='gC/m^2/s', &
avgflag='A', long_name='loss from 100-yr wood product pool', &
ptr_col=this%prod100c_loss_col)
ptr_col=this%prod100c_loss_col, default='inactive')

this%prod1c_loss_col(begc:endc) = spval
call hist_addfld1d (fname='PROD1C_LOSS', units='gC/m^2/s', &
avgflag='A', long_name='loss from 1-yr crop product pool', &
ptr_col=this%prod1c_loss_col)
ptr_col=this%prod1c_loss_col, default='inactive')

this%dwt_frootc_to_litr_met_c_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='DWT_FROOTC_TO_LITR_MET_C', units='gC/m^2/s', type2d='levdcmp', &
Expand Down Expand Up @@ -3037,12 +3045,12 @@ subroutine InitHistory(this, bounds, carbon_type)
this%dwt_closs_col(begc:endc) = spval
call hist_addfld1d (fname='DWT_CLOSS', units='gC/m^2/s', &
avgflag='A', long_name='total carbon loss from land cover conversion', &
ptr_col=this%dwt_closs_col)
ptr_col=this%dwt_closs_col, default='inactive')

this%product_closs_col(begc:endc) = spval
call hist_addfld1d (fname='PRODUCT_CLOSS', units='gC/m^2/s', &
avgflag='A', long_name='total carbon loss from wood product pools', &
ptr_col=this%product_closs_col)
ptr_col=this%product_closs_col, default='inactive')

this%landuseflux_col(begc:endc) = spval
call hist_addfld1d (fname='LAND_USE_FLUX', units='gC/m^2/s', &
Expand Down Expand Up @@ -4966,6 +4974,31 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end do
end do
endif

! debug
do fc = 1,num_soilc
c = filter_soilc(fc)
this%plant_to_litter_cflux(c) = 0._r8
this%plant_to_cwd_cflux(c) = 0._r8
do j = 1, nlevdecomp
this%plant_to_litter_cflux(c) = &
this%plant_to_litter_cflux(c) + &
this%phenology_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + &
this%phenology_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + &
this%phenology_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + &
this%gap_mortality_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + &
this%gap_mortality_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + &
this%gap_mortality_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + &
this%m_c_to_litr_met_fire_col(c,j)* dzsoi_decomp(j) + &
this%m_c_to_litr_cel_fire_col(c,j)* dzsoi_decomp(j) + &
this%m_c_to_litr_lig_fire_col(c,j)* dzsoi_decomp(j)
this%plant_to_cwd_cflux(c) = &
this%plant_to_cwd_cflux(c) + &
this%gap_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j) + &
this%fire_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j)
end do
end do

end associate
end subroutine Summary

Expand Down
73 changes: 58 additions & 15 deletions components/clm/src/biogeochem/CNCarbonStateType.F90
Expand Up @@ -18,6 +18,8 @@ module CNCarbonStateType
use LandunitType , only : lun
use ColumnType , only : col
use PatchType , only : pft
use clm_varctl , only : nu_com

!
! !PUBLIC TYPES:
implicit none
Expand Down Expand Up @@ -99,6 +101,16 @@ module CNCarbonStateType
real(r8), pointer :: endcb_col (:) ! patch carbon mass, end of time step (gC/m**2)
real(r8), pointer :: errcb_patch (:) ! patch carbon balance error for the timestep (gC/m**2)
real(r8), pointer :: errcb_col (:) ! patch carbon balance error for the timestep (gC/m**2)

real(r8), pointer :: totpftc_beg_col(:)
real(r8), pointer :: cwdc_beg_col(:)
real(r8), pointer :: totlitc_beg_col(:)
real(r8), pointer :: totsomc_beg_col(:)

real(r8), pointer :: totpftc_end_col(:)
real(r8), pointer :: cwdc_end_col(:)
real(r8), pointer :: totlitc_end_col(:)
real(r8), pointer :: totsomc_end_col(:)

contains

Expand Down Expand Up @@ -218,6 +230,16 @@ subroutine InitAllocate(this, bounds)
allocate(this%errcb_patch (begp:endp)); this%errcb_patch (:) = nan
allocate(this%errcb_col (begc:endc)); this%errcb_col (:) = nan

allocate(this%totpftc_beg_col(begc:endc)); this%totpftc_beg_col (:) = nan
allocate(this%cwdc_beg_col (begc:endc)); this%cwdc_beg_col (:) = nan
allocate(this%totlitc_beg_col(begc:endc)); this%totlitc_beg_col (:) = nan
allocate(this%totsomc_beg_col(begc:endc)); this%totsomc_beg_col (:) = nan

allocate(this%totpftc_end_col(begc:endc)); this%totpftc_end_col (:) = nan
allocate(this%cwdc_end_col (begc:endc)); this%cwdc_end_col (:) = nan
allocate(this%totlitc_end_col(begc:endc)); this%totlitc_end_col (:) = nan
allocate(this%totsomc_end_col(begc:endc)); this%totsomc_end_col (:) = nan

end subroutine InitAllocate

!------------------------------------------------------------------------
Expand Down Expand Up @@ -263,7 +285,7 @@ subroutine InitHistory(this, bounds, carbon_type)
this%grainc_patch(begp:endp) = spval
call hist_addfld1d (fname='GRAINC', units='gC/m^2', &
avgflag='A', long_name='grain C', &
ptr_patch=this%grainc_patch)
ptr_patch=this%grainc_patch, default='inactive')
end if

this%woodc_patch(begp:endp) = spval
Expand Down Expand Up @@ -379,12 +401,12 @@ subroutine InitHistory(this, bounds, carbon_type)
this%xsmrpool_patch(begp:endp) = spval
call hist_addfld1d (fname='XSMRPOOL', units='gC/m^2', &
avgflag='A', long_name='temporary photosynthate C pool', &
ptr_patch=this%xsmrpool_patch)
ptr_patch=this%xsmrpool_patch, default='inactive')

this%ctrunc_patch(begp:endp) = spval
call hist_addfld1d (fname='PFT_CTRUNC', units='gC/m^2', &
avgflag='A', long_name='patch-level sink for C truncation', &
ptr_patch=this%ctrunc_patch)
ptr_patch=this%ctrunc_patch, default='inactive')

this%dispvegc_patch(begp:endp) = spval
call hist_addfld1d (fname='DISPVEGC', units='gC/m^2', &
Expand Down Expand Up @@ -746,12 +768,12 @@ subroutine InitHistory(this, bounds, carbon_type)
this%ctrunc_col(begc:endc) = spval
call hist_addfld1d (fname='COL_CTRUNC', units='gC/m^2', &
avgflag='A', long_name='column-level sink for C truncation', &
ptr_col=this%ctrunc_col)
ptr_col=this%ctrunc_col, default='inactive')

this%seedc_col(begc:endc) = spval
call hist_addfld1d (fname='SEEDC', units='gC/m^2', &
avgflag='A', long_name='pool for seeding new Patches', &
ptr_col=this%seedc_col)
ptr_col=this%seedc_col, default='inactive')

this%totlitc_col(begc:endc) = spval
call hist_addfld1d (fname='LITTERC', units='gC/m^2', &
Expand Down Expand Up @@ -782,27 +804,27 @@ subroutine InitHistory(this, bounds, carbon_type)
this%prod10c_col(begc:endc) = spval
call hist_addfld1d (fname='PROD10C', units='gC/m^2', &
avgflag='A', long_name='10-yr wood product C', &
ptr_col=this%prod10c_col)
ptr_col=this%prod10c_col, default='inactive')

this%prod100c_col(begc:endc) = spval
call hist_addfld1d (fname='PROD100C', units='gC/m^2', &
avgflag='A', long_name='100-yr wood product C', &
ptr_col=this%prod100c_col)
ptr_col=this%prod100c_col, default='inactive')

this%prod1c_col(begc:endc) = spval
call hist_addfld1d (fname='PROD1C', units='gC/m^2', &
avgflag='A', long_name='1-yr crop product C', &
ptr_col=this%prod1c_col)
ptr_col=this%prod1c_col, default='inactive')

this%totprodc_col(begc:endc) = spval
call hist_addfld1d (fname='TOTPRODC', units='gC/m^2', &
avgflag='A', long_name='total wood product C', &
ptr_col=this%totprodc_col)
ptr_col=this%totprodc_col, default='inactive')

this%fuelc_col(begc:endc) = spval
call hist_addfld1d (fname='FUELC', units='gC/m^2', &
avgflag='A', long_name='fuel load', &
ptr_col=this%fuelc_col)
ptr_col=this%fuelc_col, default='inactive')

end if

Expand Down Expand Up @@ -1041,7 +1063,7 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars)
!-----------------------------------------------
! initialize patch-level carbon state variables
!-----------------------------------------------

do p = bounds%begp,bounds%endp

this%leafcmax_patch(p) = 0._r8
Expand Down Expand Up @@ -1080,8 +1102,30 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars)
this%deadstemc_patch(p) = 0._r8
end if
this%deadstemc_storage_patch(p) = 0._r8
this%deadstemc_xfer_patch(p) = 0._r8

this%deadstemc_xfer_patch(p) = 0._r8

if (nu_com .ne. 'RD') then
! eca competition calculate root NP uptake as a function of fine root biomass
! better to initialize frootc(p) with a non-zero value
if (pft%itype(p) == noveg) then
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
else
if (ecophyscon%evergreen(pft%itype(p)) == 1._r8) then
this%leafc_patch(p) = 20._r8 * ratio
this%frootc_patch(p) = 20._r8 * ratio
this%frootc_storage_patch(p) = 0._r8
else if (pft%itype(p) >= npcropmin) then ! prognostic crop types
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
else
this%leafc_storage_patch(p) = 20._r8 * ratio
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 20._r8 * ratio
end if
end if
end if

this%livecrootc_patch(p) = 0._r8
this%livecrootc_storage_patch(p) = 0._r8
this%livecrootc_xfer_patch(p) = 0._r8
Expand Down Expand Up @@ -1139,9 +1183,8 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars)
this%grainc_storage_patch(p) + &
this%grainc_xfer_patch(p)
end if

endif

end do

! initialize column-level variables
Expand Down

0 comments on commit ba5010f

Please sign in to comment.