From 3a1247c55b1c5afe207393fcc682d42cabe9a30b Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 6 Sep 2024 18:38:02 +0200 Subject: [PATCH 01/17] Clean code, add conditions for exit, fix bugs --- .../testmods_dirs/clm/mimicsplus/user_nl_clm | 3 +- src/biogeochem/CNFUNMIMICSplusMod.F90 | 408 +++++++++--------- .../SoilBiogeochemCompetitionMod.F90 | 12 +- ...ilBiogeochemDecompCascadeMIMICSplusMod.F90 | 262 +++++------ 4 files changed, 352 insertions(+), 333 deletions(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm index ff26188d87..554237debe 100644 --- a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm @@ -49,4 +49,5 @@ hist_dov2xy = .true., .true. soil_decomp_method = 'MIMICSplusAas2023' hist_fincl1 += 'TOTMYCC', 'SOILC_vr', 'TOTMICC', 'TOTMYCC', 'TOTLITC', 'TOTSOMC', 'TOTLITC_1m', 'TOTSOMC_1m', 'DYN_COL_SOIL_ADJUSTMENTS_C', 'TOTCOLC', 'TOTECOSYSC', 'LIT_MET_C_vr', 'LIT_STR_C_vr', 'SOM_AVL_C_vr', - 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' \ No newline at end of file + 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' + diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 2fa290e75c..4532e0a69c 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -12,6 +12,7 @@ module CNFUNMIMICSplusMod use shr_log_mod , only : errMsg => shr_log_errMsg use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) use clm_varctl , only : iulog + use decompMod , only : subgrid_level_gridcell, subgrid_level_column, subgrid_level_patch use clm_varpar , only : i_phys_som, i_chem_som, i_avl_som, i_ecm_myc, i_am_myc use PatchType , only : patch use ColumnType , only : col @@ -37,7 +38,7 @@ module CNFUNMIMICSplusMod use CanopyStateType , only : canopystate_type use perf_mod , only : t_startf, t_stopf use clm_varpar , only : nlevdecomp - use clm_varcon , only : secspday + use clm_varcon , only : secspday, spval ! ! !PUBLIC TYPES: implicit none @@ -50,7 +51,6 @@ module CNFUNMIMICSplusMod public:: CNFUNMIMICSplusInit ! FUNMIMICSplus calculation initialization public:: CNFUNMIMICSplus ! FUNMIMICSplus calculation itself public:: updateCNFUNMIMICSplus - private :: fun_cost_active private :: fun_cost_nonmyc private :: fun_cost_fix private :: fun_retranslocation @@ -63,7 +63,7 @@ module CNFUNMIMICSplusMod integer, parameter :: ipfix = 5 ! Process number for fixing. orginal version in FUN: [icost...] integer, parameter :: ipret = 6 ! Process number for retranslocation. - real(r8), parameter :: big_cost = 1000000000._r8! An arbitrarily large cost + real(r8), parameter :: big_cost = 5.e+7_r8! An arbitrarily large cost ! array index when plant is fixing integer, parameter :: plants_are_fixing = 1 @@ -84,13 +84,10 @@ module CNFUNMIMICSplusMod real(r8), pointer :: rootc_dens(:,:) ! the root carbon density (gC/m2) real(r8), pointer :: rootC(:) ! root biomass (gC/m2) real(r8), pointer :: n_uptake_myc_frac(:,:) ! the arrary for the ECM and AM ratio (-) orginal version in FUN: [permyc] - real(r8), pointer :: kc_active(:,:) ! the kc_active parameter (gC/m2) - real(r8), pointer :: kn_active(:,:) ! the kn_active parameter (gC/m2) real(r8), pointer :: plant_ndemand_pool(:) ! The N demand pool (gN/m2) real(r8), pointer :: plant_ndemand_pool_step(:,:) ! the N demand pool (gN/m2) real(r8), pointer :: litterfall_n_step(:,:) ! N loss based on the leafc to litter (gN/m2) real(r8), pointer :: litterfall_c_step(:,:) ! N loss based on the leafc to litter (gN/m2) - real(r8), pointer :: tc_soisno(:,:) ! Soil temperature (degrees Celsius) real(r8), pointer :: npp_remaining(:,:) ! A temporary variable for npp_remaining(gC/m2) real(r8), pointer :: n_retrans_acc(:,:) ! N acquired by retranslocation (gN/m2) real(r8), pointer :: free_nretrans_acc(:,:) ! N acquired by retranslocation (gN/m2) @@ -115,15 +112,6 @@ module CNFUNMIMICSplusMod real(r8), pointer :: n_nonmyc_vr(:,:) ! Layer non-myc N uptake (gN/m2) ! Uptake fluxes for COST_METHOD=2 - - ! hypothetical fluxes on N in each layer - real(r8), pointer :: n_exch_fixation(:) ! N aquired from one unit of C for fixation (unitless) - real(r8), pointer :: n_exch_retrans(:) ! N aquired from one unit of C for retrans (unitless) - real(r8), pointer :: n_exch_active(:) ! N aquired from one unit of C for act no3 (unitless) - real(r8), pointer :: n_exch_nonmyc(:) ! N aquired from one unit of C for nonmyc no3 (unitless) - - real(r8), pointer :: free_Nretrans(:) ! the total amount of NO3 and NH4 (gN/m3/s) - ! Update Fluxes real(r8), pointer :: c_am_resp_vr_col(:,:) ! carbon respiration flux for AM mycorrhiza real(r8), pointer :: c_ecm_resp_vr_col(:,:) ! carbon respiration flux for ECM mycorrhiza @@ -200,104 +188,88 @@ subroutine InitAllocate (this, bounds) begc = bounds%begc; endc = bounds%endc begp = bounds%begp; endp = bounds%endp - allocate(this%rootc_dens(bounds%begp:bounds%endp,1:nlevdecomp)); this%rootc_dens(:,:)= nan - - allocate(this%rootC(bounds%begp:bounds%endp)); this%rootC(:)= nan + allocate(this%rootc_dens(bounds%begp:bounds%endp,1:nlevdecomp)); this%rootc_dens(:,:)= spval - allocate(this%n_uptake_myc_frac(bounds%begp:bounds%endp,1:nmyc)); this%n_uptake_myc_frac(:,:) = nan + allocate(this%rootC(bounds%begp:bounds%endp)); this%rootC(:)= spval - allocate(this%kc_active(bounds%begp:bounds%endp,1:nmyc)); this%kc_active(:,:) = nan + allocate(this%n_uptake_myc_frac(bounds%begp:bounds%endp,1:nmyc)); this%n_uptake_myc_frac(:,:) = spval - allocate(this%kn_active(bounds%begp:bounds%endp,1:nmyc)); this%kn_active(:,:) = nan + allocate(this%plant_ndemand_pool(bounds%begp:bounds%endp)); this%plant_ndemand_pool(:) = spval - allocate(this%plant_ndemand_pool(bounds%begp:bounds%endp)); this%plant_ndemand_pool(:) = nan - - allocate(this%plant_ndemand_pool_step(bounds%begp:bounds%endp,1:nmyc)); this%plant_ndemand_pool_step(:,:) = nan - - allocate(this%litterfall_n_step(bounds%begp:bounds%endp,1:nmyc)); this%litterfall_n_step(:,:) = nan - - allocate(this%litterfall_c_step(bounds%begp:bounds%endp,1:nmyc)); this%litterfall_c_step(:,:) = nan + allocate(this%plant_ndemand_pool_step(bounds%begp:bounds%endp,1:nmyc)); this%plant_ndemand_pool_step(:,:) = spval - allocate(this%tc_soisno(bounds%begc:bounds%endc,1:nlevdecomp)); this%tc_soisno(:,:) = nan + allocate(this%litterfall_n_step(bounds%begp:bounds%endp,1:nmyc)); this%litterfall_n_step(:,:) = spval - allocate(this%npp_remaining(bounds%begp:bounds%endp,1:nmyc)); this%npp_remaining(:,:) = nan + allocate(this%litterfall_c_step(bounds%begp:bounds%endp,1:nmyc)); this%litterfall_c_step(:,:) = spval - allocate(this%n_retrans_acc(bounds%begp:bounds%endp,1:nmyc)); this%n_retrans_acc(:,:) = nan + allocate(this%npp_remaining(bounds%begp:bounds%endp,1:nmyc)); this%npp_remaining(:,:) = spval - allocate(this%free_nretrans_acc(bounds%begp:bounds%endp,1:nmyc)); this%free_nretrans_acc(:,:) = nan + allocate(this%n_retrans_acc(bounds%begp:bounds%endp,1:nmyc)); this%n_retrans_acc(:,:) = spval + + allocate(this%free_nretrans_acc(bounds%begp:bounds%endp,1:nmyc)); this%free_nretrans_acc(:,:) = spval - allocate(this%npp_retrans_acc(bounds%begp:bounds%endp,1:nmyc)); this%npp_retrans_acc(:,:) = nan + allocate(this%npp_retrans_acc(bounds%begp:bounds%endp,1:nmyc)); this%npp_retrans_acc(:,:) = spval - allocate(this%nt_uptake(bounds%begp:bounds%endp,1:nmyc)); this%nt_uptake(:,:) = nan + allocate(this%nt_uptake(bounds%begp:bounds%endp,1:nmyc)); this%nt_uptake(:,:) = spval - allocate(this%npp_uptake(bounds%begp:bounds%endp,1:nmyc)); this%npp_uptake(:,:) = nan + allocate(this%npp_uptake(bounds%begp:bounds%endp,1:nmyc)); this%npp_uptake(:,:) = spval - allocate(this%costs_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%costs_paths(:,:,:) = nan + allocate(this%costs_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%costs_paths(:,:,:) = spval - allocate(this%sminn_layer(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminn_layer(:,:) = nan + allocate(this%sminn_layer(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminn_layer(:,:) = spval - allocate(this%sminn_layer_step(bounds%begp:bounds%endp,1:nlevdecomp,1:nmyc)); this%sminn_layer_step(:,:,:) = nan + allocate(this%sminn_layer_step(bounds%begp:bounds%endp,1:nlevdecomp,1:nmyc)); this%sminn_layer_step(:,:,:) = spval - allocate(this%n_active_vr(bounds%begp:bounds%endp, 1:nlevdecomp)); this%n_active_vr(:,:) = nan + allocate(this%n_active_vr(bounds%begp:bounds%endp, 1:nlevdecomp)); this%n_active_vr(:,:) = spval - allocate(this%n_nonmyc_vr(bounds%begp:bounds%endp, 1:nlevdecomp)); this%n_nonmyc_vr(:,:) = nan + allocate(this%n_nonmyc_vr(bounds%begp:bounds%endp, 1:nlevdecomp)); this%n_nonmyc_vr(:,:) = spval - allocate(this%sminfrc(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminfrc(:,:) = nan + allocate(this%sminfrc(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminfrc(:,:) = spval - allocate(this%sminn_to_plant(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminn_to_plant(:,:) = nan + allocate(this%sminn_to_plant(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminn_to_plant(:,:) = spval ! Uptake fluxes for COST_METHOD=2 ! actual npp to each layer for each uptake process - allocate(this%npp_to_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_to_paths(:,:,:) = nan - - allocate(this%npp_frac_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_frac_paths(:,:,:) = nan - - allocate(this%n_from_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%n_from_paths(:,:,:) = nan + allocate(this%npp_to_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_to_paths(:,:,:) = spval - allocate(this%n_paths_acc(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%n_paths_acc(:,:,:) = nan + allocate(this%npp_frac_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_frac_paths(:,:,:) = spval - allocate(this%npp_paths_acc(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_paths_acc(:,:,:) = nan + allocate(this%n_from_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%n_from_paths(:,:,:) = spval - ! hypothetical fluxes on N in each layer - allocate(this%n_exch_fixation(1:nlevdecomp)); this%n_exch_fixation(:) = nan + allocate(this%n_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6)); this%n_paths_acc(:,:,:) = spval - allocate(this%n_exch_retrans(1:nlevdecomp)); this%n_exch_retrans(:) = nan + allocate(this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6)); this%npp_paths_acc(:,:,:) = spval - allocate(this%n_exch_active(1:nlevdecomp)); this%n_exch_active(:) = nan - - allocate(this%n_exch_nonmyc(1:nlevdecomp)); this%n_exch_nonmyc(:) = nan - - allocate(this% free_Nretrans(bounds%begp:bounds%endp)); this%free_Nretrans(:) = nan ! update fluxes - allocate(this%c_am_resp_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_am_resp_vr_col(:,:) = nan + allocate(this%c_am_resp_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_am_resp_vr_col(:,:) = spval - allocate(this%c_ecm_resp_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_resp_vr_col(:,:) = nan + allocate(this%c_ecm_resp_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_resp_vr_col(:,:) = spval - allocate(this%c_am_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_am_growth_vr_col(:,:) = nan + allocate(this%c_am_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_am_growth_vr_col(:,:) = spval - allocate(this%c_ecm_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_growth_vr_col(:,:) = nan + allocate(this%c_ecm_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_growth_vr_col(:,:) = spval - allocate(this%n_am_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_am_growth_vr_col(:,:) = nan + allocate(this%n_am_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_am_growth_vr_col(:,:) = spval - allocate(this%n_ecm_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_ecm_growth_vr_col(:,:) = nan + allocate(this%n_ecm_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_ecm_growth_vr_col(:,:) = spval - allocate(this%c_ecm_enz_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_enz_vr_col(:,:) = nan + allocate(this%c_ecm_enz_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_enz_vr_col(:,:) = spval - allocate(this%n_somc2ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_somc2ecm_vr_col(:,:) = nan - allocate(this%n_somp2ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_somp2ecm_vr_col(:,:) = nan - allocate(this%c_somc2soma_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_somc2soma_vr_col(:,:) = nan - allocate(this%c_somp2soma_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_somp2soma_vr_col(:,:) = nan - allocate(this%sminno3_to_ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_to_ecm_vr_col(:,:) = nan - allocate(this%sminno3_to_am_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_to_am_vr_col(:,:) = nan - allocate(this%sminnh4_to_ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_to_ecm_vr_col(:,:) = nan - allocate(this%sminnh4_to_am_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_to_am_vr_col(:,:) = nan + allocate(this%n_somc2ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_somc2ecm_vr_col(:,:) = spval + allocate(this%n_somp2ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_somp2ecm_vr_col(:,:) = spval + allocate(this%c_somc2soma_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_somc2soma_vr_col(:,:) = spval + allocate(this%c_somp2soma_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_somp2soma_vr_col(:,:) = spval + allocate(this%sminno3_to_ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_to_ecm_vr_col(:,:) = spval + allocate(this%sminno3_to_am_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_to_am_vr_col(:,:) = spval + allocate(this%sminnh4_to_ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_to_ecm_vr_col(:,:) = spval + allocate(this%sminnh4_to_am_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_to_am_vr_col(:,:) = spval - allocate(this%sminno3_nonmyc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_nonmyc_to_plant_col(:,:) = nan - allocate(this%sminnh4_nonmyc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_nonmyc_to_plant_col(:,:) = nan + allocate(this%sminno3_nonmyc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_nonmyc_to_plant_col(:,:) = spval + allocate(this%sminnh4_nonmyc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_nonmyc_to_plant_col(:,:) = spval - allocate(this%no3_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%no3_myc_to_plant_col(:,:) = nan - allocate(this%nh4_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%nh4_myc_to_plant_col(:,:) = nan + allocate(this%no3_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%no3_myc_to_plant_col(:,:) = spval + allocate(this%nh4_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%nh4_myc_to_plant_col(:,:) = spval end subroutine InitAllocate @@ -325,13 +297,10 @@ subroutine SetZeros (this, bounds) this%rootc_dens(:,:) = 0._r8 this%rootC(:) = 0._r8 this%n_uptake_myc_frac(:,:) = 0._r8 - this%kc_active(:,:) = 0._r8 - this%kn_active(:,:) = 0._r8 this%plant_ndemand_pool(:) = 0._r8 this%plant_ndemand_pool_step(:,:) = 0._r8 this%litterfall_n_step(:,:) = 0._r8 this%litterfall_c_step(:,:) = 0._r8 - this%tc_soisno(:,:) = 0._r8 this%npp_remaining(:,:) = 0._r8 this%costs_paths(:,:,:) = big_cost this%npp_to_paths(:,:,:) = 0._r8 @@ -350,11 +319,7 @@ subroutine SetZeros (this, bounds) this%n_nonmyc_vr(:,:) = 0._r8 this%sminfrc(:,:) = 0._r8 this%sminn_to_plant(:,:) = 0._r8 - this%n_exch_fixation(:) = 0._r8 - this%n_exch_retrans(:) = 0._r8 - this%n_exch_active(:) = 0._r8 - this%n_exch_nonmyc(:) = 0._r8 - this%free_Nretrans(:) = 0._r8 + this%c_am_resp_vr_col(:,:) = 0._r8 this%c_ecm_resp_vr_col(:,:) = 0._r8 this%c_am_growth_vr_col(:,:) = 0._r8 @@ -565,7 +530,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s real(r8) :: total_c_spent_retrans real(r8) :: total_c_accounted_retrans - real(r8) :: frac_alloc_ecm(bounds%begp:bounds%endp,1:nmyc) ! fraction from ROI allocated to EcM + real(r8) :: frac_alloc_ecm ! fraction from ROI allocated to EcM real(r8) :: c_am_resp_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp) ! carbon respiration flux for AM mycorrhiza real(r8) :: c_ecm_resp_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp) ! carbon respiration flux for ECM mycorrhiza @@ -598,10 +563,6 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s b_fix => pftcon%b_fix , & ! Input: A BNF parameter c_fix => pftcon%c_fix , & ! Input: A BNF parameter s_fix => pftcon%s_fix , & ! Input: A BNF parameter - akc_active => pftcon%akc_active , & ! Input: A mycorrhizal uptake parameter - akn_active => pftcon%akn_active , & ! Input: A mycorrhizal uptake parameter - ekc_active => pftcon%ekc_active , & ! Input: A mycorrhizal uptake parameter - ekn_active => pftcon%ekn_active , & ! Input: A mycorrhizal upatke parameter kc_nonmyc => pftcon%kc_nonmyc , & ! Input: A non-mycorrhizal uptake parameter kn_nonmyc => pftcon%kn_nonmyc , & ! Input: A non-mycorrhizal uptake parameter perecm => pftcon%perecm , & ! Input: The fraction of ECM associated PFT @@ -670,7 +631,6 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s Nnonmyc_nh4 => cnveg_nitrogenflux_inst%Nnonmyc_nh4_patch , & ! Output: [real(r8) (:) ] Non-mycorrhizal N uptake (gN/m2/s) Nam_nh4 => cnveg_nitrogenflux_inst%Nam_nh4_patch , & ! Output: [real(r8) (:) ] AM uptake (gN/m2/s) Necm_nh4 => cnveg_nitrogenflux_inst%Necm_nh4_patch , & ! Output: [real(r8) (:) ] ECM uptake (gN/m2/s) - Npassive => cnveg_nitrogenflux_inst%Npassive_patch , & ! Output: [real(r8) (:) ] Passive N uptake (gN/m2/s) Nfix => cnveg_nitrogenflux_inst%Nfix_patch , & ! Output: [real(r8) (:) ] Symbiotic BNF (gN/m2/s) cost_nfix => cnveg_nitrogenflux_inst%cost_Nfix_patch , & ! Output: [real(r8) (:) ] Cost of fixation gC:gN cost_nactive => cnveg_nitrogenflux_inst%cost_Nactive_patch , & ! Output: [real(r8) (:) ] Cost of active uptake gC:gN @@ -704,17 +664,10 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s n_paths_acc => cnfunmimicsplus_inst%n_paths_acc , & npp_paths_acc => cnfunmimicsplus_inst%npp_paths_acc , & dn => cnfunmimicsplus_inst%dn , & - free_Nretrans => cnfunmimicsplus_inst%free_Nretrans , & free_nretrans_acc => cnfunmimicsplus_inst%free_nretrans_acc , & - kc_active => cnfunmimicsplus_inst%kc_active , & - kn_active => cnfunmimicsplus_inst%kn_active , & litterfall_c_step => cnfunmimicsplus_inst%litterfall_c_step , & litterfall_n_step => cnfunmimicsplus_inst%litterfall_n_step , & n_active_vr => cnfunmimicsplus_inst%n_active_vr , & - n_exch_active => cnfunmimicsplus_inst%n_exch_active , & - n_exch_fixation => cnfunmimicsplus_inst%n_exch_fixation , & - n_exch_nonmyc => cnfunmimicsplus_inst%n_exch_nonmyc , & - n_exch_retrans => cnfunmimicsplus_inst%n_exch_retrans , & n_nonmyc_vr => cnfunmimicsplus_inst%n_nonmyc_vr , & n_retrans_acc => cnfunmimicsplus_inst%n_retrans_acc , & n_uptake_myc_frac => cnfunmimicsplus_inst%n_uptake_myc_frac , & @@ -735,7 +688,6 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s ! C and N soil pools: decomp_cpools_vr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col , & decomp_npools_vr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col , & - tc_soisno => cnfunmimicsplus_inst%tc_soisno , & c_am_resp_vr_col => cnfunmimicsplus_inst%c_am_resp_vr_col , & c_ecm_resp_vr_col => cnfunmimicsplus_inst%c_ecm_resp_vr_col , & @@ -807,16 +759,18 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s (smin_no3_to_plant_vr(c,j) + smin_nh4_to_plant_vr(c,j)) * dt, am_step , dzsoi_decomp(j),- big_cost, roi_am) frac_alloc_ecm=(roi_ecm)/(roi_ecm + roi_am) ! if (crootfr(p,j)>0.0_r8) then - n_uptake_myc_frac(p,ecm_step) = n_uptake_myc_frac(p,ecm_step) + frac_alloc_ecm(p,imyc) * crootfr(p,j) + n_uptake_myc_frac(p,ecm_step) = n_uptake_myc_frac(p,ecm_step) + frac_alloc_ecm * crootfr(p,j) endif end do n_uptake_myc_frac(p,am_step) = 1.0_r8 - n_uptake_myc_frac(p,ecm_step) if(leafc(p)>0.0_r8)then ! N available in leaf which fell off in this timestep. Same fraction loss as C. - litterfall_c_step(p,imyc) = dt * n_uptake_myc_frac(p,ecm_step) * leafc_to_litter_fun(p) - litterfall_n_step(p,imyc) = dt * n_uptake_myc_frac(p,ecm_step) * leafn(p) * leafc_to_litter_fun(p)/leafc(p) - litterfall_c_step(p,imyc) = dt * n_uptake_myc_frac(p,am_step) * leafc_to_litter_fun(p) - litterfall_n_step(p,imyc) = dt * n_uptake_myc_frac(p,am_step) * leafn(p) * leafc_to_litter_fun(p)/leafc(p) + do imyc = 1,nmyc + litterfall_c_step(p,imyc) = dt * n_uptake_myc_frac(p,ecm_step) * leafc_to_litter_fun(p) + litterfall_n_step(p,imyc) = dt * n_uptake_myc_frac(p,ecm_step) * leafn(p) * leafc_to_litter_fun(p)/leafc(p) + litterfall_c_step(p,imyc) = dt * n_uptake_myc_frac(p,am_step) * leafc_to_litter_fun(p) + litterfall_n_step(p,imyc) = dt * n_uptake_myc_frac(p,am_step) * leafn(p) * leafc_to_litter_fun(p)/leafc(p) + end do endif end do @@ -899,14 +853,13 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s ! COST FIXATION PATHWAY ! checks which photosyntetic pathway plant has (C3 / C4) and if they can do nitrogen fixation do j = 1, nlevdecomp - tc_soisno(c,j) = t_soisno(c,j) - tfrz ! Soil temperature if(pftcon%c3psn(patch%itype(p)).eq.1)then fixer=1 else fixer=0 endif costs_paths(p,j,ipfix) = fun_cost_fix(fixer,a_fix(ivt(p)),b_fix(ivt(p))& - ,c_fix(ivt(p)) ,big_cost,crootfr(p,j),s_fix(ivt(p)),tc_soisno(c,j)) + ,c_fix(ivt(p)) ,big_cost,crootfr(p,j),s_fix(ivt(p)),t_soisno(c,j)) end do ! ACTIVE UPTAKE @@ -945,7 +898,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end do ! Remove C required to pair with N from passive uptake from the available pool. - npp_remaining(p,imyc) = npp_remaining(p,imyc) * plantCN(p) + npp_remaining(p,imyc) = npp_remaining(p,imyc) total_N_conductance = 0.0_r8 fix_loop: do FIX =plants_are_fixing, plants_not_fixing !loop around percentages of fixers and nonfixers, with differnt costs. @@ -977,12 +930,18 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end do do j = 1, nlevdecomp + + ! Calculate npp allocation to pathways proportional to their exchange rate (N/C) - npp_frac_paths(p,j,ipanh4) = (1._r8/costs_paths(p,j,ipanh4)) / total_N_conductance - npp_frac_paths(p,j,ipnmnh4) = (1._r8/costs_paths(p,j,ipnmnh4)) / total_N_conductance - npp_frac_paths(p,j,ipano3) = (1._r8/costs_paths(p,j,ipano3)) / total_N_conductance - npp_frac_paths(p,j,ipnmno3) = (1._r8/costs_paths(p,j,ipnmno3)) / total_N_conductance - + rootc_dens_step = rootc_dens(p,j) * n_uptake_myc_frac(p,imyc) + if (rootc_dens_step > 0._r8) then + npp_frac_paths(p,j,ipanh4) = (1._r8/costs_paths(p,j,ipanh4)) / total_N_conductance + npp_frac_paths(p,j,ipnmnh4) = (1._r8/costs_paths(p,j,ipnmnh4)) / total_N_conductance + npp_frac_paths(p,j,ipano3) = (1._r8/costs_paths(p,j,ipano3)) / total_N_conductance + npp_frac_paths(p,j,ipnmno3) = (1._r8/costs_paths(p,j,ipnmno3)) / total_N_conductance + else + npp_frac_paths(p,j,ipano3:ipnmnh4) = 0.0_r8 + endif if(FIX==plants_are_fixing)then npp_frac_paths(p,j,ipfix) = (1.0_r8 * 1._r8/costs_paths(p,j,ipfix)) / total_N_conductance else @@ -992,15 +951,13 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s sum_n_acquired = sum_n_acquired + npp_frac_paths(p,j,ipanh4)/costs_paths(p,j,ipanh4) + & npp_frac_paths(p,j,ipano3)/costs_paths(p,j,ipano3) + & npp_frac_paths(p,j,ipnmnh4)/costs_paths(p,j,ipnmnh4) + npp_frac_paths(p,j,ipnmno3)/costs_paths(p,j,ipnmno3) - if(FIX==plants_are_fixing)then sum_n_acquired= sum_n_acquired + npp_frac_paths(p,j,ipfix)/costs_paths(p,j,ipfix) end if end do - total_N_resistance = 1.0_r8/sum_n_acquired !gC/gN - + free_n_retrans = 0.0_r8 ! Calculate appropriate degree of retranslocation if(leafc(p).gt.0.0_r8.and.litterfall_n_step(p,imyc)* fixerfrac>0.0_r8.and.ivt(p) 0.0_r8) then + if (imyc == ecm_step) then + call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_ecm_myc),decomp_npools_vr(c,j,i_ecm_myc), & + decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & + decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & + sminn_layer_step(p,j,imyc), sminfrc(c,j), ecm_step, dzsoi_decomp(j), & + npp_to_paths(p,j,ipano3), npp_to_paths(p,j,ipanh4), & + n_from_paths(p,j,ipnmno3), n_from_paths(p,j,ipnmnh4),n_from_paths(p,j,ipano3), n_from_paths(p,j,ipanh4), & + sminno3_to_ecm_vr_patch(p,j), sminnh4_to_ecm_vr_patch(p,j), & + c_ecm_resp_vr_patch(p,j), c_ecm_growth_vr_patch(p,j), n_ecm_growth_vr_patch(p,j), c_ecm_enz_vr_patch(p,j), & + c_somp2soma_vr_patch(p,j), c_somc2soma_vr_patch(p,j), n_somp2ecm_vr_patch(p,j), n_somc2ecm_vr_patch(p,j)) + ! update npp_to_nonmyc with cost + else + call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_am_myc),decomp_npools_vr(c,j,i_am_myc), & + decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & + decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & + sminn_layer_step(p,j,imyc), sminfrc(c,j), ecm_step, dzsoi_decomp(j), & + npp_to_paths(p,j,ipano3), npp_to_paths(p,j,ipanh4), & + n_from_paths(p,j,ipnmno3), n_from_paths(p,j,ipnmnh4),n_from_paths(p,j,ipano3), n_from_paths(p,j,ipanh4), & + sminno3_to_am_vr_patch(p,j), sminnh4_to_am_vr_patch(p,j), & + c_am_resp_vr_patch(p,j), c_am_growth_vr_patch(p,j), n_am_growth_vr_patch(p,j)) + endif + npp_to_paths(p,j,ipnmno3) = n_from_paths(p,j,ipnmno3) * costs_paths(p,j,ipnmno3) + npp_to_paths(p,j,ipnmnh4) = n_from_paths(p,j,ipnmnh4) * costs_paths(p,j,ipnmnh4) + + ! switch units to gN/m3/s for use in other routines + sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) + sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) + sminnh4_to_am_vr_patch(p,j) = sminnh4_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) + sminnh4_to_ecm_vr_patch(p,j) = sminnh4_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) else - call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_am_myc),decomp_npools_vr(c,j,i_am_myc), & - decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & - decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & - (sminn_layer_step(p,j,imyc) * fixerfrac), sminfrc(c,j), ecm_step, dzsoi_decomp(j), & - npp_to_paths(p,j,ipano3), npp_to_paths(p,j,ipanh4), & - n_from_paths(p,j,ipnmno3), n_from_paths(p,j,ipnmnh4),n_from_paths(p,j,ipano3), n_from_paths(p,j,ipanh4), & - sminno3_to_am_vr_patch(p,j), sminnh4_to_am_vr_patch(p,j), & - c_am_resp_vr_patch(p,j), c_am_growth_vr_patch(p,j), n_am_growth_vr_patch(p,j)) - endif - npp_to_paths(p,j,ipnmno3) = n_from_paths(p,j,ipnmno3) * costs_paths(p,j,ipnmno3) - npp_to_paths(p,j,ipnmnh4) = n_from_paths(p,j,ipnmnh4) * costs_paths(p,j,ipnmnh4) + do ipath = ipano3,ipnmnh4 + npp_to_paths(p,imyc,ipath) = 0.0_r8 + n_from_paths(p,imyc,ipath) = 0.0_r8 + end do + ! switch units to gN/m3/s for use in other routines + sminno3_to_am_vr_patch(p,j) = 0.0_r8 + sminno3_to_ecm_vr_patch(p,j) = 0.0_r8 + sminnh4_to_am_vr_patch(p,j) = 0.0_r8 + sminnh4_to_ecm_vr_patch(p,j) = 0.0_r8 - ! switch units to gN/m3/s for use in other routines - sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - sminnh4_to_am_vr_patch(p,j) = sminnh4_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - sminnh4_to_ecm_vr_patch(p,j) = sminnh4_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - - N_acquired = sum(n_from_paths(p,j,ipano3:ipnmnh4)) ! How much N did we end up with - - C_spent = sum(npp_to_paths(p,j,ipano3:ipnmnh4)) ! How much did it actually cost? + endif + N_acquired = sum(n_from_paths(p,j,ipano3:ipnmnh4)) ! How much N did we end up with + + C_spent = sum(npp_to_paths(p,j,ipano3:ipnmnh4)) ! How much did it actually cost? @@ -1153,7 +1124,6 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s do ipath = ipano3,ipnmnh4 n_paths_acc(p,imyc,ipath) = n_paths_acc(p,imyc,ipath) + n_from_paths(p,j,ipath) end do - !-------------------- C flux accumulation------------! do ipath = ipano3,ipnmnh4 npp_paths_acc(p,imyc,ipath) = npp_paths_acc(p,imyc,ipath) + npp_to_paths(p,j,ipath) @@ -1177,7 +1147,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s n_nonmyc_vr(p,j) = n_nonmyc_vr(p,j) + sum(n_from_paths(p,j,ipnmno3:ipnmnh4)) n_active_no3_vr(p,j) = n_active_no3_vr(p,j) + n_from_paths(p,j,ipano3) n_active_nh4_vr(p,j) = n_active_nh4_vr(p,j) + n_from_paths(p,j,ipanh4) - n_nonmyc_n03_vr(p,j) = n_nonmyc_no3_vr(p,j) + n_from_paths(p,j,ipnmno3) + n_nonmyc_no3_vr(p,j) = n_nonmyc_no3_vr(p,j) + n_from_paths(p,j,ipnmno3) n_nonmyc_nh4_vr(p,j) = n_nonmyc_nh4_vr(p,j) + n_from_paths(p,j,ipnmnh4) end do end if !unmet demand` @@ -1188,10 +1158,10 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end do stp ! Turn step level quantities back into fluxes per second. Nfix(p) = sum(n_paths_acc(p,1:nmyc,ipfix)) / dt - retransn_to_npool(p) = sum(n_paths_acc(p,1:nmyc,ipret)) / dt ! DELETE? + retransn_to_npool(p) = sum(n_retrans_acc(p,1:nmyc)) / dt ! Without matrix solution if(.not. use_matrixcn)then - free_retransn_to_npool(p) = free_nretrans(p) / dt + free_retransn_to_npool(p) = sum(free_nretrans_acc(p,1:nmyc)) / dt ! With matrix solution (when it comes in) end if ! this is the N that comes off leaves. @@ -1205,8 +1175,21 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s ! we have these variable instead of smin*_to_plant_fun_vr, just need give them proper units n_active_no3_vr(p,j) = n_active_no3_vr(p,j)/(dzsoi_decomp(j)*dt) n_active_nh4_vr(p,j) = n_active_nh4_vr(p,j)/(dzsoi_decomp(j)*dt) - n_nonmyc_n03_vr(p,j) = n_nonmyc_no3_vr(p,j)/(dzsoi_decomp(j)*dt) + n_nonmyc_no3_vr(p,j) = n_nonmyc_no3_vr(p,j)/(dzsoi_decomp(j)*dt) n_nonmyc_nh4_vr(p,j) = n_nonmyc_nh4_vr(p,j)/(dzsoi_decomp(j)*dt) + if (sminn_to_plant_fun_vr(p,j) < 0.0_r8) then + write(iulog,*) 'ERROR: sminn_to_plant_fun_vr=', sminn_to_plant_fun_vr(p,j) + write(iulog,*) 'ERROR: free_retransn_to_npool=', free_retransn_to_npool(p) + write(iulog,*) 'n_uptake_myc_frac_ecm=', n_uptake_myc_frac(p,ecm_step) + write(iulog,*) 'n_uptake_myc_frac_ecm=', n_uptake_myc_frac(p,am_step) + write(iulog,*) ' sminn_layer_step_ecm=', sminn_layer_step(p,j,ecm_step) + write(iulog,*) ' sminn_layer_step_am=', sminn_layer_step(p,j,am_step) + do ipath = 1, npath6 + write(iulog,*) 'n_from_paths:', n_from_paths(p,j,ipath), npp_to_paths(p,j,ipath) + end do + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + end if end do !SPLIT TO NO3 and NH4 like in original fun @@ -1221,13 +1204,24 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s plant_ndemand_retrans(p) = plant_ndemand_retrans(p)/dt - Nuptake(p) = Nactive_no3(p) + Nactive_nh4(p) + Nnonmyc_no3(p) + Nnonmyc_nh4(p) + Nfix(p) + Npassive(p) + & + Nuptake(p) = Nactive_no3(p) + Nactive_nh4(p) + Nnonmyc_no3(p) + Nnonmyc_nh4(p) + Nfix(p)+ & retransn_to_npool(p)+free_retransn_to_npool(p) Nactive(p) = Nactive_no3(p) + Nactive_nh4(p) + Nnonmyc_no3(p) + Nnonmyc_nh4(p) - + if (Nuptake(p) > 10000._r8) then + write(iulog,*) 'ERROR: Nactive_no3 negative: ', Nactive_no3(p) + write(iulog,*) 'ERROR: Nactive_nh4 negative: ', Nactive_nh4(p) + write(iulog,*) 'ERROR: Nnonmyc_no3 negative: ', Nnonmyc_no3(p) + write(iulog,*) 'ERROR: Nnonmyc_nh4 negative: ', Nnonmyc_nh4(p) + write(iulog,*) 'ERROR: Nfix negative: ', Nfix(p) + write(iulog,*) 'ERROR: retransn_to_npool negative: ', retransn_to_npool(p) + write(iulog,*) 'ERROR: free_retransn_to_npool negative: ', free_retransn_to_npool(p) + + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + endif ! free N goes straight to the npool, not throught Nuptake... - sminn_to_plant_fun(p) = Nactive_no3(p) + Nactive_nh4(p) + Nnonmyc_no3(p) + Nnonmyc_nh4(p) + Nfix(p) + Npassive(p) + sminn_to_plant_fun(p) = Nactive_no3(p) + Nactive_nh4(p) + Nnonmyc_no3(p) + Nnonmyc_nh4(p) + Nfix(p) soil_n_extraction = ( sum(n_active_no3_vr(p,1: nlevdecomp))+sum(n_nonmyc_no3_vr(p,1: nlevdecomp))+& sum(n_active_nh4_vr(p,1: nlevdecomp)) + sum(n_nonmyc_nh4_vr(p,1: nlevdecomp))) @@ -1251,6 +1245,23 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s npp_Nuptake(p) = soilc_change(p) ! how much carbon goes to growth of tissues? npp_growth(p) = (Nuptake(p)- free_retransn_to_npool(p))*plantCN(p)+(excess_carbon_acc/dt) !does not include gresp, since this is calculated from growth + + if (npp_growth(p) < -10000._r8 .or. npp_growth(p) > 10000._r8) then + write(iulog,*) 'ERROR: Nuptake(p) is negative: ', Nuptake(p) + write(iulog,*) 'ERROR: npp_Nuptake(p) is negative: ', npp_Nuptake(p) + write(iulog,*) 'ERROR: free_retransn_to_npool(p) is negative: ', free_retransn_to_npool(p) + write(iulog,*) 'ERROR: plantCN(p) is negative: ', plantCN(p) + write(iulog,*) 'ERROR: excess_carbon_acc is negative: ', excess_carbon_acc + write(iulog,*) 'ERROR: npp_Nactive(p) is negative: ', npp_Nactive(p) + write(iulog,*) 'ERROR: npp_Nnonmyc(p) is npp_Nnonmyc: ', npp_Nnonmyc(p) + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + endif + if (npp_Nuptake(p) > 10000._r8) then + write(iulog,*) 'ERROR: npp_N negative: ', npp_Nuptake(p) + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + endif !-----------------------Diagnostic Fluxes------------------------------! if(availc(p).gt.0.0_r8)then !what happens in the night? @@ -1283,12 +1294,18 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s call t_startf( 'updateCNFUNMIMICSplus' ) call updateCNFUNMIMICSplus (bounds, num_soilc, filter_soilc, cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_carbonflux_inst, cnfunmimicsplus_inst, & - c_am_resp_vr_patch, c_ecm_resp_vr_patch, c_am_growth_vr_patch, c_ecm_growth_vr_patch, & - n_am_growth_vr_patch, n_ecm_growth_vr_patch, c_ecm_enz_vr_patch, & - n_somc2ecm_vr_patch, n_somp2ecm_vr_patch, c_somc2soma_vr_patch, c_somp2soma_vr_patch,& - sminno3_to_ecm_vr_patch, sminno3_to_am_vr_patch, sminnh4_to_ecm_vr_patch, sminnh4_to_am_vr_patch, & - n_active_no3_vr, n_nonmyc_no3_vr, n_active_nh4_vr, n_nonmyc_nh4_vr & - ) + c_am_resp_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), c_ecm_resp_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + c_am_growth_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), c_ecm_growth_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + n_am_growth_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), n_ecm_growth_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + c_ecm_enz_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), n_somc2ecm_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + n_somp2ecm_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + c_somc2soma_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), c_somp2soma_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp),& + sminno3_to_ecm_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), sminno3_to_am_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + sminnh4_to_ecm_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), sminnh4_to_am_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp), & + n_active_no3_vr(bounds%begp:bounds%endp, 1:nlevdecomp), n_nonmyc_no3_vr(bounds%begp:bounds%endp, 1:nlevdecomp), & + n_active_nh4_vr(bounds%begp:bounds%endp, 1:nlevdecomp), n_nonmyc_nh4_vr(bounds%begp:bounds%endp, 1:nlevdecomp) & + ) + call t_stopf( 'updateCNFUNMIMICSplus' ) end subroutine CNFUNMIMICSplus @@ -1319,25 +1336,25 @@ subroutine updateCNFUNMIMICSplus (bounds, num_soilc, filter_soilc, & type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst type(cnfunmimicsplus_type) , intent(inout) :: cnfunmimicsplus_inst ! mycorrhiza patch fluxes - real(r8), intent(in) :: c_am_resp_vr_patch ! carbon respiration flux for AM mycorrhiza - real(r8), intent(in) :: c_ecm_resp_vr_patch ! carbon respiration flux for ECM mycorrhiza - real(r8), intent(in) :: c_am_growth_vr_patch ! carbon growth flux for AM mycorrhiza - real(r8), intent(in) :: c_ecm_growth_vr_patch ! carbon growth flux for ECM mycorrhiza - real(r8), intent(in) :: n_am_growth_vr_patch ! nitrogen growth flux for AM mycorrhiza - real(r8), intent(in) :: n_ecm_growth_vr_patch ! nitrogen growth flux for ECM mycorrhiza - real(r8), intent(in) :: c_ecm_enz_vr_patch ! carbon enzyme production flux for ECM mycorrhiza - real(r8), intent(in) :: n_somc2ecm_vr_patch ! nitrogen mining from ECM mycorrhiza - real(r8), intent(in) :: n_somp2ecm_vr_patch ! nitrogen mining from ECM mycorrhiza - real(r8), intent(in) :: c_somc2soma_vr_patch ! carbon release from mining from somc pool - real(r8), intent(in) :: c_somp2soma_vr_patch ! carbon release from mining from somp pool - real(r8), intent(in) :: sminno3_to_ecm_vr_patch ! No3 flux from soil to ECM - real(r8), intent(in) :: sminno3_to_am_vr_patch ! No3 flux from soil to AM - real(r8), intent(in) :: sminnh4_to_ecm_vr_patch ! NH4 flux from soil to ECM - real(r8), intent(in) :: sminnh4_to_am_vr_patch ! NH4 flux from soil to AM - real(r8), intent(in) :: n_active_no3_vr ! Layer mycorrhizal no3 uptake (gN/m2) - real(r8), intent(in) :: n_nonmyc_no3_vr ! Layer non-myc no3 uptake (gN/m2) - real(r8), intent(in) :: n_active_nh4_vr ! Layer mycorrhizal nh4 uptake (gN/m2) - real(r8), intent(in) :: n_nonmyc_nh4_vr ! Layer non-myc nh4 uptake (gN/m2) + real(r8), intent(in) :: c_am_resp_vr_patch(:,:) ! carbon respiration flux for AM mycorrhiza + real(r8), intent(in) :: c_ecm_resp_vr_patch(:,:) ! carbon respiration flux for ECM mycorrhiza + real(r8), intent(in) :: c_am_growth_vr_patch(:,:) ! carbon growth flux for AM mycorrhiza + real(r8), intent(in) :: c_ecm_growth_vr_patch(:,:) ! carbon growth flux for ECM mycorrhiza + real(r8), intent(in) :: n_am_growth_vr_patch(:,:) ! nitrogen growth flux for AM mycorrhiza + real(r8), intent(in) :: n_ecm_growth_vr_patch(:,:) ! nitrogen growth flux for ECM mycorrhiza + real(r8), intent(in) :: c_ecm_enz_vr_patch(:,:) ! carbon enzyme production flux for ECM mycorrhiza + real(r8), intent(in) :: n_somc2ecm_vr_patch(:,:) ! nitrogen mining from ECM mycorrhiza + real(r8), intent(in) :: n_somp2ecm_vr_patch(:,:) ! nitrogen mining from ECM mycorrhiza + real(r8), intent(in) :: c_somc2soma_vr_patch(:,:) ! carbon release from mining from somc pool + real(r8), intent(in) :: c_somp2soma_vr_patch(:,:) ! carbon release from mining from somp pool + real(r8), intent(in) :: sminno3_to_ecm_vr_patch(:,:) ! No3 flux from soil to ECM + real(r8), intent(in) :: sminno3_to_am_vr_patch(:,:) ! No3 flux from soil to AM + real(r8), intent(in) :: sminnh4_to_ecm_vr_patch(:,:) ! NH4 flux from soil to ECM + real(r8), intent(in) :: sminnh4_to_am_vr_patch(:,:) ! NH4 flux from soil to AM + real(r8), intent(in) :: n_active_no3_vr(:,:) ! Layer mycorrhizal no3 uptake (gN/m2) + real(r8), intent(in) :: n_nonmyc_no3_vr(:,:) ! Layer non-myc no3 uptake (gN/m2) + real(r8), intent(in) :: n_active_nh4_vr(:,:) ! Layer mycorrhizal nh4 uptake (gN/m2) + real(r8), intent(in) :: n_nonmyc_nh4_vr(:,:) ! Layer non-myc nh4 uptake (gN/m2) !!! soilc_change_col is not used anywhere @@ -1462,6 +1479,7 @@ real(r8) function fun_cost_fix(fixer,a_fix,b_fix,c_fix,big_cost,crootfr,s_fix, t ! Calculate the cost of fixing N by nodules. ! Code Description: ! This code is written to CLM4CN by Mingjie Shi on 06/27/2013 +use clm_varcon , only : tfrz implicit none !-------------------------------------------------------------------------- @@ -1479,8 +1497,12 @@ real(r8) function fun_cost_fix(fixer,a_fix,b_fix,c_fix,big_cost,crootfr,s_fix, t real(r8), intent(in) :: big_cost ! an arbitrary large cost (gC/gN) real(r8), intent(in) :: crootfr ! fraction of roots for carbon that are in this layer real(r8), intent(in) :: s_fix ! Inverts Houlton et al. 2008 and constrains between 7.5 and 12.5 - real(r8), intent(in) :: tc_soisno ! soil temperature (degrees Celsius) + real(r8), intent(in) :: tc_soisno ! soil temperature (K) + ! LOCAL VARIABIABLES: + real(r8) :: t_soil_c ! temperragture in celcious + + t_soil_c = tc_soisno - tfrz if (fixer == 1 .and. crootfr > 1.e-6_r8) then ! New term to directly account for Ben Houlton's temperature response function. ! Assumes s_fix is -6. (RF, Jan 2015) @@ -1496,40 +1518,14 @@ real(r8) function fun_cost_fix(fixer,a_fix,b_fix,c_fix,big_cost,crootfr,s_fix, t ! the temperature function to give a temperature-limited N:C of f/6. This number ! can then be inverted to give a temperature limited C:N, as 1/(f/6). Which is the ! same as 6/f, given here" - fun_cost_fix = (-1*s_fix) * 1.0_r8 / (1.25_r8* (exp(a_fix + b_fix * tc_soisno * (1._r8 - 0.5_r8 * tc_soisno / c_fix)) )) + fun_cost_fix = (-1*s_fix) * 1.0_r8 / (1.25_r8* (exp(a_fix + b_fix * t_soil_c * (1._r8 - 0.5_r8 * t_soil_c / c_fix)) )) else fun_cost_fix = big_cost end if ! ends up with the fixer or non-fixer decision end function fun_cost_fix !========================================================================================= - real(r8) function fun_cost_active(sminn_layer,big_cost,kc_active,kn_active,rootc_dens,crootfr,smallValue) - -! Description: -! Calculate the cost of active uptake of N frm the soil. -! Code Description: -! This code is written to CLM4 by Mingjie Shi. - implicit none -!-------------------------------------------------------------------------- -! Function result. -!-------------------------------------------------------------------------- - real(r8), intent(in) :: sminn_layer ! Amount of N (as NH4 or NO3) in the soil that is available to plants (gN/m2). - real(r8), intent(in) :: big_cost ! An arbitrary large cost (gC/gN). - real(r8), intent(in) :: kc_active ! Constant for cost of active uptake (gC/m2). - real(r8), intent(in) :: kn_active ! Constant for cost of active uptake (gC/m2). - real(r8), intent(in) :: rootc_dens ! Root carbon density in layer (gC/m3). - real(r8), intent(in) :: crootfr ! Fraction of roots that are in this layer. - real(r8), intent(in) :: smallValue ! A small number. - - if (rootc_dens > 1.e-6_r8.and.sminn_layer > smallValue) then - fun_cost_active = kn_active/sminn_layer + kc_active/rootc_dens - else -! There are very few roots in this layer. Set a high cost. - fun_cost_active = big_cost - end if - - end function fun_cost_active !========================================================================================= real(r8) function fun_cost_nonmyc(sminn_layer,big_cost,kc_nonmyc,kn_nonmyc,rootc_dens,crootfr,smallValue) diff --git a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 index f49da9147d..dbe172410f 100644 --- a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 @@ -821,17 +821,17 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu ! sum up N fluxes to plant after initial competition sminn_to_plant(c) = 0._r8 !this isn't use in fun. do j = 1, nlevdecomp - if ((cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%no3_myc_to_plant_col & - - smin_no3_to_plant_vr(c,j)).gt.0.0000000000001_r8) then + if ((cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%sminno3_to_ecm_vr_col(c,j) + & + cnfunmimicsplus_inst%sminno3_to_am_vr_col(c,j) - smin_no3_to_plant_vr(c,j)).gt.0.0000000000001_r8) then write(iulog,*) 'problem with limitations on no3 uptake', & - cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%no3_myc_to_plant_col, & + cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%no3_myc_to_plant_col(c,j), & smin_no3_to_plant_vr(c,j) call endrun("too much NO3 uptake predicted by CNFUNMIMICSplus") end if - if ((cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%nh4_myc_to_plant_col & - - smin_nh4_to_plant_vr(c,j)).gt.0.0000000000001_r8) then + if ((cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%sminnh4_to_ecm_vr_col(c,j) + & + cnfunmimicsplus_inst%sminno3_to_am_vr_col(c,j) - smin_nh4_to_plant_vr(c,j)).gt.0.0000000000001_r8) then write(iulog,*) 'problem with limitations on nh4 uptake', & - cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%nh4_myc_to_plant_col, & + cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%nh4_myc_to_plant_col(c,j), & smin_nh4_to_plant_vr(c,j) call endrun("too much NH4 uptake predicted by CNFUNMIMICSplus") end if diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 5dcac051d7..9f80e5a337 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -33,7 +33,7 @@ module SoilBiogeochemDecompCascadeMIMICSplusMod use clm_varpar , only : i_litr_min, i_litr_max, i_cwdl2 use clm_varctl , only : iulog, spinup_state, anoxia, use_lch4, use_fates use clm_varcon , only : zsoi - use decompMod , only : bounds_type + use decompMod , only : bounds_type, subgrid_level_patch use spmdMod , only : masterproc use abortutils , only : endrun use CNSharedParamsMod , only : CNParamsShareInst, nlev_soildecomp_standard @@ -72,7 +72,7 @@ module SoilBiogeochemDecompCascadeMIMICSplusMod public :: readParams ! Read in parameters from params file public :: init_decompcascade_mimicsplus ! Initialization public :: decomp_rates_mimicsplus ! Figure out decomposition rates - public :: decomp_rates_after_FUN + !public :: decomp_rates_after_FUN public :: calc_myc_mining_rates public :: calc_myc_mortality public :: calc_myc_roi @@ -1767,113 +1767,113 @@ end subroutine decomp_rates_mimicsplus -subroutine decomp_rates_after_FUN (bounds, num_bgc_soilc, filter_bgc_soilc, & - num_soilp, filter_soilp, & - soilstate_inst, cnveg_carbonflux_inst, & - soilbiogeochem_carbonflux_inst, soilbiogeochem_nitrogenflux_inst, & - soilbiogeochem_carbonstate_inst, soilbiogeochem_nitrogenstate_inst,& - soilbiogeochem_state_inst & - ) -! -! DESCRIPTION -!! add a new subroutine decomp_rates_after_FUN, will be called in FUN -! col variables, do we have corresponding patch variables -! patch variables have to be p2c - -! USES: - use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type - use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type - use subgridAveMod , only : p2c - -! ARGUMENTS: - type(bounds_type) , intent(in) :: bounds - integer , intent(in) :: num_soilp ! number of soil patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for soil patches - integer , intent(in) :: num_bgc_soilc ! number of soil columns in filter - integer , intent(in) :: filter_bgc_soilc(:) ! filter for soil columns - type(soilstate_type) , intent(in) :: soilstate_inst - type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst - type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst - type(soilbiogeochem_carbonstate_type), intent(in) :: soilbiogeochem_carbonstate_inst - type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst - type(soilbiogeochem_carbonstate_type), intent(in) :: soilbiogeochem_nitrogenstate_inst - type(soilbiogeochem_state_type) , intent(in) :: soilbiogeochem_state_inst - - - !LOCAL VARIABLES: - integer :: fn ! number of values in pft filter - integer :: fp ! lake filter pft index - integer :: fc ! lake filter column index - integer :: p, c ! pft index - integer :: g, l ! indices - integer :: j, i, k ! soil/snow level index - real(r8), parameter :: eps = 1.e-6_r8 - real(r8):: tau_myc ! Mycorrhizal turnover rate for EcM & AM - real(r8):: myc1_conc ! Carbon concentration in ectomycorrhiza pool - real(r8):: myc2_conc ! Carbon concentration in abruscular mycorrhiza pool - real(r8):: avl_som_conc ! Carbon concentration in avaliable SOM pool - real(r8):: chem_som_conc ! Carbon concentration in chemically protected SOM pool - real(r8):: phys_som_conc ! Carbon concentration in physically protected SOM pool - real(r8):: term_1 ! - real(r8):: term_2 ! - real(r8):: t_soi_degC - - associate ( & - ! Carbon - decomp_cpools_vr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) C pools - pathfrac_decomp_cascade => soilbiogeochem_carbonflux_inst%pathfrac_decomp_cascade_col, & ! Output: [real(r8) (:,:,:) ] what fraction of C leaving a given pool passes through a given transition (frac) - rf_decomp_cascade => soilbiogeochem_carbonflux_inst%rf_decomp_cascade_col , & ! Input: [real(r8) (:,:,:) ] respired fraction in decomposition step (frac) +! subroutine decomp_rates_after_FUN (bounds, num_bgc_soilc, filter_bgc_soilc, & +! num_soilp, filter_soilp, & +! soilstate_inst, cnveg_carbonflux_inst, & +! soilbiogeochem_carbonflux_inst, soilbiogeochem_nitrogenflux_inst, & +! soilbiogeochem_carbonstate_inst, soilbiogeochem_nitrogenstate_inst,& +! soilbiogeochem_state_inst & +! ) +! ! +! ! DESCRIPTION +! !! add a new subroutine decomp_rates_after_FUN, will be called in FUN +! ! col variables, do we have corresponding patch variables +! ! patch variables have to be p2c + +! ! USES: +! use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type +! use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type +! use subgridAveMod , only : p2c + +! ! ARGUMENTS: +! type(bounds_type) , intent(in) :: bounds +! integer , intent(in) :: num_soilp ! number of soil patches in filter +! integer , intent(in) :: filter_soilp(:) ! filter for soil patches +! integer , intent(in) :: num_bgc_soilc ! number of soil columns in filter +! integer , intent(in) :: filter_bgc_soilc(:) ! filter for soil columns +! type(soilstate_type) , intent(in) :: soilstate_inst +! type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst +! type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst +! type(soilbiogeochem_carbonstate_type), intent(in) :: soilbiogeochem_carbonstate_inst +! type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst +! type(soilbiogeochem_carbonstate_type), intent(in) :: soilbiogeochem_nitrogenstate_inst +! type(soilbiogeochem_state_type) , intent(in) :: soilbiogeochem_state_inst + + +! !LOCAL VARIABLES: +! integer :: fn ! number of values in pft filter +! integer :: fp ! lake filter pft index +! integer :: fc ! lake filter column index +! integer :: p, c ! pft index +! integer :: g, l ! indices +! integer :: j, i, k ! soil/snow level index +! real(r8), parameter :: eps = 1.e-6_r8 +! real(r8):: tau_myc ! Mycorrhizal turnover rate for EcM & AM +! real(r8):: myc1_conc ! Carbon concentration in ectomycorrhiza pool +! real(r8):: myc2_conc ! Carbon concentration in abruscular mycorrhiza pool +! real(r8):: avl_som_conc ! Carbon concentration in avaliable SOM pool +! real(r8):: chem_som_conc ! Carbon concentration in chemically protected SOM pool +! real(r8):: phys_som_conc ! Carbon concentration in physically protected SOM pool +! real(r8):: term_1 ! +! real(r8):: term_2 ! +! real(r8):: t_soi_degC + +! associate ( & +! ! Carbon +! decomp_cpools_vr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) C pools +! pathfrac_decomp_cascade => soilbiogeochem_carbonflux_inst%pathfrac_decomp_cascade_col, & ! Output: [real(r8) (:,:,:) ] what fraction of C leaving a given pool passes through a given transition (frac) +! rf_decomp_cascade => soilbiogeochem_carbonflux_inst%rf_decomp_cascade_col , & ! Input: [real(r8) (:,:,:) ] respired fraction in decomposition step (frac) - decomp_npools_vr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col , & - - ) - - ! prep - tau_myc = mimicsplus_k_myc_som / secsphr ! Turnover rate mycorrhiza with unit conversions (hourly -> second) - tau_myc1 = min(1._r8, max(0._r8, mimicsplus_tau_ecm)) - fchem_myc1 = min(1._r8, max(0._r8, mimicsplus_fchem_ecm)) - fphys_myc1 = min(1._r8, max(0._r8, mimicsplus_fphys_ecm)) - tau_myc2 = min(1._r8, max(0._r8, mimicsplus_tau_am)) - fchem_myc2 = min(1._r8, max(0._r8, mimicsplus_fchem_am)) - fphys_myc2 = min(1._r8, max(0._r8, mimicsplus_fphys_am)) - ! main column loop - do fc = 1,num_bgc_soilc - c = filter_bgc_soilc(fc) - - ! Mycorrhizal concentration with necerssary unit conversions - ! mgC/cm3 = gC/m3 * (1e3 mg/g) / (1e6 cm3/m3) - myc1_conc = (decomp_cpools_vr(c,j,i_ecm_myc) / col%dz(c,j)) * & !ECW is this what goes into ROI function (see end of module) - g_to_mg * cm3_to_m3 - myc2_conc = (decomp_cpools_vr(c,j,i_am_myc) / col%dz(c,j)) * & - g_to_mg * cm3_to_m3 - - ! Soil organic matter concentration with necerssary unit conversions - ! mgC/cm3 = gC/m3 * (1e3 mg/g) / (1e6 cm3/m3) - avl_som_conc = (decomp_cpools_vr(c,j,i_avl_som) / col%dz(c,j)) * & !ECW This is for Baskaram N mining - g_to_mg * cm3_to_m3 - chem_som_conc = (decomp_cpools_vr(c,j,i_chem_som) / col%dz(c,j)) * & - g_to_mg * cm3_to_m3 - phys_som_conc = (decomp_cpools_vr(c,j,i_phys_som) / col%dz(c,j)) * & - g_to_mg * cm3_to_m3 - - - ! FLUXES from SOMC - - ! FLUXES from SOMP - - ! FLUXES from ECM +! decomp_npools_vr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col + +! ) + +! ! prep +! tau_myc = mimicsplus_k_myc_som / secsphr ! Turnover rate mycorrhiza with unit conversions (hourly -> second) +! tau_myc1 = min(1._r8, max(0._r8, mimicsplus_tau_ecm)) +! fchem_myc1 = min(1._r8, max(0._r8, mimicsplus_fchem_ecm)) +! fphys_myc1 = min(1._r8, max(0._r8, mimicsplus_fphys_ecm)) +! tau_myc2 = min(1._r8, max(0._r8, mimicsplus_tau_am)) +! fchem_myc2 = min(1._r8, max(0._r8, mimicsplus_fchem_am)) +! fphys_myc2 = min(1._r8, max(0._r8, mimicsplus_fphys_am)) +! ! main column loop +! do fc = 1,num_bgc_soilc +! c = filter_bgc_soilc(fc) + +! ! Mycorrhizal concentration with necerssary unit conversions +! ! mgC/cm3 = gC/m3 * (1e3 mg/g) / (1e6 cm3/m3) +! myc1_conc = (decomp_cpools_vr(c,j,i_ecm_myc) / col%dz(c,j)) * & !ECW is this what goes into ROI function (see end of module) +! g_to_mg * cm3_to_m3 +! myc2_conc = (decomp_cpools_vr(c,j,i_am_myc) / col%dz(c,j)) * & +! g_to_mg * cm3_to_m3 + +! ! Soil organic matter concentration with necerssary unit conversions +! ! mgC/cm3 = gC/m3 * (1e3 mg/g) / (1e6 cm3/m3) +! avl_som_conc = (decomp_cpools_vr(c,j,i_avl_som) / col%dz(c,j)) * & !ECW This is for Baskaram N mining +! g_to_mg * cm3_to_m3 +! chem_som_conc = (decomp_cpools_vr(c,j,i_chem_som) / col%dz(c,j)) * & +! g_to_mg * cm3_to_m3 +! phys_som_conc = (decomp_cpools_vr(c,j,i_phys_som) / col%dz(c,j)) * & +! g_to_mg * cm3_to_m3 + + +! ! FLUXES from SOMC + +! ! FLUXES from SOMP + +! ! FLUXES from ECM - ! FLUXES from AM +! ! FLUXES from AM - ! CALCULATE MORTALITY FLUXES +! ! CALCULATE MORTALITY FLUXES - ! CALCULATE FLUXES CARBON FLUXES +! ! CALCULATE FLUXES CARBON FLUXES - ! - end do - end associate -end subroutine decomp_rates_after_FUN +! ! +! end do +! end associate +! end subroutine decomp_rates_after_FUN subroutine calc_myc_mortality(cpool_myc, npool_myc, m_fr,fc_myc2som, fn_myc2som) ! DESCRIPTION: @@ -2153,12 +2153,12 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, real(r8), intent(in) :: dz ! layer thickness [m] ! FUN fluxes - real(r8), intent(inout) :: fc_veg2myc_no3 ! Carbon flux from plant to mycorrhiza [gC/m2] + real(r8), intent(inout) :: fc_veg2myc_no3 ! Carbon flux from plant to mycorrhiza [gC/m3] real(r8), intent(inout) :: fc_veg2myc_nh4 ! Carbon flux from plant to mycorrhiza [gC/m2] - real(r8), intent(inout) :: no3_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NO3) [gN/m2] - real(r8), intent(inout) :: nh4_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NH4) [gN/m2] - real(r8), intent(inout) :: no3_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NO3) [gN/m2] - real(r8), intent(inout) :: nh4_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NH4) [gN/m2] + real(r8), intent(inout) :: no3_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NO3) [gN/m3] + real(r8), intent(inout) :: nh4_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NH4) [gN/m3] + real(r8), intent(inout) :: no3_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NO3) [gN/m3] + real(r8), intent(inout) :: nh4_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NH4) [gN/m3] real(r8), intent(inout) :: fn_smin_no3_2myc ! nitrogen flux from inorganic NO3 pool to mycorrhiza [gN/m2] real(r8), intent(inout) :: fn_smin_nh4_2myc ! nitrogen flux from inorganic NH4 pool to mycorrhiza [gN/m2] @@ -2191,6 +2191,7 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, real(r8) :: no3_unpaid, nh4_unpaid ! nitrogen that did not actually reach the plant [gN/m2] real(r8) :: smin_overflow ! How much N mycorrhiza and non mycorrhiza promised to take out of soil and give to plant real(r8) :: l_no3_frac + real(r8), parameter :: small_value =1.0e-7_r8 character(len=256) :: message @@ -2253,18 +2254,40 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) * dt ! multiplied by dt to get it in same units as no3_from_nonmyc fn_smin_no3_2myc = fn_smin2myc * sminfrc_no3 fn_smin_nh4_2myc = fn_smin2myc * (1.0_r8 - sminfrc_no3) - ! If there is not enough nitrogen in the soil mineral, NO3 and NH4 - if (fn_smin_no3_2myc + no3_from_nonmyc > sminn * sminfrc_no3) then - smin_overflow = sminn * sminfrc_no3 - (fn_smin_no3_2myc + no3_from_nonmyc) ! NO3 that is actually in soil - - fn_smin_no3_2myc = fn_smin_no3_2myc - smin_overflow * fn_smin_no3_2myc / (fn_smin_no3_2myc + no3_from_nonmyc) ! mycorrhiza limit uptake from inorganic N pools - no3_from_nonmyc = no3_from_nonmyc - smin_overflow * no3_from_nonmyc / (fn_smin_no3_2myc + no3_from_nonmyc) ! non mycorrhiza limit uptake from inorganic N pools - endif - if (fn_smin_nh4_2myc + nh4_from_nonmyc > sminn * (1.0_r8 - sminfrc_no3)) then - smin_overflow = sminn * (1.0_r8 - sminfrc_no3) - (fn_smin_nh4_2myc + nh4_from_nonmyc) - fn_smin_nh4_2myc = fn_smin_nh4_2myc - smin_overflow * fn_smin_nh4_2myc / (fn_smin_nh4_2myc + nh4_from_nonmyc) - nh4_from_nonmyc = nh4_from_nonmyc - smin_overflow * nh4_from_nonmyc / (fn_smin_nh4_2myc + nh4_from_nonmyc) + if (sminn * sminfrc_no3 <= small_value) then + fn_smin_no3_2myc = 0.0_r8 + no3_from_nonmyc = 0.0_r8 + else + ! If there is not enough nitrogen in the soil mineral, NO3 and NH4 + if (fn_smin_no3_2myc + no3_from_nonmyc > sminn * sminfrc_no3) then + smin_overflow = (fn_smin_no3_2myc + no3_from_nonmyc) - sminn * sminfrc_no3! NO3 that is actually in soil - + fn_smin_no3_2myc = fn_smin_no3_2myc - smin_overflow * fn_smin_no3_2myc / (sminn * sminfrc_no3 + smin_overflow ) ! mycorrhiza limit uptake from inorganic N pools + no3_from_nonmyc = no3_from_nonmyc - smin_overflow * no3_from_nonmyc / (sminn * sminfrc_no3 + smin_overflow) ! non mycorrhiza limit uptake from inorganic N pools + if (& + no3_from_nonmyc < 0.0_r8 .or. fn_smin_no3_2myc < 0.0_r8) then + write(iulog,*) 'ERROR: type,myc, nonmyc, sminno3', myc_type, fn_smin_no3_2myc, no3_from_nonmyc, sminn *sminfrc_no3 - smin_overflow, sminfrc_no3 * sminn, fn_smin2myc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + endif + end if + if (sminn *(1.0_r8 - sminfrc_no3) <= small_value) then + nh4_from_nonmyc = 0.0_r8 + fn_smin_nh4_2myc = 0.0_r8 + else + if (fn_smin_nh4_2myc + nh4_from_nonmyc > sminn * (1.0_r8 - sminfrc_no3)) then + smin_overflow = (fn_smin_nh4_2myc + nh4_from_nonmyc) - sminn * (1.0_r8 - sminfrc_no3) + fn_smin_nh4_2myc = fn_smin_nh4_2myc - smin_overflow * fn_smin_nh4_2myc / (sminn * (1.0_r8 - sminfrc_no3) + smin_overflow) + nh4_from_nonmyc = nh4_from_nonmyc - smin_overflow * nh4_from_nonmyc / (sminn * (1.0_r8 - sminfrc_no3) + smin_overflow) + if ( & + nh4_from_nonmyc < 0.0_r8 .or. fn_smin_nh4_2myc < 0.0_r8) then + write(iulog,*) 'ERROR: type,myc, nonmyc, sminnh4', myc_type, fn_smin_nh4_2myc, nh4_from_nonmyc, sminn * (1.0_r8 - sminfrc_no3) - smin_overflow, (1.0_r8 - sminfrc_no3) * sminn, fn_smin2myc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + endif endif + + ! use new fraction and sminn if they got limited fn_smin2myc = (fn_smin_no3_2myc + fn_smin_nh4_2myc) /dz /dt ! put it back to gN/m3/s to be consistent with mining fluxes if(fn_smin2myc > 0.0_r8) then @@ -2273,8 +2296,7 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, l_no3_frac = 1.0_r8 endif - - + fc_veg2myc=fc_veg2myc_no3 + fc_veg2myc_nh4 if (myc_type == 1) then ! EcM call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp) call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) From 11d6a237a9c870e852770d5c07ca6a645ec0b548 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 10 Sep 2024 17:25:41 +0200 Subject: [PATCH 02/17] update tests --- .../testmods_dirs/clm/mimicsplus/user_nl_clm | 3 +- .../testmods_dirs/clm/mimicspluslong/README | 2 + .../clm/mimicspluslong/include_user_mods | 0 .../clm/mimicspluslong/shell_commands | 3 ++ .../clm/mimicspluslong/user_nl_clm | 52 +++++++++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluslong/README create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluslong/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluslong/shell_commands create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm index 554237debe..243bfd6b65 100644 --- a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm @@ -1,8 +1,7 @@ hist_dov2xy = .true., .true. ! Even though only 2 history tapes are defined here, set ndens to 1 for up to 6 history ! tapes, for the sake of mods that extend these default mods and may add other history tapes - hist_ndens = 1,1,1,1,1,1,1 !1=daily, 0=monthly output - hist_nhtfrq = 0,0,0,0,0,0,0 + hist_nhtfrq = 1,1,1,1,1,1,1 hist_mfilt = 1,1,1,1,1,1,1 hist_fincl1 = 'TRAFFICFLUX', 'SNOWLIQ:A','SNOWICE:A' ! Add FCO2 because few (if any) tests send this flux to the coupler, so it isn't checked via cpl hist files diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/README b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/README new file mode 100644 index 0000000000..7a0bbf7c73 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/README @@ -0,0 +1,2 @@ +This test mod turns on the MIMICSplus instead of the MIMICS or CENTURY below-ground +biogeochemistry. \ No newline at end of file diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/include_user_mods new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/shell_commands b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/shell_commands new file mode 100644 index 0000000000..a66f52f6fd --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/shell_commands @@ -0,0 +1,3 @@ +#!/bin/bash +./xmlchange CLM_FORCE_COLDSTART="on" + diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm new file mode 100644 index 0000000000..9aa507ca2f --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm @@ -0,0 +1,52 @@ +hist_dov2xy = .true., .true. +! Even though only 2 history tapes are defined here, set ndens to 1 for up to 6 history +! tapes, for the sake of mods that extend these default mods and may add other history tapes + hist_nhtfrq = 0,0,0,0,0,0,0 + hist_mfilt = 1,1,1,1,1,1,1 + hist_fincl1 = 'TRAFFICFLUX', 'SNOWLIQ:A','SNOWICE:A' +! Add FCO2 because few (if any) tests send this flux to the coupler, so it isn't checked via cpl hist files + hist_fincl1 += 'FCO2' + hist_fincl2 = 'LIT_MET_C_TO_MIC_COP_C', 'LIT_MET_C_TO_MIC_OLI_C', 'LIT_STR_C_TO_MIC_COP_C', 'LIT_STR_C_TO_MIC_OLI_C', + 'MIC_COP_C_TO_SOM_AVL_C', 'MIC_COP_C_TO_SOM_CHEM_C', 'MIC_COP_C_TO_SOM_PHYS_C', + 'MIC_OLI_C_TO_SOM_AVL_C', 'MIC_OLI_C_TO_SOM_CHEM_C', 'MIC_OLI_C_TO_SOM_PHYS_C', + 'SOM_CHEM_C_TO_SOM_AVL_C', 'SOM_PHYS_C_TO_SOM_AVL_C', + 'SOM_AVL_C_TO_MIC_COP_C', 'SOM_AVL_C_TO_MIC_OLI_C', + 'MYC_ECM_C_TO_SOM_AVL_C', 'MYC_ECM_C_TO_SOM_CHEM_C', 'MYC_ECM_C_TO_SOM_PHYS_C', + 'MYC_AM_C_TO_SOM_AVL_C', 'MYC_AM_C_TO_SOM_CHEM_C', 'MYC_AM_C_TO_SOM_PHYS_C' + + hist_fincl3 = 'TOTMYCC', 'SOILC_vr', 'TOTMICC', 'TOTMYCC', 'TOTLITC', 'TOTSOMC', 'TOTLITC_1m', 'TOTSOMC_1m', + 'DYN_COL_SOIL_ADJUSTMENTS_C', 'TOTCOLC', 'TOTECOSYSC', 'LIT_MET_C_vr', 'LIT_STR_C_vr', 'SOM_AVL_C_vr', + 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' + + hist_fincl5 = 'L1_RESP_FRAC_M1_vr', 'L1_RESP_FRAC_M2_vr', 'L2_RESP_FRAC_M1_vr', 'L2_RESP_FRAC_M2_vr', + 'M1_RESP_FRAC_S1_vr', 'M1_RESP_FRAC_S2_vr', 'M1_RESP_FRAC_S3_vr', + 'M2_RESP_FRAC_S1_vr', 'M2_RESP_FRAC_S2_vr', 'M2_RESP_FRAC_S3_vr', + 'S2_RESP_FRAC_S1_vr', 'S3_RESP_FRAC_S1_vr', + 'S1_RESP_FRAC_M1_vr', 'S1_RESP_FRAC_M2_vr', + 'MYC1_RESP_FRAC_S1_vr', 'MYC1_RESP_FRAC_S2_vr', 'MYC1_RESP_FRAC_S3_vr', + 'MYC2_RESP_FRAC_S1_vr', 'MYC2_RESP_FRAC_S2_vr', 'MYC2_RESP_FRAC_S3_vr' + + hist_fincl6 = 'L1_PATHFRAC_M1_vr', 'L1_PATHFRAC_M2_vr', 'L2_PATHFRAC_M1_vr', 'L2_PATHFRAC_M2_vr', + 'M1_PATHFRAC_S1_vr', 'M1_PATHFRAC_S2_vr', 'M1_PATHFRAC_S3_vr', + 'M2_PATHFRAC_S1_vr', 'M2_PATHFRAC_S2_vr', 'M2_PATHFRAC_S3_vr', + 'S2_PATHFRAC_S1_vr', 'S3_PATHFRAC_S1_vr', + 'S1_PATHFRAC_M1_vr', 'S1_PATHFRAC_M2_vr', + 'MYC1_PATHFRAC_S1_vr', 'MYC1_PATHFRAC_S2_vr', 'MYC1_PATHFRAC_S3_vr', + 'MYC2_PATHFRAC_S1_vr', 'MYC2_PATHFRAC_S2_vr', 'MYC2_PATHFRAC_S3_vr' + + hist_fincl7 = 'LIT_MET_HR_M1', 'LIT_MET_HR_M2', 'LIT_STR_HR_M1', 'LIT_STR_HR_M2', + 'MIC_COP_HR_S1', 'MIC_COP_HR_S2', 'MIC_COP_HR_S3', + 'MIC_OLI_HR_S1', 'MIC_OLI_HR_S2', 'MIC_OLI_HR_S3', + 'SOM_AVL_HR_M1', 'SOM_AVL_HR_M2', + + + + use_ssre = .true. + paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus.nc' + + +soil_decomp_method = 'MIMICSplusAas2023' +hist_fincl1 += 'TOTMYCC', 'SOILC_vr', 'TOTMICC', 'TOTMYCC', 'TOTLITC', 'TOTSOMC', 'TOTLITC_1m', 'TOTSOMC_1m', + 'DYN_COL_SOIL_ADJUSTMENTS_C', 'TOTCOLC', 'TOTECOSYSC', 'LIT_MET_C_vr', 'LIT_STR_C_vr', 'SOM_AVL_C_vr', + 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' + From 36262f873bd84062d2f8fd830ce25d08615927c6 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 10 Sep 2024 17:26:52 +0200 Subject: [PATCH 03/17] Add totmyc for nytrogen --- .../SoilBiogeochemNitrogenStateType.F90 | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 index 0940914aca..2ae1987aad 100644 --- a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 @@ -51,6 +51,7 @@ module SoilBiogeochemNitrogenStateType real(r8), pointer :: totlitn_col (:) ! col (gN/m2) total litter nitrogen real(r8), pointer :: totmicn_col (:) ! col (gN/m2) total microbial nitrogen real(r8), pointer :: totsomn_col (:) ! col (gN/m2) total soil organic matter nitrogen + real(r8), pointer :: totmycn_col (:) ! col (gN/m2) total mycorrhiza nitrogen real(r8), pointer :: totlitn_1m_col (:) ! col (gN/m2) total litter nitrogen to 1 meter real(r8), pointer :: totsomn_1m_col (:) ! col (gN/m2) total soil organic matter nitrogen to 1 meter real(r8), pointer :: dyn_nbal_adjustments_col (:) ! (gN/m2) adjustments to each column made in this timestep via dynamic column adjustments (note: this variable only makes sense at the column-level: it is meaningless if averaged to the gridcell-level) @@ -131,6 +132,7 @@ subroutine InitAllocate(this, bounds) allocate(this%ntrunc_col (begc:endc)) ; this%ntrunc_col (:) = nan allocate(this%totlitn_col (begc:endc)) ; this%totlitn_col (:) = nan allocate(this%totmicn_col (begc:endc)) ; this%totmicn_col (:) = nan + allocate(this%totmycn_col (begc:endc)) ; this%totmycn_col (:) = nan allocate(this%totsomn_col (begc:endc)) ; this%totsomn_col (:) = nan allocate(this%totlitn_1m_col (begc:endc)) ; this%totlitn_1m_col (:) = nan allocate(this%totsomn_1m_col (begc:endc)) ; this%totsomn_1m_col (:) = nan @@ -312,6 +314,12 @@ subroutine InitHistory(this, bounds) avgflag='A', long_name='total microbial N', & ptr_col=this%totmicn_col) end if + if ( decomp_method == mimicsplus_decomp) then !ECW do I need to do sth here? Do I need to add myc here? + this%totmycn_col(begc:endc) = spval + call hist_addfld1d (fname='TOTMYCN', units='gN/m^2', & + avgflag='A', long_name='total mycorrhizal N', & + ptr_col=this%totmycn_col) + end if this%totsomn_col(begc:endc) = spval call hist_addfld1d (fname='TOTSOMN', units='gN/m^2', & @@ -435,6 +443,7 @@ subroutine InitCold(this, bounds, & end if this%totlitn_col(c) = 0._r8 this%totmicn_col(c) = 0._r8 + this%totmycn_col(c) = 0._r8 this%totsomn_col(c) = 0._r8 this%totlitn_1m_col(c) = 0._r8 this%totsomn_1m_col(c) = 0._r8 @@ -753,6 +762,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column ) end if this%totlitn_col(i) = value_column this%totmicn_col(i) = value_column + this%totmycn_col(i) = value_column this%totsomn_col(i) = value_column this%totsomn_1m_col(i) = value_column this%totlitn_1m_col(i) = value_column @@ -991,6 +1001,21 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg end if end do + ! total mycorrhyzal nitrogen (TOTMYCN) + do fc = 1,num_allc + c = filter_allc(fc) + this%totmycn_col(c) = 0._r8 + end do + do l = 1, ndecomp_pools + if ( decomp_cascade_con%is_mycorrhiza(l) ) then + do fc = 1,num_allc + c = filter_allc(fc) + this%totmycn_col(c) = & + this%totmycn_col(c) + & + this%decomp_npools_col(c,l) + end do + end if + end do ! total soil organic matter nitrogen (TOTSOMN) do fc = 1,num_allc c = filter_allc(fc) @@ -1070,6 +1095,7 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg this%cwdn_col(c) + & this%totlitn_col(c) + & this%totmicn_col(c) + & + this%totmycn_col(c) + & this%totsomn_col(c) + & this%sminn_col(c) + & ecovegn_col @@ -1080,6 +1106,7 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg this%cwdn_col(c) + & this%totlitn_col(c) + & this%totmicn_col(c) + & + this%totmycn_col(c) + & this%totsomn_col(c) + & this%sminn_col(c) + & this%ntrunc_col(c) + & From 19fdafc8b5d20f9d59974303a784b2a05d6f9b4c Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 10 Sep 2024 17:28:01 +0200 Subject: [PATCH 04/17] Add fixes for various mistakes --- src/biogeochem/CNBalanceCheckMod.F90 | 3 ++- src/main/clm_instMod.F90 | 3 ++- .../SoilBiogeochemDecompCascadeMIMICSplusMod.F90 | 9 +++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index 35efd2e9aa..9ef0a2bed8 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -497,6 +497,7 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & use clm_varctl, only : use_crop use subgridAveMod, only: c2g use atm2lndType, only: atm2lnd_type + use SoilBiogeochemDecompCascadeConType, only: decomp_method, mimicsplus_decomp ! ! !ARGUMENTS: class(cn_balance_type) , intent(inout) :: this @@ -595,7 +596,7 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, & col_ninputs(c) = col_ninputs(c) + fates_litter_flux(c) end if - if(use_fun)then + if(use_fun .or. decomp_method == mimicsplus_decomp) then col_ninputs(c) = col_ninputs(c) + ffix_to_sminn(c) ! for FUN, free living fixation is a seprate flux. RF. endif diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index ff1f57c845..4db9f9ab5c 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -394,8 +394,9 @@ subroutine clm_instInit(bounds) else if (decomp_method == mimicsplus_decomp ) then call init_decompcascade_mimicsplus(bounds, soilbiogeochem_state_inst, & soilstate_inst) - call cnfunmimicsplus_inst%Init(bounds) end if + ! init this all the time, so we don't have to pass it as optional. + call cnfunmimicsplus_inst%Init(bounds) ! Initalize soilbiogeochem carbon types diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 9f80e5a337..0c5b0205d9 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -2012,9 +2012,10 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ real(r8), intent(out) :: cost_myc_nh4 ! cost function for mycorrhiza in FUN UNITS!!!! !LOCAL VARIABLES - real(r8) :: secphr = 60.0_r8 * 60.0_r8 + real(r8), parameter :: secphr = 60.0_r8 * 60.0_r8 real(r8), parameter :: f_enz = 0.1_r8 ! [-]Fraction of C from vegetation to EcM, that goes into SOMa for mining real(r8), parameter :: f_growth = 0.5_r8 ! [-] Fraction of mycorrhizal N uptake that needs to stay within the fungi (not given to plant) + real(r8), parameter :: small_Value = 1.0e-6_r8 real(r8) :: fn_myc2veg ! nitrogen fluxes mycorrhiza to vegetation real(r8) :: fn_smin2myc ! nitrogen flux from mineral soil to myc [gN/m2/s] @@ -2067,10 +2068,10 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ end if end if - if (fn_myc2veg > 0) then - if (sminfrc_no3 > 0) then + if (fn_myc2veg > small_Value) then + if (sminfrc_no3 > small_Value) then cost_myc_no3 = fc_veg2myc / (fn_myc2veg) / sminfrc_no3 - if ( (1.0_r8 - sminfrc_no3)> 0) then + if ( (1.0_r8 - sminfrc_no3)> small_Value) then cost_myc_nh4 = fc_veg2myc / (fn_myc2veg) / (1.0_r8 - sminfrc_no3) else cost_myc_nh4 = big_cost From e97c6e6a54eed18d1b4b853b525de6b164f08f63 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 10 Sep 2024 17:28:18 +0200 Subject: [PATCH 05/17] add pools and flux update to decomp --- src/biogeochem/CNDriverMod.F90 | 3 +- .../SoilBiogeochemDecompMod.F90 | 83 +++++++++++++++++-- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index ba2a803719..a4a60a1702 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -541,7 +541,8 @@ subroutine CNDriverNoLeaching(bounds, cn_decomp_pools=cn_decomp_pools(begc:endc,1:nlevdecomp,1:ndecomp_pools), & p_decomp_cpool_loss=p_decomp_cpool_loss(begc:endc,1:nlevdecomp,1:ndecomp_cascade_transitions), & pmnf_decomp_cascade=pmnf_decomp_cascade(begc:endc,1:nlevdecomp,1:ndecomp_cascade_transitions), & - p_decomp_npool_to_din=p_decomp_npool_to_din(begc:endc,1:nlevdecomp,1:ndecomp_cascade_transitions)) + p_decomp_npool_to_din=p_decomp_npool_to_din(begc:endc,1:nlevdecomp,1:ndecomp_cascade_transitions), & + cnfunmimicsplus_inst=cnfunmimicsplus_inst) call t_stopf('SoilBiogeochemDecomp') diff --git a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 index adc914700b..6b0e674c2c 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 @@ -13,6 +13,7 @@ module SoilBiogeochemDecompMod use clm_varpar , only : nlevdecomp, ndecomp_cascade_transitions, ndecomp_pools use clm_varctl , only : use_nitrif_denitrif, use_lch4, iulog use clm_varcon , only : dzsoi_decomp + use clm_varpar , only : i_phys_som, i_chem_som, i_avl_som, i_ecm_myc, i_am_myc use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, mimics_decomp, mimicsplus_decomp, decomp_method, use_soil_matrixcn use SoilBiogeochemStateType , only : soilbiogeochem_state_type use SoilBiogeochemCarbonStateType , only : soilbiogeochem_carbonstate_type @@ -71,10 +72,12 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, soilbiogeochem_state_inst, soilbiogeochem_carbonstate_inst, soilbiogeochem_carbonflux_inst, & soilbiogeochem_nitrogenstate_inst, soilbiogeochem_nitrogenflux_inst, & cn_decomp_pools, p_decomp_cpool_loss, pmnf_decomp_cascade, & - p_decomp_npool_to_din) + p_decomp_npool_to_din, cnfunmimicsplus_inst) ! ! !USES: use SoilBiogeochemDecompCascadeConType, only : i_atm + use CNFUNMIMICSplusMod, only : cnfunmimicsplus_type + use clm_time_manager, only : get_step_size_real ! ! !ARGUMENT: type(bounds_type) , intent(in) :: bounds @@ -89,11 +92,14 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, real(r8) , intent(inout) :: p_decomp_cpool_loss(bounds%begc:,1:,1:) ! potential C loss from one pool to another real(r8) , intent(inout) :: pmnf_decomp_cascade(bounds%begc:,1:,1:) ! potential mineral N flux from one pool to another real(r8) , intent(in) :: p_decomp_npool_to_din(bounds%begc:,1:,1:) ! potential flux to dissolved inorganic N + type(cnfunmimicsplus_type) , intent(inout) :: cnfunmimicsplus_inst ! ! !LOCAL VARIABLES: - integer :: c,j,k,l,m ! indices - integer :: fc ! lake filter column index - integer :: begc,endc ! bounds + integer :: c,j,k,l,m ! indices + integer :: fc ! lake filter column index + integer :: begc,endc ! bounds + real(r8) :: dt ! timestep + ! For methane code real(r8):: hrsum(bounds%begc:bounds%endc,1:nlevdecomp) ! sum of HR (gC/m2/s) !----------------------------------------------------------------------- @@ -131,12 +137,29 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, decomp_cascade_hr_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_hr_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s) decomp_cascade_ctransfer_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s) phr_vr => soilbiogeochem_carbonflux_inst%phr_vr_col , & ! Input: [real(r8) (:,:) ] potential HR (gC/m3/s) - fphr => soilbiogeochem_carbonflux_inst%fphr_col & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic - ) + fphr => soilbiogeochem_carbonflux_inst%fphr_col , & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic + + c_am_resp_vr => cnfunmimicsplus_inst%c_am_resp_vr_col , & + c_ecm_resp_vr => cnfunmimicsplus_inst%c_ecm_resp_vr_col , & + c_am_growth_vr => cnfunmimicsplus_inst%c_am_growth_vr_col , & + c_ecm_growth_vr => cnfunmimicsplus_inst%c_ecm_growth_vr_col , & + n_am_growth_vr => cnfunmimicsplus_inst%n_am_growth_vr_col , & + n_ecm_growth_vr => cnfunmimicsplus_inst%n_ecm_growth_vr_col , & + c_ecm_enz_vr => cnfunmimicsplus_inst%c_ecm_enz_vr_col , & + n_somc2ecm_vr => cnfunmimicsplus_inst%n_somc2ecm_vr_col(:,:) , & ! nitrogen mining from ECM mycorrhiza + n_somp2ecm_vr => cnfunmimicsplus_inst%n_somp2ecm_vr_col(:,:) , & ! nitrogen mining from ECM mycorrhiza + c_somc2soma_vr => cnfunmimicsplus_inst%c_somc2soma_vr_col(:,:) , & ! carbon release from mining from somc pool + c_somp2soma_vr => cnfunmimicsplus_inst%c_somp2soma_vr_col(:,:) , & ! carbon release from mining from somp pool + sminno3_to_ecm_vr => cnfunmimicsplus_inst%sminno3_to_ecm_vr_col(:,:) , & ! No3 flux from soil NO3 to ECM + sminno3_to_am_vr => cnfunmimicsplus_inst%sminno3_to_am_vr_col(:,:) , & ! No3 flux from soil NO3 to AM + sminnh4_to_ecm_vr => cnfunmimicsplus_inst%sminnh4_to_ecm_vr_col(:,:) , & ! No3 flux from soil NO3 to ECM + sminnh4_to_am_vr => cnfunmimicsplus_inst%sminnh4_to_am_vr_col(:,:) & ! No3 flux from soil NO3 to A + ) + dt = get_step_size_real() ! column loop to calculate actual immobilization and decomp rates, following ! resolution of plant/heterotroph competition for mineral N - + dt = get_step_size_real() ! calculate c:n ratios of applicable pools !ECW CN ratio calculated based on pool sizes do l = 1, ndecomp_pools if ( floating_cn_ratio_decomp_pools(l) ) then @@ -274,6 +297,52 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, end do end do + ! update fluxes from mimicsplus after FUN + + + if (decomp_method == mimicsplus_decomp) then + + do fc = 1,num_bgc_soilc + c = filter_bgc_soilc(fc) + do j = 1,nlevdecomp + do k = 1,ndecomp_cascade_transitions + + if (cascade_donor_pool(k) == i_ecm_myc) then + ! mining fluxes + if (cascade_receiver_pool(k) == i_chem_som) then + ! mortality fluxes have been calculated in the mimicsplus_decomp_rates() + decomp_cascade_ntransfer_vr(c,j,k) = decomp_cascade_ntransfer_vr(c,j,k) - n_somc2ecm_vr(c,j) + else if (cascade_receiver_pool(k) == i_phys_som) then + decomp_cascade_ntransfer_vr(c,j,k) = decomp_cascade_ntransfer_vr(c,j,k) - n_somp2ecm_vr(c,j) + end if + + elseif (cascade_receiver_pool(k) == i_avl_som) then + ! carbon release associated with mining + if (cascade_donor_pool(k) == i_chem_som) then + decomp_cascade_ctransfer_vr(c,j,k) = decomp_cascade_ctransfer_vr(c,j,k) + c_somc2soma_vr(c,j) + else if (cascade_donor_pool(k) == i_phys_som) then + decomp_cascade_ctransfer_vr(c,j,k) = decomp_cascade_ctransfer_vr(c,j,k) + c_somp2soma_vr(c,j) + end if + end if + ! fluxes that are not part of the cascade. + decomp_cpools_vr(c,j,i_ecm_myc) = decomp_cpools_vr(c,j,i_ecm_myc) + (c_ecm_growth_vr(c,j) - & + c_ecm_resp_vr(c,j)) * dt + decomp_npools_vr(c,j,i_ecm_myc) = decomp_npools_vr(c,j,i_ecm_myc) + (n_ecm_growth_vr(c,j) + & + sminno3_to_ecm_vr(c,j) + sminnh4_to_ecm_vr(c,j)) * dt + decomp_cpools_vr(c,j,i_am_myc) = decomp_cpools_vr(c,j,i_am_myc) + (c_am_growth_vr(c,j) - & + c_am_resp_vr(c,j)) * dt + decomp_npools_vr(c,j,i_am_myc) = decomp_npools_vr(c,j,i_am_myc) + (n_ecm_growth_vr(c,j) + & + sminno3_to_am_vr(c,j) + sminnh4_to_am_vr(c,j)) * dt + decomp_npools_vr(c,j,i_avl_som) = decomp_npools_vr(c,j,i_avl_som) + c_ecm_enz_vr(c,j) * dt + end do ! transitions + end do ! layer + enddo !column + + + + + end if + end associate end subroutine SoilBiogeochemDecomp From 31d9bb4d1fa5c2f9bfaeb2a9d75d190ee762c15c Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 17 Sep 2024 17:31:52 +0200 Subject: [PATCH 06/17] add single point test --- .../testmods_dirs/clm/mimics/user_nl_clm | 1 + .../testmods_dirs/clm/mimicsplus/user_nl_clm | 2 +- .../clm/mimicspluslong/user_nl_clm | 2 +- .../testmods_dirs/clm/mimicspluspoi/README | 2 + .../clm/mimicspluspoi/include_user_mods | 0 .../clm/mimicspluspoi/shell_commands | 5 ++ .../clm/mimicspluspoi/user_nl_clm | 52 +++++++++++++++++++ 7 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/README create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/shell_commands create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm index 63983aca20..f44dc4d803 100644 --- a/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm @@ -6,3 +6,4 @@ hist_dov2xy = .true., .true. hist_ndens = 1,1,1,1,1,1 hist_nhtfrq = 1,1 hist_mfilt = 1,1 + paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus_netcdf5_11.09.24.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm index 243bfd6b65..adb5db0421 100644 --- a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm @@ -42,7 +42,7 @@ hist_dov2xy = .true., .true. use_ssre = .true. - paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus.nc' + paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus_netcdf5_11.09.24.nc' soil_decomp_method = 'MIMICSplusAas2023' diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm index 9aa507ca2f..4379360486 100644 --- a/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluslong/user_nl_clm @@ -42,7 +42,7 @@ hist_dov2xy = .true., .true. use_ssre = .true. - paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus.nc' + paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus_netcdf5_11.09.24.nc' soil_decomp_method = 'MIMICSplusAas2023' diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/README b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/README new file mode 100644 index 0000000000..7a0bbf7c73 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/README @@ -0,0 +1,2 @@ +This test mod turns on the MIMICSplus instead of the MIMICS or CENTURY below-ground +biogeochemistry. \ No newline at end of file diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/include_user_mods new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/shell_commands b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/shell_commands new file mode 100644 index 0000000000..da0e1375f5 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/shell_commands @@ -0,0 +1,5 @@ +#!/bin/bash +./xmlchange CLM_FORCE_COLDSTART="on" +./xmlchange NTASKS=1 +./xmlchange PTS_LON=170.0 +./xmlchange PTS_LAT=-42.0 diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/user_nl_clm new file mode 100644 index 0000000000..adb5db0421 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicspluspoi/user_nl_clm @@ -0,0 +1,52 @@ +hist_dov2xy = .true., .true. +! Even though only 2 history tapes are defined here, set ndens to 1 for up to 6 history +! tapes, for the sake of mods that extend these default mods and may add other history tapes + hist_nhtfrq = 1,1,1,1,1,1,1 + hist_mfilt = 1,1,1,1,1,1,1 + hist_fincl1 = 'TRAFFICFLUX', 'SNOWLIQ:A','SNOWICE:A' +! Add FCO2 because few (if any) tests send this flux to the coupler, so it isn't checked via cpl hist files + hist_fincl1 += 'FCO2' + hist_fincl2 = 'LIT_MET_C_TO_MIC_COP_C', 'LIT_MET_C_TO_MIC_OLI_C', 'LIT_STR_C_TO_MIC_COP_C', 'LIT_STR_C_TO_MIC_OLI_C', + 'MIC_COP_C_TO_SOM_AVL_C', 'MIC_COP_C_TO_SOM_CHEM_C', 'MIC_COP_C_TO_SOM_PHYS_C', + 'MIC_OLI_C_TO_SOM_AVL_C', 'MIC_OLI_C_TO_SOM_CHEM_C', 'MIC_OLI_C_TO_SOM_PHYS_C', + 'SOM_CHEM_C_TO_SOM_AVL_C', 'SOM_PHYS_C_TO_SOM_AVL_C', + 'SOM_AVL_C_TO_MIC_COP_C', 'SOM_AVL_C_TO_MIC_OLI_C', + 'MYC_ECM_C_TO_SOM_AVL_C', 'MYC_ECM_C_TO_SOM_CHEM_C', 'MYC_ECM_C_TO_SOM_PHYS_C', + 'MYC_AM_C_TO_SOM_AVL_C', 'MYC_AM_C_TO_SOM_CHEM_C', 'MYC_AM_C_TO_SOM_PHYS_C' + + hist_fincl3 = 'TOTMYCC', 'SOILC_vr', 'TOTMICC', 'TOTMYCC', 'TOTLITC', 'TOTSOMC', 'TOTLITC_1m', 'TOTSOMC_1m', + 'DYN_COL_SOIL_ADJUSTMENTS_C', 'TOTCOLC', 'TOTECOSYSC', 'LIT_MET_C_vr', 'LIT_STR_C_vr', 'SOM_AVL_C_vr', + 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' + + hist_fincl5 = 'L1_RESP_FRAC_M1_vr', 'L1_RESP_FRAC_M2_vr', 'L2_RESP_FRAC_M1_vr', 'L2_RESP_FRAC_M2_vr', + 'M1_RESP_FRAC_S1_vr', 'M1_RESP_FRAC_S2_vr', 'M1_RESP_FRAC_S3_vr', + 'M2_RESP_FRAC_S1_vr', 'M2_RESP_FRAC_S2_vr', 'M2_RESP_FRAC_S3_vr', + 'S2_RESP_FRAC_S1_vr', 'S3_RESP_FRAC_S1_vr', + 'S1_RESP_FRAC_M1_vr', 'S1_RESP_FRAC_M2_vr', + 'MYC1_RESP_FRAC_S1_vr', 'MYC1_RESP_FRAC_S2_vr', 'MYC1_RESP_FRAC_S3_vr', + 'MYC2_RESP_FRAC_S1_vr', 'MYC2_RESP_FRAC_S2_vr', 'MYC2_RESP_FRAC_S3_vr' + + hist_fincl6 = 'L1_PATHFRAC_M1_vr', 'L1_PATHFRAC_M2_vr', 'L2_PATHFRAC_M1_vr', 'L2_PATHFRAC_M2_vr', + 'M1_PATHFRAC_S1_vr', 'M1_PATHFRAC_S2_vr', 'M1_PATHFRAC_S3_vr', + 'M2_PATHFRAC_S1_vr', 'M2_PATHFRAC_S2_vr', 'M2_PATHFRAC_S3_vr', + 'S2_PATHFRAC_S1_vr', 'S3_PATHFRAC_S1_vr', + 'S1_PATHFRAC_M1_vr', 'S1_PATHFRAC_M2_vr', + 'MYC1_PATHFRAC_S1_vr', 'MYC1_PATHFRAC_S2_vr', 'MYC1_PATHFRAC_S3_vr', + 'MYC2_PATHFRAC_S1_vr', 'MYC2_PATHFRAC_S2_vr', 'MYC2_PATHFRAC_S3_vr' + + hist_fincl7 = 'LIT_MET_HR_M1', 'LIT_MET_HR_M2', 'LIT_STR_HR_M1', 'LIT_STR_HR_M2', + 'MIC_COP_HR_S1', 'MIC_COP_HR_S2', 'MIC_COP_HR_S3', + 'MIC_OLI_HR_S1', 'MIC_OLI_HR_S2', 'MIC_OLI_HR_S3', + 'SOM_AVL_HR_M1', 'SOM_AVL_HR_M2', + + + + use_ssre = .true. + paramfile = '/cluster/projects/nn2806k/elisacw/parameters/clm_params_mimicsplus_netcdf5_11.09.24.nc' + + +soil_decomp_method = 'MIMICSplusAas2023' +hist_fincl1 += 'TOTMYCC', 'SOILC_vr', 'TOTMICC', 'TOTMYCC', 'TOTLITC', 'TOTSOMC', 'TOTLITC_1m', 'TOTSOMC_1m', + 'DYN_COL_SOIL_ADJUSTMENTS_C', 'TOTCOLC', 'TOTECOSYSC', 'LIT_MET_C_vr', 'LIT_STR_C_vr', 'SOM_AVL_C_vr', + 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' + From cd5b564f275afb6dc40306d6857ee521c20d88bf Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 17 Sep 2024 17:32:19 +0200 Subject: [PATCH 07/17] wip balance fix and refactor --- src/biogeochem/CNCStateUpdate1Mod.F90 | 32 +- src/biogeochem/CNFUNMIMICSplusMod.F90 | 91 ++++- src/biogeochem/CNVegNitrogenFluxType.F90 | 6 + .../SoilBiogeochemCarbonFluxType.F90 | 37 +- .../SoilBiogeochemCompetitionMod.F90 | 22 +- ...ilBiogeochemDecompCascadeMIMICSplusMod.F90 | 315 ++++++++++++++++-- .../SoilBiogeochemDecompMod.F90 | 37 +- .../SoilBiogeochemNStateUpdate1Mod.F90 | 8 +- .../SoilBiogeochemNitrogenFluxType.F90 | 9 + 9 files changed, 482 insertions(+), 75 deletions(-) diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90 index 41051d0c39..a59c3b7442 100644 --- a/src/biogeochem/CNCStateUpdate1Mod.F90 +++ b/src/biogeochem/CNCStateUpdate1Mod.F90 @@ -14,7 +14,8 @@ module CNCStateUpdate1Mod use clm_varpar , only : i_litr_min, i_litr_max, i_cwd use pftconMod , only : npcropmin, nc3crop, pftcon use abortutils , only : endrun - use decompMod , only : bounds_type + use clm_varctl , only : iulog + use decompMod , only : bounds_type, subgrid_level_patch use CNVegCarbonStateType , only : cnveg_carbonstate_type use CNVegCarbonFluxType , only : cnveg_carbonflux_type use CropType , only : crop_type @@ -37,6 +38,8 @@ module CNCStateUpdate1Mod public :: CStateUpdate0 public :: CStateUpdate1 !----------------------------------------------------------------------- + character(len=*), parameter, private :: sourcefile = & + __FILE__ contains @@ -272,7 +275,12 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & soilpatch_loop: do fp = 1,num_soilp p = filter_soilp(fp) c = patch%column(p) + if (cs_veg%cpool_patch(p) < -1.0e-09_r8 .or. cs_veg%cpool_patch(p) > 1.0e6_r8) then + write(iulog,*) 'ERROR: cpool_patch=',cs_veg%cpool_patch(p) + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + end if ! phenology: transfer growth fluxes ! @@ -350,7 +358,12 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & check_cpool = cs_veg%cpool_patch(p)- cf_veg%psnsun_to_cpool_patch(p)*dt-cf_veg%psnshade_to_cpool_patch(p)*dt cpool_delta = cs_veg%cpool_patch(p) + if (cs_veg%cpool_patch(p) < -1.0e-09_r8) then + write(iulog,*) 'ERROR: cpool_patch=',cs_veg%cpool_patch(p),cf_veg%availc_patch(p) + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + end if ! maintenance respiration fluxes from cpool cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_xsmrpool_patch(p)*dt @@ -372,7 +385,12 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & !RF Add in the carbon spent on uptake respiration. cs_veg%cpool_patch(p)= cs_veg%cpool_patch(p) - cf_veg%soilc_change_patch(p)*dt - + if (cs_veg%cpool_patch(p) < -1.0e-09_r8 .or. cs_veg%cpool_patch(p) > 1.0e6_r8) then + write(iulog,*) 'ERROR: cpool_patch=',cs_veg%cpool_patch(p),cf_veg%cpool_to_resp_patch(p)*dt,cf_veg%soilc_change_patch(p)*dt,cf_veg%availc_patch(p) + + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + end if ! maintenance respiration fluxes from xsmrpool cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) + cf_veg%cpool_to_xsmrpool_patch(p)*dt cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%leaf_xsmr_patch(p)*dt @@ -403,6 +421,16 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) + cf_veg%cpool_to_leafc_storage_patch(p)*dt cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) + cf_veg%cpool_to_frootc_patch(p)*dt cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) + cf_veg%cpool_to_frootc_storage_patch(p)*dt + + if (cs_veg%cpool_patch(p) < -1.0e-09_r8 .or. cs_veg%cpool_patch(p) > 1.0e6_r8) then + write(iulog,*) 'ERROR: cpool_patch=',cs_veg%cpool_patch(p) + write(iulog,*) 'ERROR: cpool_to_leafc_patch=',cf_veg%cpool_to_leafc_patch(p)*dt + write(iulog,*) 'ERROR: cpool_to_leafc_storage_patch=',cf_veg%cpool_to_leafc_storage_patch(p)*dt + write(iulog,*) 'ERROR: cpool_to_frootc_patch=',cf_veg%cpool_to_frootc_patch(p)*dt + write(iulog,*) 'ERROR: cpool_to_frootc_storage_patch=',cf_veg%cpool_to_frootc_storage_patch(p)*dt + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + end if ! ! For the matrix solution the actual state update comes after the matrix ! multiply in VegMatrix, but the matrix needs to be setup with diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 4532e0a69c..6d0b5988c9 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -486,7 +486,6 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s type(soilbiogeochem_carbonstate_type) , intent(inout) :: soilbiogeochem_carbonstate_inst type(cnfunmimicsplus_type) , intent(inout) :: cnfunmimicsplus_inst - ! LOCAL VARIABLES: integer :: fn ! number of values in pft filter integer :: fp ! lake filter pft index @@ -506,6 +505,8 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s real(r8) :: ndays_off ! number of days to complete leaf offset real(r8) :: frac_ideal_C_use ! How much less C do we use for 'buying' N than that needed to get to the ideal ratio? fraction. real(r8) :: N_acquired + real(r8) :: N_before_corr + real(r8) :: N_bc(1:npath6) real(r8) :: C_spent real(r8) :: leaf_narea ! leaf n per unit leaf area in gN/m2 (averaged across canopy, which is OK for the cost calculation) real(r8) :: sum_n_acquired ! Sum N aquired from one unit of C (unitless) @@ -756,7 +757,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s call calc_myc_roi(decomp_cpools_vr(c,j,i_am_myc),decomp_npools_vr(c,j,i_am_myc) , & decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & - (smin_no3_to_plant_vr(c,j) + smin_nh4_to_plant_vr(c,j)) * dt, am_step , dzsoi_decomp(j),- big_cost, roi_am) + (smin_no3_to_plant_vr(c,j) + smin_nh4_to_plant_vr(c,j)) * dt, am_step , dzsoi_decomp(j),big_cost, roi_am) frac_alloc_ecm=(roi_ecm)/(roi_ecm + roi_am) ! if (crootfr(p,j)>0.0_r8) then n_uptake_myc_frac(p,ecm_step) = n_uptake_myc_frac(p,ecm_step) + frac_alloc_ecm * crootfr(p,j) @@ -912,8 +913,8 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s endif npp_to_spend = npp_remaining(p,imyc) * fixerfrac !put parameter here. ! has to be zeroed since depend on accumula - n_from_paths(p,:,ipano3:ipnmnh4) = 0._r8 !act and nonmyc boths nh4 and no3 - + n_from_paths(p,:,:) = 0.0_r8 !act and nonmyc boths nh4 and no3 + npp_frac_paths(p,:,:) = 0.0_r8 ! Calculate Integrated Resistance OF WHOLE SOIL COLUMN sum_n_acquired = 0.0_r8 @@ -956,7 +957,12 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s sum_n_acquired= sum_n_acquired + npp_frac_paths(p,j,ipfix)/costs_paths(p,j,ipfix) end if end do - + if (sum_n_acquired>0.0_r8) then + total_N_resistance = max(1.0_r8/sum_n_acquired,1.0_r8/big_cost) + else + total_N_resistance = 1.0_r8/big_cost + endif + free_n_retrans = 0.0_r8 ! Calculate appropriate degree of retranslocation if(leafc(p).gt.0.0_r8.and.litterfall_n_step(p,imyc)* fixerfrac>0.0_r8.and.ivt(p) 0.0_r8) then if (imyc == ecm_step) then + sminno3_to_ecm_vr_patch(p,j) = 0.0_r8 + sminnh4_to_ecm_vr_patch(p,j) = 0.0_r8 call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_ecm_myc),decomp_npools_vr(c,j,i_ecm_myc), & decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & @@ -1072,6 +1093,8 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s c_somp2soma_vr_patch(p,j), c_somc2soma_vr_patch(p,j), n_somp2ecm_vr_patch(p,j), n_somc2ecm_vr_patch(p,j)) ! update npp_to_nonmyc with cost else + sminno3_to_am_vr_patch(p,j) = 0.0_r8 + sminnh4_to_am_vr_patch(p,j) = 0.0_r8 call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_am_myc),decomp_npools_vr(c,j,i_am_myc), & decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & @@ -1081,9 +1104,27 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s sminno3_to_am_vr_patch(p,j), sminnh4_to_am_vr_patch(p,j), & c_am_resp_vr_patch(p,j), c_am_growth_vr_patch(p,j), n_am_growth_vr_patch(p,j)) endif + if (sminno3_to_am_vr_patch(p,j) + sminno3_to_am_vr_patch(p,j) + & + sminnh4_to_ecm_vr_patch(p,j) + sminnh4_to_ecm_vr_patch(p,j) + & + n_from_paths(p,j,ipnmno3) + n_from_paths(p,j,ipnmnh4) > sminn_layer_step(p,j,imyc) ) then + write(iulog,*) 'ERROR: myc_type is=',imyc, N_before_corr - sum(n_from_paths(p,j,ipano3:ipnmnh4)) + write(iulog,*) 'ERROR: N before corrections=',N_before_corr, N_bc + write(iulog,*) 'ERROR: More N acquired before correcting for sminn diff: ', sum(n_from_paths(p,j,ipano3:ipnmnh4)), n_from_paths(p,j,:) + write(iulog,*) 'ERROR: More cost_paths: ', N_before_corr,costs_paths(p,j,ipano3:ipnmnh4) + write(iulog,*) 'ERROR: More cost_paths: ', '0.0',costs_paths(p,j,ipano3:ipnmnh4) + write(iulog,*) 'ERROR: C_spent and npp: ', C_spent,npp_to_paths(p,j,ipano3:ipnmnh4) + write(iulog,*) 'ERROR: Cpent diff:', C_spent - sum(npp_to_paths(p,j,ipano3:ipnmnh4)) + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + endif npp_to_paths(p,j,ipnmno3) = n_from_paths(p,j,ipnmno3) * costs_paths(p,j,ipnmno3) npp_to_paths(p,j,ipnmnh4) = n_from_paths(p,j,ipnmnh4) * costs_paths(p,j,ipnmnh4) + if ( sum(npp_to_paths(p,j,ipano3:ipnmnh4)) > C_spent) then + write(iulog,*) 'ERROR: C spent before correcting for sminn diff: ', C_spent ,npp_to_paths(p,j,ipano3:ipnmnh4) + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + endif ! switch units to gN/m3/s for use in other routines sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) @@ -1232,21 +1273,36 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s npp_Nactive_nh4(p) = sum(npp_paths_acc(p,1:nmyc,ipanh4)) / dt npp_Nnonmyc_no3(p) = sum(npp_paths_acc(p,1:nmyc,ipnmno3)) / dt npp_Nnonmyc_nh4(p) = sum(npp_paths_acc(p,1:nmyc,ipnmnh4)) / dt - + npp_Nfix(p) = sum(npp_paths_acc(p,1:nmyc,ipfix)) /dt npp_Nactive(p) = npp_Nactive_no3(p) + npp_Nactive_nh4(p) + npp_Nnonmyc_no3(p) + npp_Nnonmyc_nh4(p) npp_Nnonmyc(p) = npp_Nnonmyc_no3(p) + npp_Nnonmyc_nh4(p) - + npp_Nretrans(p) = sum(npp_retrans_acc(p,1:nmyc))/dt + !---------------------------Extra Respiration Fluxes--------------------! - soilc_change(p) = sum(npp_paths_acc(p,1:nmyc,ipano3)) + sum(npp_paths_acc(p,1:nmyc,ipanh4)) + sum(npp_paths_acc(p,1:nmyc,ipnmno3)) & - + sum(npp_paths_acc(p,1:nmyc,ipnmno3)) + sum(npp_paths_acc(p,1:nmyc,ipnmnh4)) & - + sum(npp_paths_acc(p,1:nmyc,ipfix)) / dt !ECW thats it right?, retrans is 0? + soilc_change(p) = npp_Nactive(p) + npp_Nfix(p) + npp_Nretrans(p) soilc_change(p) = soilc_change(p) + burned_off_carbon / dt npp_burnedoff(p) = burned_off_carbon/dt npp_Nuptake(p) = soilc_change(p) ! how much carbon goes to growth of tissues? - npp_growth(p) = (Nuptake(p)- free_retransn_to_npool(p))*plantCN(p)+(excess_carbon_acc/dt) !does not include gresp, since this is calculated from growth + npp_growth(p) = (Nuptake(p)- free_retransn_to_npool(p))*plantCN(p)+(excess_carbon_acc/dt) !does not include gresp, since this is calculated from growth + if (availc(p) <= 0.0_r8 .and. soilc_change(p) > 0.0_r8) then + write(iulog,*) 'ERROR: availc(p): ', availc(p) + write(iulog,*) 'ERROR: soilc_change(p): ', soilc_change(p) + write(iulog,*) 'ERROR: free_retransn_to_npool(p) is negative: ', free_retransn_to_npool(p) + write(iulog,*) 'ERROR:burned_off_carbon / dt: ',burned_off_carbon / dt + write(iulog,*) 'ERROR: excess_carbon_acc: ', sum(npp_uptake(p,1:nmyc)) + write(iulog,*) 'ERROR: npp_Nretrans(p): ', npp_Nretrans(p) + write(iulog,*) 'npp_growth(p): ',npp_growth(p) + + do ipath = 1,npath6 + write(iulog,*) 'ERROR nppaths_ecm:',ipath, npp_paths_acc(p,1,ipath) + write(iulog,*) 'ERROR nppaths_am:',ipath, npp_paths_acc(p,1,ipath) + enddo + call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & + msg= errMsg(sourcefile, __LINE__)) + endif - if (npp_growth(p) < -10000._r8 .or. npp_growth(p) > 10000._r8) then + if (npp_growth(p) < -1.0e-7_r8 .or. npp_growth(p) > 10000._r8) then write(iulog,*) 'ERROR: Nuptake(p) is negative: ', Nuptake(p) write(iulog,*) 'ERROR: npp_Nuptake(p) is negative: ', npp_Nuptake(p) write(iulog,*) 'ERROR: free_retransn_to_npool(p) is negative: ', free_retransn_to_npool(p) @@ -1257,12 +1313,11 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & msg= errMsg(sourcefile, __LINE__)) endif - if (npp_Nuptake(p) > 10000._r8) then - write(iulog,*) 'ERROR: npp_N negative: ', npp_Nuptake(p) + if (availc(p) - npp_Nuptake(p) - npp_growth(p) < 0._r8) then + write(iulog,*) 'ERROR: balance Cfun is negative: ',availc(p), npp_Nuptake(p),npp_growth(p),excess_carbon_acc/dt,npp_Nretrans(p) call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & msg= errMsg(sourcefile, __LINE__)) endif - !-----------------------Diagnostic Fluxes------------------------------! if(availc(p).gt.0.0_r8)then !what happens in the night? nuptake_npp_fraction_patch(p) = npp_Nuptake(p)/availc(p) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index 08b92dd534..1d9bfd515c 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -272,6 +272,12 @@ module CNVegNitrogenFluxType real(r8), pointer :: cost_nretrans_patch (:) ! Average cost of retranslocation (gN/m2/s) real(r8), pointer :: nuptake_npp_fraction_patch (:) ! frac of npp spent on N acquisition (gN/m2/s) + real(r8), pointer :: sminno3_nonmyc_to_plant_col(:,:) ! No3 flux from min soil to plant (only nonmyc pathway can do this) + real(r8), pointer :: sminnh4_nonmyc_to_plant_col(:,:) ! NH4 flux from min soil to plant (only nonmyc pathway can do this) + real(r8), pointer :: no3_myc_to_plant_col(:,:) ! No3 flux from min soil to plant by mycorrhiza + real(r8), pointer :: nh4_myc_to_plant_col(:,:) ! NH4 flux from min soil to plant by mycorrhiza + + ! Matrix solution variables contains diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index 55205207c4..5a58e8278a 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -61,6 +61,14 @@ module SoilBiogeochemCarbonFluxType real(r8), pointer :: fates_litter_flux (:) ! (gC/m2/s) A summary of the total litter ! flux passed in from FATES. ! This is a diagnostic for balance checks only + real(r8), pointer :: c_am_resp_vr_col(:,:) ! carbon respiration flux for AM mycorrhiza + real(r8), pointer :: c_ecm_resp_vr_col(:,:) ! carbon respiration flux for ECM mycorrhiza + real(r8), pointer :: c_am_growth_vr_col(:,:) ! carbon growth flux for AM mycorrhiza + real(r8), pointer :: c_ecm_growth_vr_col(:,:) ! carbon growth flux for ECM mycorrhiza + + real(r8), pointer :: c_ecm_enz_vr_col(:,:) ! carbon enzyme production flux for ECM mycorrhiza + real(r8), pointer :: c_somc2soma_vr_col(:,:) ! carbon release from mining from somc pool + real(r8), pointer :: c_somp2soma_vr_col(:,:) ! carbon release from mining from somp pool contains @@ -172,6 +180,15 @@ subroutine InitAllocate(this, bounds) allocate(this%litr_lig_c_to_n_col(begc:endc)) this%litr_lig_c_to_n_col(:)= 0._r8 + + allocate(this%c_am_resp_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_am_resp_vr_col = spval + allocate(this%c_ecm_resp_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_ecm_resp_vr_col = spval + allocate(this%c_am_growth_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_am_growth_vr_col = spval + allocate(this%c_ecm_growth_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_ecm_growth_vr_col = spval + + allocate(this%c_ecm_enz_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_ecm_enz_vr_col = spval + allocate(this%c_somc2soma_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_somc2soma_vr_col = spval + allocate(this%c_somp2soma_vr_col(begc:endc,1:nlevdecomp_full)) ; this%c_somp2soma_vr_col = spval end subroutine InitAllocate @@ -729,6 +746,14 @@ subroutine SetValues ( this, num_column, filter_column, value_column) do fi = 1,num_column i = filter_column(fi) this%hr_vr_col(i,j) = value_column + + this%c_am_resp_vr_col(i,j) = value_column + this%c_ecm_resp_vr_col(i,j) = value_column + this%c_am_growth_vr_col(i,j) = value_column + this%c_ecm_growth_vr_col(i,j) = value_column + this%c_ecm_enz_vr_col(i,j) = value_column + this%c_somc2soma_vr_col(i,j) = value_column + this%c_somp2soma_vr_col(i,j) = value_column end do end do @@ -751,7 +776,7 @@ subroutine Summary(this, bounds, & num_bgc_soilc, filter_bgc_soilc, num_soilp, filter_soilp, & soilbiogeochem_decomp_cascade_ctransfer_col, & soilbiogeochem_cwdc_col, soilbiogeochem_cwdn_col, & - leafc_to_litter_patch, frootc_to_litter_patch) + leafc_to_litter_patch, frootc_to_litter_patch, c_myc_resp) ! ! !DESCRIPTION: ! On the radiation time step, carbon summary calculations @@ -773,6 +798,7 @@ subroutine Summary(this, bounds, & real(r8), intent(in), optional :: leafc_to_litter_patch(:) real(r8), intent(in), optional :: frootc_to_litter_patch(:) + real(r8), intent(in), optional :: c_myc_resp(bounds%begc:,1:) ! ! !LOCAL VARIABLES: integer :: c,j,k,l,p @@ -826,6 +852,15 @@ subroutine Summary(this, bounds, & end do end do + ! we need to explicitly add mycorrhizal respiration, since that is due to the flux to plant and not part of the cascade. + if (decomp_method == mimicsplus_decomp) then + do j = 1,nlevdecomp + do fc = 1,num_bgc_soilc + c = filter_bgc_soilc(fc) + this%hr_vr_col(c,j) = & + this%hr_vr_col(c,j) + + end do + end do ! add up all vertical transport tendency terms and calculate total som leaching loss as the sum of these do l = 1, ndecomp_pools do fc = 1,num_bgc_soilc diff --git a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 index dbe172410f..b86cdd2592 100644 --- a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 @@ -19,6 +19,7 @@ module SoilBiogeochemCompetitionMod use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type use SoilBiogeochemNitrogenUptakeMod , only : SoilBiogeochemNitrogenUptake use ColumnType , only : col + use PatchType , only : patch use CNVegstateType , only : cnveg_state_type use CNVegCarbonStateType , only : cnveg_carbonstate_type use CNVegCarbonFluxType , only : cnveg_carbonflux_type @@ -216,7 +217,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu ! ! !LOCAL VARIABLES: integer :: c,p,l,pi,j,k ! indices - integer :: fc ! filter column index + integer :: fc,fp ! filter column index, filter patch index logical :: local_use_fun ! local version of use_fun real(r8) :: amnf_immob_vr ! actual mineral N flux from immobilization (gN/m3/s) real(r8) :: n_deficit_vr ! microbial N deficit, vertically resolved (gN/m3/s) @@ -246,6 +247,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu real(r8) :: residual_smin_no3(bounds%begc:bounds%endc) real(r8) :: residual_plant_ndemand(bounds%begc:bounds%endc) real(r8) :: sminn_to_plant_new(bounds%begc:bounds%endc) + real(r8) :: unmet_plant_demand_no3(bounds%begc:bounds%endc,1:nlevdecomp) ! plant demand that has not been met by sminno3 uptake. + real(r8) :: unmet_plant_demand_nh4(bounds%begc:bounds%endc,1:nlevdecomp) ! plant demand that has not been met by sminnh4 uptake. !----------------------------------------------------------------------- associate( & @@ -297,6 +300,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu sminn_to_plant_new(bounds%begc:bounds%endc) = 0._r8 local_use_fun = (use_fun .or. decomp_method == mimicsplus_decomp) + unmet_plant_demand_no3(bounds%begc:bounds%endc,1:nlevdecomp) = 0._r8 + unmet_plant_demand_nh4(bounds%begc:bounds%endc,1:nlevdecomp) = 0._r8 if_nitrif: if (.not. use_nitrif_denitrif) then ! init sminn_tot @@ -393,16 +398,6 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu call t_stopf( 'CNFUN' ) end if - if ( decomp_method == mimicsplus_decomp ) then - call t_startf( 'CNFUNMIMICSplus' ) - call CNFUNMIMICSplus(bounds,num_bgc_soilc,filter_bgc_soilc,num_bgc_vegp,filter_bgc_vegp,waterstatebulk_inst, & - waterfluxbulk_inst,temperature_inst,soilstate_inst,cnveg_state_inst,cnveg_carbonstate_inst,& - cnveg_carbonflux_inst,cnveg_nitrogenstate_inst,cnveg_nitrogenflux_inst ,& - soilbiogeochem_nitrogenflux_inst,soilbiogeochem_carbonflux_inst,canopystate_inst, & - soilbiogeochem_nitrogenstate_inst, soilbiogeochem_carbonstate_inst, cnfunmimicsplus_inst) - call t_stopf( 'CNFUNMIMICSplus' ) - end if - ! sum up N fluxes to plant do j = 1, nlevdecomp do fc=1,num_bgc_soilc @@ -767,6 +762,11 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu end do end do + ! do j = 1, nlevdecomp + ! do fp = 1, num_bgc_vegp + ! p = filter_bgc_vegp(fp) + ! c = patch%column(p) + ! if (plant_ndemand(c)*nuptake_prof(c,j) > ) if ( use_fun ) then call t_startf( 'CNFUN' ) call CNFUN(bounds,num_bgc_soilc,filter_bgc_soilc,num_bgc_vegp,filter_bgc_vegp,waterstatebulk_inst,& diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 0c5b0205d9..cc3461f7ba 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -1965,7 +1965,7 @@ subroutine calc_myc_roi(cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_somc, & if (cpool_myc > 0.0_r8) then roi = (fn_smin2myc + fn_mining_somc + fn_mining_somp) / (params_inst%mimicsplus_k_myc_som / secsphr ) * & params_inst%mimicsplus_mge_ecm / cpool_myc - if (roi == 0.0_r8) then + if (roi <= 0.0_r8) then roi = 1.0_r8/big_roi end if else @@ -1975,11 +1975,11 @@ subroutine calc_myc_roi(cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_somc, & if (cpool_myc > 0.0_r8) then roi = fn_smin2myc/ (params_inst%mimicsplus_k_myc_som / secsphr ) * & params_inst%mimicsplus_mge_am / cpool_myc - if (roi == 0.0_r8) then + if (roi <= 0.0_r8) then roi = 1.0_r8/big_roi end if else - roi = big_roi + roi = 1.0_r8/big_roi endif endif @@ -1994,8 +1994,9 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ ! Mycorrhizal pools have ac constant C:N ratio, these are fullfilled by uptake fluxes from inorganic nitrogen (to EcM & AM), and mining (to EcM). ! The Nitrogen that is left after C:N ratio is fullfilled can go to vegetation (uptake - demand equation) ! Under limited nitrogen soil ocnditions, the carbon use efficiency can be lowered + use clm_time_manager, only: get_step_size_real ! !ARGUMENTS: - real(r8), intent(in) :: fc_veg2myc ! Carbon flux from plant to mycorrhiza + real(r8), intent(in) :: fc_veg2myc ! Carbon flux from plant to mycorrhiza [gC/m2] real(r8), intent(in) :: cpool_myc ! Carbon pool of mycorrhiza [gC/m3] () real(r8), intent(in) :: npool_myc ! Nitrogen pool of mycorrhiza [gN/m3] () real(r8), intent(in) :: cpool_somp ! physically protected SOM pool [gC/m3] @@ -2016,16 +2017,19 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ real(r8), parameter :: f_enz = 0.1_r8 ! [-]Fraction of C from vegetation to EcM, that goes into SOMa for mining real(r8), parameter :: f_growth = 0.5_r8 ! [-] Fraction of mycorrhizal N uptake that needs to stay within the fungi (not given to plant) real(r8), parameter :: small_Value = 1.0e-6_r8 + real(r8) :: dt real(r8) :: fn_myc2veg ! nitrogen fluxes mycorrhiza to vegetation - real(r8) :: fn_smin2myc ! nitrogen flux from mineral soil to myc [gN/m2/s] - real(r8) :: fc_somp2soma,fc_somc2soma ! carbon fluxes som to som due to mining [gC/m2/s] - real(r8) :: fn_mining_somc,fn_mining_somp ! nitrogen fluxes to som to myc (mining + scavenging) [gN/m2/s] + real(r8) :: fn_smin2myc ! nitrogen flux from mineral soil to myc [gN/m3/s] + real(r8) :: fc_somp2soma,fc_somc2soma ! carbon fluxes som to som due to mining [gC/m3/s] + real(r8) :: fn_mining_somc,fn_mining_somp ! nitrogen fluxes to som to myc (mining + scavenging) [gN/m3/s] real(r8) :: N_demand_myc ![gN/m3 h] real(r8) :: N_uptake_myc ![gN/m3 h] real(r8) :: c_use_eff ! carbon use efficiency [-] + dt=get_step_size_real() + if (myc_type == 1) then c_use_eff = params_inst%mimicsplus_mge_ecm else @@ -2033,7 +2037,7 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ endif fn_smin2myc = (params_inst%mimicsplus_vmax_myc / secphr) * sminn / dz * & - (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) !ECW double check thats ecphr is correct here + (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) ! Initialize mining rates fc_somp2soma = 0.0_r8 @@ -2041,7 +2045,7 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ fn_mining_somp = 0.0_r8 fn_mining_somc = 0.0_r8 if (myc_type == 1) then - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,fc_somp2soma,fn_mining_somp) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,fc_somp2soma,fn_mining_somp) ! gN/m3/s call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_myc,fc_somc2soma,fn_mining_somc) endif @@ -2050,7 +2054,7 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ if (myc_type == 1) then !fn_myc_veg = (fn_smin2myc + fn_somc2myc_ecm + fn_somp2myc_ecm) - c_use_eff * fc_veg2myc * (1.0_r8 - f_enz) / params_inst%mimicsplus_cn_myc N_uptake_myc = fn_smin2myc + fn_mining_somc + fn_mining_somp - N_demand_myc = c_use_eff * fc_veg2myc * (1.0_r8 - f_enz) / params_inst%mimicsplus_cn_myc + N_demand_myc = c_use_eff * fc_veg2myc * (1.0_r8 - f_enz) / params_inst%mimicsplus_cn_myc / dz / dt !gC/m3/s if (N_uptake_myc > N_demand_myc) then fn_myc2veg = N_uptake_myc - N_demand_myc else @@ -2070,15 +2074,15 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ if (fn_myc2veg > small_Value) then if (sminfrc_no3 > small_Value) then - cost_myc_no3 = fc_veg2myc / (fn_myc2veg) / sminfrc_no3 + cost_myc_no3 = fc_veg2myc / (fn_myc2veg) / sminfrc_no3 / dz / dt if ( (1.0_r8 - sminfrc_no3)> small_Value) then - cost_myc_nh4 = fc_veg2myc / (fn_myc2veg) / (1.0_r8 - sminfrc_no3) + cost_myc_nh4 = fc_veg2myc / (fn_myc2veg) / (1.0_r8 - sminfrc_no3) / dz / dt else cost_myc_nh4 = big_cost end if else cost_myc_no3 = big_cost - cost_myc_nh4 = fc_veg2myc / (fn_myc2veg) / (1.0_r8 - sminfrc_no3) + cost_myc_nh4 = fc_veg2myc / (fn_myc2veg) / (1.0_r8 - sminfrc_no3) / dz / dt endif else cost_myc_no3 = big_cost @@ -2110,13 +2114,18 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_myc, fc_som2soma ! LOCAL VARIABLES: real(r8) :: secphr = 60.0_r8 * 60.0_r8 - real(r8), parameter :: small_flux = 1.e-14_r8 + real(r8), parameter :: small_value = 1.e-10_r8 ! SOM carbon flux fc_som2soma = (params_inst%mimicsplus_k_mo / secphr) * dz * cpool_myc * cpool_som ! Nitrogen mining flux - if (cpool_myc > small_flux) then + if (fc_som2soma > small_value) then + if (npool_myc > small_value) then fn_mining_som = fc_som2soma * (npool_myc / cpool_myc ) + else + fn_mining_som = 0.0_r8 + fc_som2soma = 0.0_r8 + endif else fn_mining_som = 0.0_r8 fc_som2soma = 0.0_r8 @@ -2154,7 +2163,7 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, real(r8), intent(in) :: dz ! layer thickness [m] ! FUN fluxes - real(r8), intent(inout) :: fc_veg2myc_no3 ! Carbon flux from plant to mycorrhiza [gC/m3] + real(r8), intent(inout) :: fc_veg2myc_no3 ! Carbon flux from plant to mycorrhiza [gC/m2] real(r8), intent(inout) :: fc_veg2myc_nh4 ! Carbon flux from plant to mycorrhiza [gC/m2] real(r8), intent(inout) :: no3_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NO3) [gN/m3] real(r8), intent(inout) :: nh4_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NH4) [gN/m3] @@ -2300,7 +2309,12 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, fc_veg2myc=fc_veg2myc_no3 + fc_veg2myc_nh4 if (myc_type == 1) then ! EcM call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp) - call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) + if ( cpool_somc < 0.0_r8 .or. cpool_myc < 0.0_r8 .or. & + npool_myc < 0.0_r8 .or. cpool_somp < 0.0_r8) then + write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if N_demand_myc = c_use_eff * (1 - f_enz) * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt N_uptake_myc = fn_smin2myc + l_fn_mining_somp + l_fn_mining_somc if (N_uptake_myc > N_demand_myc) then @@ -2358,6 +2372,7 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, fnh4_myc2veg = fn_myc2veg * (1 - l_no3_frac) no3_unpaid = fno3_myc2veg * dz * dt - no3_from_myc ! plants did not actually get all the promised nitrogen (NO3 / NH4) nh4_unpaid = fnh4_myc2veg * dz * dt - nh4_from_myc + !if (no3_unpaid + nh4_unpaid < 0) then ! message = "N flux from AM mycorrhiza to plant is greater than mycorrhiza can actually give to the plant" ! call endrun(msg=message) @@ -2366,10 +2381,272 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, no3_from_myc = fno3_myc2veg * dz * dt ! if we can give more nitrogen than we promised just give it nh4_from_myc = fnh4_myc2veg * dz * dt !endif - + if ( no3_from_myc < 0.0_r8 .or. nh4_from_myc < 0.0_r8 & + ) then + write(iulog,*) 'ERROR: type,no3_from_myc, nh4_from_myc',myc_type, no3_from_myc, nh4_from_myc, fc_veg2myc_no3,fc_veg2myc_nh4, l_no3_frac, l_fn_mining_somp,l_fn_mining_somc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if end subroutine fun_fluxes_myc_update1 - + + subroutine fun_fluxes_myc_update2 (cpool_myc, npool_myc, cpool_somp, cpool_soma,cpool_somc, & + npool_somp, npool_somc, sminn, sminfrc_no3, myc_type, dz, & + fc_veg2myc_no3, fc_veg2myc_nh4, & + no3_from_nonmyc,nh4_from_nonmyc, & + no3_from_myc, nh4_from_myc, & + fn_smin_no3_2myc, fn_smin_nh4_2myc, c_myc_resp,c_myc_growth,n_myc_growth,c_ecm_enz, & + fc_somp2soma, fc_somc2soma, fn_mining_somp,fn_mining_somc) + + ! ! DESCRIPTION: + ! Updating Nitrogen and Carbon fluxes into mycorrhizal pools, to let them grow + ! + ! ! USES: + use clm_time_manager, only: get_step_size_real + + ! + ! !ARGUMENTS: + + real(r8), intent(in) :: cpool_myc ! Carbon pool of mycorrhiza [gC/m3] + real(r8), intent(in) :: npool_myc ! Nitrogen pool of mycorrhiza [gN/m3] + real(r8), intent(in) :: cpool_somp ! physically protected SOM pool [gC/m3] + real(r8), intent(in) :: cpool_soma ! available SOM pool [gC/m3] + real(r8), intent(in) :: cpool_somc ! chemically protected SOM pool [gC/m3] + real(r8), intent(in) :: npool_somp ! physically protected SOM pool [gN/m3] + real(r8), intent(in) :: npool_somc ! chemically protected SOM pool [gN/m3] + real(r8), intent(in) :: sminn ! soil mineral nitrogen (NO3+NH4) [gN/m2] + real(r8), intent(in) :: sminfrc_no3 ! fraction of soil mineral nitrogen NO3 [-] + integer, intent(in) :: myc_type ! type of mycorrhiza EcM=1, AM=2 [-] + real(r8), intent(in) :: dz ! layer thickness [m] + + ! FUN fluxes + real(r8), intent(inout) :: fc_veg2myc_no3 ! Carbon flux from plant to mycorrhiza [gC/m2] + real(r8), intent(inout) :: fc_veg2myc_nh4 ! Carbon flux from plant to mycorrhiza [gC/m2] + real(r8), intent(inout) :: no3_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NO3) [gN/m3] + real(r8), intent(inout) :: nh4_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NH4) [gN/m3] + real(r8), intent(inout) :: no3_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NO3) [gN/m3] + real(r8), intent(inout) :: nh4_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NH4) [gN/m3] + + real(r8), intent(inout) :: fn_smin_no3_2myc ! nitrogen flux from inorganic NO3 pool to mycorrhiza [gN/m2] + real(r8), intent(inout) :: fn_smin_nh4_2myc ! nitrogen flux from inorganic NH4 pool to mycorrhiza [gN/m2] + + ! Mycorrhiza internal fluxes + real(r8), intent(inout) :: c_myc_resp ! carbon respiration flux for AM mycorrhiza [gC/m3/s] + real(r8), intent(inout) :: c_myc_growth ! carbon growth flux for AM mycorrhiza [gC/m3/s] + real(r8), intent(inout) :: n_myc_growth ! nitrogen growth flux for AM mycorrhiza [gN/m3/s] + real(r8), intent(inout), optional :: c_ecm_enz ! carbon enzyme production flux for ECM mycorrhiza [gC/m3/s] + + ! Mining fluxes + real(r8), intent(inout), optional :: fc_somp2soma ! carbon fluxes somp to soma due to mining [gC/m3/s] + real(r8), intent(inout), optional :: fc_somc2soma ! carbon fluxes somc to soma due to mining [gC/m3/s] + real(r8) ,intent(inout), optional :: fn_mining_somp ! nitrogen fluxes to somp to myc (mining + scavenging) [gN/m3/s] + real(r8) ,intent(inout), optional :: fn_mining_somc ! nitrogen fluxes to somc to myc (mining + scavenging) [gN/m3/s] + + ! LOCAL VARIABLES + real(r8) :: secphr = 60.0_r8 * 60.0_r8 + real(r8) :: dt ! timestep size (seconds) + real(r8), parameter :: f_enz = 0.1_r8 ! [-]Fraction of C from vegetation to EcM, that goes into SOMa for mining + real(r8), parameter :: f_growth = 0.5_r8 ! [-] Fraction of mycorrhizal N uptake that needs to stay within the fungi (not given to plant) + real(r8) :: fc_veg2myc ! carbon flux vegetation to mycorrhiza [] + real(r8) :: fn_myc2veg ! nitrogen fluxes mycorrhiza to vegetation [gN/m3/s] + real(r8) :: l_c_ecm_enz, l_fc_somp2soma, l_fc_somc2soma, l_fn_mining_somp, l_fn_mining_somc !locals of optional args + real(r8) :: N_uptake_myc ! [gN/m3/s] + real(r8) :: N_demand_myc ! [gN/m3/s] + real(r8) :: c_use_eff ! carbon use efficiency [-] + real(r8) :: frac_no3_myc, frac_no3_nonmyc ! [-] + real(r8) :: fn_smin2myc, fno3_myc2veg,fnh4_myc2veg ! local fluxes for balancing [gN/m3/s] + real(r8) :: no3_unpaid, nh4_unpaid ! nitrogen that did not actually reach the plant [gN/m2] + real(r8) :: smin_overflow ! How much N mycorrhiza and non mycorrhiza promised to take out of soil and give to plant + real(r8) :: l_no3_frac + real(r8), parameter :: small_value =1.0e-7_r8 + + character(len=256) :: message + + dt = get_step_size_real() + + ! If statements check, if mining is happening. Mining includes: C Enzymes production flux from EcM, + ! C fluxes from SOMp and c to SOMa, and N fluxes from SOMp and c to EcM. + ! If no mining occurs eg. only AM is present those fluxes are set to 0. + if (present(c_ecm_enz)) then + l_c_ecm_enz = c_ecm_enz + else + l_c_ecm_enz = 0.0_r8 + end if + + if (present(fc_somp2soma)) then + l_fc_somp2soma = fc_somp2soma + else + l_fc_somp2soma = 0.0_r8 + end if + + if (present(fc_somc2soma)) then + l_fc_somc2soma = fc_somc2soma + else + l_fc_somc2soma = 0.0_r8 + end if + + if (present(fn_mining_somp)) then + l_fn_mining_somp = fn_mining_somp + else + l_fn_mining_somp = 0.0_r8 + end if + + if (present(fn_mining_somc)) then + l_fn_mining_somc = fn_mining_somc + else + l_fn_mining_somc = 0.0_r8 + end if + + ! Initialize carbon use efficiencies + if (myc_type == 1) then + c_use_eff = params_inst%mimicsplus_mge_ecm + else + c_use_eff = params_inst%mimicsplus_mge_am + endif + + ! Get no3/total N fraction + if (no3_from_myc + nh4_from_myc > 0.0_r8) then + frac_no3_myc = no3_from_myc / (no3_from_myc + nh4_from_myc) + else + frac_no3_myc = 1.0_r8 + end if + if (no3_from_nonmyc + nh4_from_nonmyc > 0.0_r8) then + frac_no3_nonmyc = no3_from_nonmyc / (no3_from_nonmyc + nh4_from_nonmyc) + else + frac_no3_nonmyc = 1.0_r8 + end if + + ! Soil mineral nitrogen flux to mycorrhiza, split into NO3 and NH4 + fn_smin2myc = (params_inst%mimicsplus_vmax_myc / secphr) * sminn * & + (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) * dt ! multiplied by dt to get it in same units as no3_from_nonmyc + fn_smin_no3_2myc = fn_smin2myc * sminfrc_no3 + fn_smin_nh4_2myc = fn_smin2myc * (1.0_r8 - sminfrc_no3) + if (sminn * sminfrc_no3 <= small_value) then + fn_smin_no3_2myc = 0.0_r8 + no3_from_nonmyc = 0.0_r8 + else + ! If there is not enough nitrogen in the soil mineral, NO3 and NH4 + if (fn_smin_no3_2myc + no3_from_nonmyc > sminn * sminfrc_no3) then + smin_overflow = (fn_smin_no3_2myc + no3_from_nonmyc) - sminn * sminfrc_no3! NO3 that is actually in soil - + fn_smin_no3_2myc = fn_smin_no3_2myc - smin_overflow * fn_smin_no3_2myc / (sminn * sminfrc_no3 + smin_overflow ) ! mycorrhiza limit uptake from inorganic N pools + no3_from_nonmyc = no3_from_nonmyc - smin_overflow * no3_from_nonmyc / (sminn * sminfrc_no3 + smin_overflow) ! non mycorrhiza limit uptake from inorganic N pools + if (& + no3_from_nonmyc < 0.0_r8 .or. fn_smin_no3_2myc < 0.0_r8) then + write(iulog,*) 'ERROR: type,myc, nonmyc, sminno3', myc_type, fn_smin_no3_2myc, no3_from_nonmyc, sminn *sminfrc_no3 - smin_overflow, sminfrc_no3 * sminn, fn_smin2myc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + endif + end if + if (sminn *(1.0_r8 - sminfrc_no3) <= small_value) then + nh4_from_nonmyc = 0.0_r8 + fn_smin_nh4_2myc = 0.0_r8 + else + if (fn_smin_nh4_2myc + nh4_from_nonmyc > sminn * (1.0_r8 - sminfrc_no3)) then + smin_overflow = (fn_smin_nh4_2myc + nh4_from_nonmyc) - sminn * (1.0_r8 - sminfrc_no3) + fn_smin_nh4_2myc = fn_smin_nh4_2myc - smin_overflow * fn_smin_nh4_2myc / (sminn * (1.0_r8 - sminfrc_no3) + smin_overflow) + nh4_from_nonmyc = nh4_from_nonmyc - smin_overflow * nh4_from_nonmyc / (sminn * (1.0_r8 - sminfrc_no3) + smin_overflow) + if ( & + nh4_from_nonmyc < 0.0_r8 .or. fn_smin_nh4_2myc < 0.0_r8) then + write(iulog,*) 'ERROR: type,myc, nonmyc, sminnh4', myc_type, fn_smin_nh4_2myc, nh4_from_nonmyc, sminn * (1.0_r8 - sminfrc_no3) - smin_overflow, (1.0_r8 - sminfrc_no3) * sminn, fn_smin2myc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + endif + endif + + + + ! use new fraction and sminn if they got limited + fn_smin2myc = (fn_smin_no3_2myc + fn_smin_nh4_2myc) /dz /dt ! put it back to gN/m3/s to be consistent with mining fluxes + if(fn_smin2myc > 0.0_r8) then + l_no3_frac = fn_smin_no3_2myc / fn_smin2myc + else + l_no3_frac = 1.0_r8 + endif + + fc_veg2myc=fc_veg2myc_no3 + fc_veg2myc_nh4 + if (myc_type == 1) then ! EcM + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) + if ( cpool_somc < 0.0_r8 .or. cpool_myc < 0.0_r8 .or. & + npool_myc < 0.0_r8 .or. cpool_somp < 0.0_r8) then + write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + N_demand_myc = c_use_eff * (1 - f_enz) * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt + N_uptake_myc = fn_smin2myc + l_fn_mining_somp + l_fn_mining_somc + if (N_uptake_myc > N_demand_myc) then + fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg + n_myc_growth = N_demand_myc ! How much N the need to grow + l_c_ecm_enz = fc_veg2myc * f_enz + ! we add the enzymes here into the EcM pool because we first took them away, but now add them again + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + l_c_ecm_enz + ! enzyme flux will go to soma pool in the next update routine + c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow + else ! less N in soil, so we limit N flux to vegetaion and mycorrhiza N demand so their sum is equal to N uptake + fn_myc2veg = (1-f_growth) * N_uptake_myc + n_myc_growth = f_growth * N_uptake_myc + l_c_ecm_enz = fc_veg2myc * f_enz + ! we add the enzymes here into the EcM pool because we first took them away, but now add them again + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + l_c_ecm_enz + c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow + end if + + ! update inout optional arguments + if (present(c_ecm_enz)) then + c_ecm_enz = l_c_ecm_enz + endif + if (present(fc_somp2soma)) then + fc_somp2soma = l_fc_somp2soma + end if + if (present(fc_somc2soma)) then + fc_somc2soma = l_fc_somc2soma + end if + if (present(fn_mining_somp)) then + fn_mining_somp = l_fn_mining_somp + end if + if (present(fn_mining_somc)) then + fn_mining_somc = l_fn_mining_somc + end if + + else ! AM + N_demand_myc = c_use_eff * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt + N_uptake_myc = fn_smin2myc + if (N_uptake_myc > N_demand_myc) then + fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg + n_myc_growth = N_demand_myc ! How much N the need to grow + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc ! How much C they need to grow + c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow + + else + fn_myc2veg = (1-f_growth) * N_uptake_myc + n_myc_growth = f_growth * N_uptake_myc + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc / fc_veg2myc + c_myc_resp = fc_veg2myc - c_myc_growth + end if + endif + + fno3_myc2veg = fn_myc2veg * l_no3_frac ! Amount of NO3 / NH4 mycorrhiza could give to plant + fnh4_myc2veg = fn_myc2veg * (1 - l_no3_frac) + no3_unpaid = fno3_myc2veg * dz * dt - no3_from_myc ! plants did not actually get all the promised nitrogen (NO3 / NH4) + nh4_unpaid = fnh4_myc2veg * dz * dt - nh4_from_myc + + !if (no3_unpaid + nh4_unpaid < 0) then + ! message = "N flux from AM mycorrhiza to plant is greater than mycorrhiza can actually give to the plant" + ! call endrun(msg=message) + !else + ! Bringing nitrogen fluxes to vegetation back to gN/m2 + no3_from_myc = fno3_myc2veg * dz * dt ! if we can give more nitrogen than we promised just give it + nh4_from_myc = fnh4_myc2veg * dz * dt + !endif + if ( no3_from_myc < 0.0_r8 .or. nh4_from_myc < 0.0_r8 & + ) then + write(iulog,*) 'ERROR: type,no3_from_myc, nh4_from_myc',myc_type, no3_from_myc, nh4_from_myc, fc_veg2myc_no3,fc_veg2myc_nh4, l_no3_frac, l_fn_mining_somp,l_fn_mining_somc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + end subroutine fun_fluxes_myc_update2 + + + + !Moisture function, based on testbed code: https://github.com/wwieder/biogeochem_testbed/blob/957a5c634b9f2d0b4cdba0faa06b5a91216ace33/SOURCE_CODE/mimics_cycle.f90#L401-L419 real(r8) function r_moist(h2osoi_liq,watsat, h2osoi_ice, dz) !As in testbed (and CLM) version of MIMICS diff --git a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 index 6b0e674c2c..e22333a26b 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 @@ -139,21 +139,20 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, phr_vr => soilbiogeochem_carbonflux_inst%phr_vr_col , & ! Input: [real(r8) (:,:) ] potential HR (gC/m3/s) fphr => soilbiogeochem_carbonflux_inst%fphr_col , & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic - c_am_resp_vr => cnfunmimicsplus_inst%c_am_resp_vr_col , & - c_ecm_resp_vr => cnfunmimicsplus_inst%c_ecm_resp_vr_col , & - c_am_growth_vr => cnfunmimicsplus_inst%c_am_growth_vr_col , & - c_ecm_growth_vr => cnfunmimicsplus_inst%c_ecm_growth_vr_col , & - n_am_growth_vr => cnfunmimicsplus_inst%n_am_growth_vr_col , & - n_ecm_growth_vr => cnfunmimicsplus_inst%n_ecm_growth_vr_col , & - c_ecm_enz_vr => cnfunmimicsplus_inst%c_ecm_enz_vr_col , & - n_somc2ecm_vr => cnfunmimicsplus_inst%n_somc2ecm_vr_col(:,:) , & ! nitrogen mining from ECM mycorrhiza - n_somp2ecm_vr => cnfunmimicsplus_inst%n_somp2ecm_vr_col(:,:) , & ! nitrogen mining from ECM mycorrhiza - c_somc2soma_vr => cnfunmimicsplus_inst%c_somc2soma_vr_col(:,:) , & ! carbon release from mining from somc pool - c_somp2soma_vr => cnfunmimicsplus_inst%c_somp2soma_vr_col(:,:) , & ! carbon release from mining from somp pool - sminno3_to_ecm_vr => cnfunmimicsplus_inst%sminno3_to_ecm_vr_col(:,:) , & ! No3 flux from soil NO3 to ECM - sminno3_to_am_vr => cnfunmimicsplus_inst%sminno3_to_am_vr_col(:,:) , & ! No3 flux from soil NO3 to AM - sminnh4_to_ecm_vr => cnfunmimicsplus_inst%sminnh4_to_ecm_vr_col(:,:) , & ! No3 flux from soil NO3 to ECM - sminnh4_to_am_vr => cnfunmimicsplus_inst%sminnh4_to_am_vr_col(:,:) & ! No3 flux from soil NO3 to A + c_am_resp_vr => soilbiogeochem_carbonflux_inst%c_am_resp_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C respiration flux for AM mycorrhiza (gC/m3/s) + c_ecm_resp_vr => soilbiogeochem_carbonflux_inst%c_ecm_resp_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C respiration flux for ECM mycorrhiza (gC/m3/s) + c_am_growth_vr => soilbiogeochem_carbonflux_inst%c_am_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C growth flux for AM mycorrhiza (gC/m3/s) + c_ecm_growth_vr => soilbiogeochem_carbonflux_inst%c_ecm_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C growth flux for ECM mycorrhiza (gC/m3/s) + n_am_growth_vr => soilbiogeochem_nitrogenflux_inst%n_am_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved N growth flux for AM mycorrhiza (gC/m3/s) + n_ecm_growth_vr => soilbiogeochem_nitrogenflux_inst%n_ecm_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved N growth flux for ECM mycorrhiza (gC/m3/s) + c_ecm_enz_vr => soilbiogeochem_carbonflux_inst%c_ecm_enz_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C enzyme flux for ECM mycorrhiza (goes from plant) (gC/m3/s) + n_somc2ecm_vr => soilbiogeochem_nitrogenflux_inst%n_somc2ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:) ]nitrogen mining from ECM mycorrhiza + n_somp2ecm_vr => soilbiogeochem_nitrogenflux_inst%n_somp2ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:) ]nitrogen mining from ECM mycorrhiza + c_somc2soma_vr => soilbiogeochem_carbonflux_inst%c_somc2soma_vr_col(:,:) , & ! Input: [real(r8) (:,:) carbon release from mining from somp pool + sminno3_to_ecm_vr => soilbiogeochem_nitrogenflux_inst%sminno3_to_ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to ECM + sminno3_to_am_vr => soilbiogeochem_nitrogenflux_inst%sminno3_to_am_vr_col(:,:) , & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to AM + sminnh4_to_ecm_vr => soilbiogeochem_nitrogenflux_inst%sminnh4_to_ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to ECM + sminnh4_to_am_vr => soilbiogeochem_nitrogenflux_inst%sminnh4_to_am_vr_col(:,:) & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to A ) dt = get_step_size_real() @@ -325,15 +324,13 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, end if end if ! fluxes that are not part of the cascade. - decomp_cpools_vr(c,j,i_ecm_myc) = decomp_cpools_vr(c,j,i_ecm_myc) + (c_ecm_growth_vr(c,j) - & - c_ecm_resp_vr(c,j)) * dt + decomp_cpools_vr(c,j,i_ecm_myc) = decomp_cpools_vr(c,j,i_ecm_myc) + c_ecm_growth_vr(c,j) * dt decomp_npools_vr(c,j,i_ecm_myc) = decomp_npools_vr(c,j,i_ecm_myc) + (n_ecm_growth_vr(c,j) + & sminno3_to_ecm_vr(c,j) + sminnh4_to_ecm_vr(c,j)) * dt - decomp_cpools_vr(c,j,i_am_myc) = decomp_cpools_vr(c,j,i_am_myc) + (c_am_growth_vr(c,j) - & - c_am_resp_vr(c,j)) * dt + decomp_cpools_vr(c,j,i_am_myc) = decomp_cpools_vr(c,j,i_am_myc) + c_am_growth_vr(c,j) * dt decomp_npools_vr(c,j,i_am_myc) = decomp_npools_vr(c,j,i_am_myc) + (n_ecm_growth_vr(c,j) + & sminno3_to_am_vr(c,j) + sminnh4_to_am_vr(c,j)) * dt - decomp_npools_vr(c,j,i_avl_som) = decomp_npools_vr(c,j,i_avl_som) + c_ecm_enz_vr(c,j) * dt + decomp_cpools_vr(c,j,i_avl_som) = decomp_cpools_vr(c,j,i_avl_som) + c_ecm_enz_vr(c,j) * dt end do ! transitions end do ! layer enddo !column diff --git a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 index 7998c568b6..855d2cc135 100644 --- a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 @@ -243,11 +243,11 @@ subroutine SoilBiogeochemNStateUpdate1(num_bgc_soilc, filter_bgc_soilc, & ns%smin_no3_vr_col(c,j) = ns%smin_no3_vr_col(c,j) - nf%smin_no3_to_plant_vr_col(c,j)*dt else if (decomp_method == mimicsplus_decomp) then ! we treat mycorrhiza differently in mimics plus - ns%smin_nh4_vr_col(c,j) = ns%smin_nh4_vr_col(c,j) - cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j)*dt - & - (cnfunmimicsplus_inst%sminnh4_to_am_vr_col(c,j) + cnfunmimicsplus_inst%sminnh4_to_ecm_vr_col(c,j)) * dt + ns%smin_nh4_vr_col(c,j) = ns%smin_nh4_vr_col(c,j) - nf%sminnh4_nonmyc_to_plant_col(c,j) * dt - & + (nf%sminnh4_to_am_vr_col(c,j) + nf%sminnh4_to_ecm_vr_col(c,j)) * dt - ns%smin_no3_vr_col(c,j) = ns%smin_no3_vr_col(c,j) - cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j)*dt - & - (cnfunmimicsplus_inst%sminno3_to_am_vr_col(c,j) + cnfunmimicsplus_inst%sminno3_to_ecm_vr_col(c,j)) * dt + ns%smin_no3_vr_col(c,j) = ns%smin_no3_vr_col(c,j) - nf%sminno3_nonmyc_to_plant_col(c,j) * dt - & + (nf%sminno3_to_am_vr_col(c,j) + nf%sminno3_to_ecm_vr_col(c,j)) * dt else ns%smin_nh4_vr_col(c,j) = ns%smin_nh4_vr_col(c,j) - nf%sminn_to_plant_fun_nh4_vr_col(c,j)*dt diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 index a0a54693b7..9b9cd864dd 100644 --- a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 @@ -132,6 +132,15 @@ module SoilBiogeochemNitrogenFluxType real(r8), pointer :: fates_litter_flux (:) ! (gN/m2/s) A summary of the total litter ! flux passed in from FATES. ! This is a diagnostic for balance checks only + real(r8), pointer :: n_am_growth_vr_col(:,:) ! nitrogen growth flux for AM mycorrhiza + real(r8), pointer :: n_ecm_growth_vr_col(:,:) ! nitrogen growth flux for ECM mycorrhiza + real(r8), pointer :: n_somc2ecm_vr_col(:,:) ! nitrogen mining from ECM mycorrhiza + real(r8), pointer :: n_somp2ecm_vr_col(:,:) ! nitrogen mining from ECM mycorrhiza + + real(r8), pointer :: sminno3_to_ecm_vr_col(:,:) ! No3 flux from soil NO3 to ECM + real(r8), pointer :: sminno3_to_am_vr_col(:,:) ! No3 flux from soil NO3 to AM + real(r8), pointer :: sminnh4_to_ecm_vr_col(:,:) ! No3 flux from soil NO3 to ECM + real(r8), pointer :: sminnh4_to_am_vr_col(:,:) ! No3 flux from soil NO3 to AM ! track tradiagonal matrix contains From 8946896f6d657dc02f74aec9df76bd3b531b35b7 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 19 Sep 2024 19:30:51 +0200 Subject: [PATCH 08/17] move column vars to flux types for output --- src/biogeochem/CNFUNMIMICSplusMod.F90 | 260 +++++++----------- src/biogeochem/CNVegNitrogenFluxType.F90 | 5 - src/main/clm_instMod.F90 | 4 +- .../SoilBiogeochemCarbonFluxType.F90 | 53 +++- .../SoilBiogeochemNStateUpdate1Mod.F90 | 3 +- .../SoilBiogeochemNitrogenFluxType.F90 | 39 +++ 6 files changed, 187 insertions(+), 177 deletions(-) diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 6d0b5988c9..dc1bc3d5dc 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -113,23 +113,6 @@ module CNFUNMIMICSplusMod ! Uptake fluxes for COST_METHOD=2 ! Update Fluxes - real(r8), pointer :: c_am_resp_vr_col(:,:) ! carbon respiration flux for AM mycorrhiza - real(r8), pointer :: c_ecm_resp_vr_col(:,:) ! carbon respiration flux for ECM mycorrhiza - real(r8), pointer :: c_am_growth_vr_col(:,:) ! carbon growth flux for AM mycorrhiza - real(r8), pointer :: c_ecm_growth_vr_col(:,:) ! carbon growth flux for ECM mycorrhiza - real(r8), pointer :: n_am_growth_vr_col(:,:) ! nitrogen growth flux for AM mycorrhiza - real(r8), pointer :: n_ecm_growth_vr_col(:,:) ! nitrogen growth flux for ECM mycorrhiza - real(r8), pointer :: c_ecm_enz_vr_col(:,:) ! carbon enzyme production flux for ECM mycorrhiza - real(r8), pointer :: n_somc2ecm_vr_col(:,:) ! nitrogen mining from ECM mycorrhiza - real(r8), pointer :: n_somp2ecm_vr_col(:,:) ! nitrogen mining from ECM mycorrhiza - real(r8), pointer :: c_somc2soma_vr_col(:,:) ! carbon release from mining from somc pool - real(r8), pointer :: c_somp2soma_vr_col(:,:) ! carbon release from mining from somp pool - real(r8), pointer :: sminno3_to_ecm_vr_col(:,:) ! No3 flux from soil NO3 to ECM - real(r8), pointer :: sminno3_to_am_vr_col(:,:) ! No3 flux from soil NO3 to AM - real(r8), pointer :: sminnh4_to_ecm_vr_col(:,:) ! No3 flux from soil NO3 to ECM - real(r8), pointer :: sminnh4_to_am_vr_col(:,:) ! No3 flux from soil NO3 to AM - real(r8), pointer :: sminno3_nonmyc_to_plant_col(:,:) ! No3 flux from min soil to plant (only nonmyc pathway can do this) - real(r8), pointer :: sminnh4_nonmyc_to_plant_col(:,:) ! NH4 flux from min soil to plant (only nonmyc pathway can do this) real(r8), pointer :: no3_myc_to_plant_col(:,:) ! No3 flux from min soil to plant by mycorrhiza real(r8), pointer :: nh4_myc_to_plant_col(:,:) ! NH4 flux from min soil to plant by mycorrhiza @@ -152,7 +135,7 @@ module CNFUNMIMICSplusMod contains - subroutine Init (this, bounds) + subroutine Init (this, bounds, soilbiogeochem_carbonflux_inst, soilbiogeochem_nitrogenflux_inst) ! ! !DESCRIPTION: ! Initialize xxx @@ -161,10 +144,12 @@ subroutine Init (this, bounds) ! ! !ARGUMENTS: class(cnfunmimicsplus_type) :: this - type(bounds_type) , intent(in) :: bounds + type(bounds_type) , intent(in) :: bounds + type(soilbiogeochem_carbonflux_type), intent(inout) :: soilbiogeochem_carbonflux_inst + type(soilbiogeochem_nitrogenflux_type), intent(inout) :: soilbiogeochem_nitrogenflux_inst call this%InitAllocate(bounds) - call this%SetZeros(bounds) + call this%SetZeros(bounds,soilbiogeochem_carbonflux_inst,soilbiogeochem_nitrogenflux_inst) end subroutine Init @@ -240,40 +225,12 @@ subroutine InitAllocate (this, bounds) allocate(this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6)); this%npp_paths_acc(:,:,:) = spval - - ! update fluxes - allocate(this%c_am_resp_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_am_resp_vr_col(:,:) = spval - - allocate(this%c_ecm_resp_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_resp_vr_col(:,:) = spval - - allocate(this%c_am_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_am_growth_vr_col(:,:) = spval - - allocate(this%c_ecm_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_growth_vr_col(:,:) = spval - - allocate(this%n_am_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_am_growth_vr_col(:,:) = spval - - allocate(this%n_ecm_growth_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_ecm_growth_vr_col(:,:) = spval - - allocate(this%c_ecm_enz_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_ecm_enz_vr_col(:,:) = spval - - allocate(this%n_somc2ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_somc2ecm_vr_col(:,:) = spval - allocate(this%n_somp2ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%n_somp2ecm_vr_col(:,:) = spval - allocate(this%c_somc2soma_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_somc2soma_vr_col(:,:) = spval - allocate(this%c_somp2soma_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%c_somp2soma_vr_col(:,:) = spval - allocate(this%sminno3_to_ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_to_ecm_vr_col(:,:) = spval - allocate(this%sminno3_to_am_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_to_am_vr_col(:,:) = spval - allocate(this%sminnh4_to_ecm_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_to_ecm_vr_col(:,:) = spval - allocate(this%sminnh4_to_am_vr_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_to_am_vr_col(:,:) = spval - - allocate(this%sminno3_nonmyc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminno3_nonmyc_to_plant_col(:,:) = spval - allocate(this%sminnh4_nonmyc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%sminnh4_nonmyc_to_plant_col(:,:) = spval - allocate(this%no3_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%no3_myc_to_plant_col(:,:) = spval allocate(this%nh4_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%nh4_myc_to_plant_col(:,:) = spval end subroutine InitAllocate - subroutine SetZeros (this, bounds) + subroutine SetZeros (this, bounds, soilbiogeochem_carbonflux_inst,soilbiogeochem_nitrogenflux_inst) ! ! !DESCRIPTION: ! Sets module data structure to zero @@ -281,9 +238,10 @@ subroutine SetZeros (this, bounds) ! !USES: ! ! !ARGUMENTS: - class(cnfunmimicsplus_type) :: this - type(bounds_type) , intent(in) :: bounds - + class(cnfunmimicsplus_type) :: this + type(bounds_type) , intent(in) :: bounds + type(soilbiogeochem_carbonflux_type), intent(inout) :: soilbiogeochem_carbonflux_inst + type(soilbiogeochem_nitrogenflux_type), intent(inout) :: soilbiogeochem_nitrogenflux_inst integer :: begc, endc integer :: begg, endg integer :: begp, endp @@ -291,55 +249,59 @@ subroutine SetZeros (this, bounds) begg = bounds%begg; endg = bounds%endg begc = bounds%begc; endc = bounds%endc begp = bounds%begp; endp = bounds%endp - - this%rootc_dens_step = 0._r8 - this%sminn_diff = 0._r8 - this%rootc_dens(:,:) = 0._r8 - this%rootC(:) = 0._r8 - this%n_uptake_myc_frac(:,:) = 0._r8 - this%plant_ndemand_pool(:) = 0._r8 - this%plant_ndemand_pool_step(:,:) = 0._r8 - this%litterfall_n_step(:,:) = 0._r8 - this%litterfall_c_step(:,:) = 0._r8 - this%npp_remaining(:,:) = 0._r8 - this%costs_paths(:,:,:) = big_cost - this%npp_to_paths(:,:,:) = 0._r8 - this%npp_frac_paths(:,:,:) = 0._r8 - this%n_from_paths(:,:,:) = 0._r8 - this%n_paths_acc(:,:,:) = 0._r8 - this%npp_paths_acc(:,:,:) = 0._r8 - this%n_retrans_acc(:,:) = 0._r8 - this%free_nretrans_acc(:,:) = 0._r8 - this%npp_retrans_acc(:,:) = 0._r8 - this%nt_uptake(:,:) = 0._r8 - this%npp_uptake(:,:) = 0._r8 - this%sminn_layer(:,:) = 0._r8 - this%sminn_layer_step(:,:,:) = 0._r8 - this%n_active_vr(:,:) = 0._r8 - this%n_nonmyc_vr(:,:) = 0._r8 - this%sminfrc(:,:) = 0._r8 - this%sminn_to_plant(:,:) = 0._r8 - - this%c_am_resp_vr_col(:,:) = 0._r8 - this%c_ecm_resp_vr_col(:,:) = 0._r8 - this%c_am_growth_vr_col(:,:) = 0._r8 - this%c_ecm_growth_vr_col(:,:) = 0._r8 - this%n_am_growth_vr_col(:,:) = 0._r8 - this%n_ecm_growth_vr_col(:,:) = 0._r8 - this%c_ecm_enz_vr_col(:,:) = 0._r8 - this%n_somc2ecm_vr_col(:,:) = 0._r8 - this%n_somp2ecm_vr_col(:,:) = 0._r8 - this%c_somc2soma_vr_col(:,:) = 0._r8 - this%c_somp2soma_vr_col(:,:) = 0._r8 - this%sminno3_to_ecm_vr_col(:,:) = 0._r8 - this%sminno3_to_am_vr_col(:,:) = 0._r8 - this%sminnh4_to_ecm_vr_col(:,:) = 0._r8 - this%sminnh4_to_am_vr_col(:,:) = 0._r8 - this%sminno3_nonmyc_to_plant_col(:,:) = 0._r8 - this%sminnh4_nonmyc_to_plant_col(:,:) = 0._r8 - this%no3_myc_to_plant_col(:,:) = 0._r8 - this%nh4_myc_to_plant_col(:,:) = 0._r8 + associate( cf => soilbiogeochem_carbonflux_inst , & + nf => soilbiogeochem_nitrogenflux_inst ) + + this%rootc_dens_step = 0._r8 + this%sminn_diff = 0._r8 + this%rootc_dens(begp:endp,1:nlevdecomp) = 0._r8 + this%rootC(begp:endp) = 0._r8 + this%n_uptake_myc_frac(begp:endp,1:nmyc) = 0._r8 + this%plant_ndemand_pool(begp:endp) = 0._r8 + this%plant_ndemand_pool_step(begp:endp,1:nmyc) = 0._r8 + this%litterfall_n_step(begp:endp,1:nmyc) = 0._r8 + this%litterfall_c_step(begp:endp,1:nmyc) = 0._r8 + this%npp_remaining(begp:endp,1:nmyc) = 0._r8 + this%costs_paths(begp:endp,1:nlevdecomp,1:npath6) = big_cost + this%npp_to_paths(begp:endp,1:nlevdecomp,1:npath6) = 0._r8 + this%npp_frac_paths(begp:endp,1:nlevdecomp,1:npath6) = 0._r8 + this%n_from_paths(begp:endp,1:nlevdecomp,1:npath6) = 0._r8 + this%n_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6) = 0._r8 + this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6) = 0._r8 + this%n_retrans_acc(bounds%begp:bounds%endp,1:nmyc) = 0._r8 + this%free_nretrans_acc(bounds%begp:bounds%endp,1:nmyc) = 0._r8 + this%npp_retrans_acc(bounds%begp:bounds%endp,1:nmyc) = 0._r8 + this%nt_uptake(bounds%begp:bounds%endp,1:nmyc) = 0._r8 + this%npp_uptake(bounds%begp:bounds%endp,1:nmyc) = 0._r8 + this%sminn_layer(bounds%begc:bounds%endc,1:nlevdecomp) = 0._r8 + this%sminn_layer_step(bounds%begc:bounds%endc,1:nlevdecomp,1:nmyc) = 0._r8 + this%n_active_vr(bounds%begp:bounds%endp, 1:nlevdecomp) = 0._r8 + this%n_nonmyc_vr(bounds%begp:bounds%endp, 1:nlevdecomp) = 0._r8 + this%sminfrc(bounds%begc:bounds%endc,1:nlevdecomp) = 0._r8 + this%sminn_to_plant(bounds%begc:bounds%endc,1:nlevdecomp) = 0._r8 + + cf%c_am_resp_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + cf%c_ecm_resp_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + cf%c_am_growth_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + cf%c_ecm_growth_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%n_am_growth_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%n_ecm_growth_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + cf%c_ecm_enz_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%n_somc2ecm_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%n_somp2ecm_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + cf%c_somc2soma_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + cf%c_somp2soma_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%sminno3_to_ecm_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%sminno3_to_am_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%sminnh4_to_ecm_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%sminnh4_to_am_vr_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%sminno3_nonmyc_to_plant_col(begc:endc,1:nlevdecomp) = 0._r8 + nf%sminnh4_nonmyc_to_plant_col(begc:endc,1:nlevdecomp) = 0._r8 + this%no3_myc_to_plant_col(begc:endc,1:nlevdecomp) = 0._r8 + this%nh4_myc_to_plant_col(begc:endc,1:nlevdecomp) = 0._r8 + + end associate end subroutine SetZeros subroutine readParams ( ncid ) @@ -580,23 +542,15 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s leafc => cnveg_carbonstate_inst%leafc_patch , & ! Input: [real(r8) (:)] (gC/m2) leaf C leafc_storage => cnveg_carbonstate_inst%leafc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) leaf C storage frootc => cnveg_carbonstate_inst%frootc_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C - frootc_storage => cnveg_carbonstate_inst%frootc_storage_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C storage livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:)] (gC/m2) live stem C livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! Input: [real(r8) (:)] (gC/m2) live coarse root C leafc_storage_xfer_acc => cnveg_carbonstate_inst%leafc_storage_xfer_acc_patch , & ! uutput: [real(r8) (:)] Accmulated leaf C transfer (gC/m2) - storage_cdemand => cnveg_carbonstate_inst%storage_cdemand_patch , & ! Output: [real(r8) (:)] C use f rom the C storage pool - tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one sided leaf area index 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 - livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:)] (gN/m2) live stem N - livecrootn => cnveg_nitrogenstate_inst%livecrootn_patch , & ! Input: [real(r8) (:)] (gN/m2) retranslocation N retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:)] (gN/m2) live coarse root N leafn_storage_xfer_acc => cnveg_nitrogenstate_inst%leafn_storage_xfer_acc_patch, & ! Output: [real(r8) (:)] Accmulated leaf N transfer (gC/m2) storage_ndemand => cnveg_nitrogenstate_inst%storage_ndemand_patch , & ! Output: [real(r8) (:)] N demand during the offset period leafc_to_litter => cnveg_carbonflux_inst%leafc_to_litter_patch , & ! Output: [real(r8) (:) ] leaf C litterfall (gC/m2/s) leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch , & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s) - prev_leafc_to_litter => cnveg_carbonflux_inst%prev_leafc_to_litter_patch , & ! Output: [real(r8) (:)] previous timestep leaf C litterfall flux (gC/m2/s) - leafc_storage_to_xfer => cnveg_carbonflux_inst%leafc_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] npp_Nactive => cnveg_carbonflux_inst%npp_Nactive_patch , & ! Output: [real(r8) (:) ] Mycorrhizal N uptake used C (gC/m2/s) npp_Nnonmyc => cnveg_carbonflux_inst%npp_Nnonmyc_patch , & ! Output: [real(r8) (:) ] Non-mycorrhizal N uptake use C (gC/m2/s) npp_Nam => cnveg_carbonflux_inst%npp_Nam_patch , & ! Output: [real(r8) (:) ] AM uptake use C (gC/m2/s) @@ -614,12 +568,9 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s npp_Nuptake => cnveg_carbonflux_inst%npp_Nuptake_patch , & ! Output: [real(r8) (:) ] Total N uptake of FUN used C (gC/m2/s) npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! Output: [real(r8) (:) ] Total N uptake of FUN used C (gC/m2/s) npp_burnedoff => cnveg_carbonflux_inst%npp_burnedoff_patch , & ! Output: [real(r8) (:) ] C that cannot be used for N uptake(gC/m2/s) - leafc_change => cnveg_carbonflux_inst%leafc_change_patch , & ! Output: [real(r8) (:) ] Used C from the leaf (gC/m2/s) leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] plant_ndemand => cnveg_nitrogenflux_inst%plant_ndemand_patch , & ! Iutput: [real(r8) (:) ] N flux required to support initial GPP (gN/m2/s) plant_ndemand_retrans => cnveg_nitrogenflux_inst%plant_ndemand_retrans_patch , & ! Output: [real(r8) (:) ] N demand generated for FUN (gN/m2/s) - plant_ndemand_season => cnveg_nitrogenflux_inst%plant_ndemand_season_patch , & ! Output: [real(r8) (:) ] N demand for seasonal deciduous forest (gN/m2/s) - plant_ndemand_stress => cnveg_nitrogenflux_inst%plant_ndemand_stress_patch , & ! Output: [real(r8) (:) ] N demand for stress deciduous forest (gN/m2/s) Nactive => cnveg_nitrogenflux_inst%Nactive_patch , & ! Output: [real(r8) (:) ] Mycorrhizal N uptake (gN/m2/s) Nnonmyc => cnveg_nitrogenflux_inst%Nnonmyc_patch , & ! Output: [real(r8) (:) ] Non-mycorrhizal N uptake (gN/m2/s) Nam => cnveg_nitrogenflux_inst%Nam_patch , & ! Output: [real(r8) (:) ] AM uptake (gN/m2/s) @@ -682,28 +633,19 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s rootc_dens => cnfunmimicsplus_inst%rootc_dens , & rootc_dens_step => cnfunmimicsplus_inst%rootc_dens_step , & sminfrc => cnfunmimicsplus_inst%sminfrc , & - sminn_diff => cnfunmimicsplus_inst%sminn_diff , & sminn_layer_step => cnfunmimicsplus_inst%sminn_layer_step , & sminn_to_plant => cnfunmimicsplus_inst%sminn_to_plant , & ! C and N soil pools: decomp_cpools_vr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col , & - decomp_npools_vr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col , & - - c_am_resp_vr_col => cnfunmimicsplus_inst%c_am_resp_vr_col , & - c_ecm_resp_vr_col => cnfunmimicsplus_inst%c_ecm_resp_vr_col , & - c_am_growth_vr_col => cnfunmimicsplus_inst%c_am_growth_vr_col , & - c_ecm_growth_vr_col => cnfunmimicsplus_inst%c_ecm_growth_vr_col , & - n_am_growth_vr_col => cnfunmimicsplus_inst%n_am_growth_vr_col , & - n_ecm_growth_vr_col => cnfunmimicsplus_inst%n_ecm_growth_vr_col , & - c_ecm_enz_vr_col => cnfunmimicsplus_inst%c_ecm_enz_vr_col ) + decomp_npools_vr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col ) dt = get_step_size_real() stepspday = secspday / dt ! Time step of FUNMIMICSplus: once per day - call cnfunmimicsplus_inst%SetZeros(bounds) ! set everything to zero + call cnfunmimicsplus_inst%SetZeros(bounds,soilbiogeochem_carbonflux_inst,soilbiogeochem_nitrogenflux_inst) ! set everything to zero do fp = 1,num_soilp ! PFT Starts p = filter_soilp(fp) @@ -1274,12 +1216,12 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s npp_Nnonmyc_no3(p) = sum(npp_paths_acc(p,1:nmyc,ipnmno3)) / dt npp_Nnonmyc_nh4(p) = sum(npp_paths_acc(p,1:nmyc,ipnmnh4)) / dt npp_Nfix(p) = sum(npp_paths_acc(p,1:nmyc,ipfix)) /dt - npp_Nactive(p) = npp_Nactive_no3(p) + npp_Nactive_nh4(p) + npp_Nnonmyc_no3(p) + npp_Nnonmyc_nh4(p) + npp_Nactive(p) = npp_Nactive_no3(p) + npp_Nactive_nh4(p) npp_Nnonmyc(p) = npp_Nnonmyc_no3(p) + npp_Nnonmyc_nh4(p) npp_Nretrans(p) = sum(npp_retrans_acc(p,1:nmyc))/dt !---------------------------Extra Respiration Fluxes--------------------! - soilc_change(p) = npp_Nactive(p) + npp_Nfix(p) + npp_Nretrans(p) + soilc_change(p) = npp_Nactive(p) + npp_Nfix(p) + npp_Nnonmyc(p) + npp_Nretrans(p) soilc_change(p) = soilc_change(p) + burned_off_carbon / dt npp_burnedoff(p) = burned_off_carbon/dt npp_Nuptake(p) = soilc_change(p) @@ -1314,7 +1256,13 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s msg= errMsg(sourcefile, __LINE__)) endif if (availc(p) - npp_Nuptake(p) - npp_growth(p) < 0._r8) then - write(iulog,*) 'ERROR: balance Cfun is negative: ',availc(p), npp_Nuptake(p),npp_growth(p),excess_carbon_acc/dt,npp_Nretrans(p) + write(iulog,*) 'ERROR: balance Cfun is negative: ' + write(iulog,*) 'Acailc, npp_Nuptake/growth:',availc(p), npp_Nuptake(p),npp_growth(p) + write(iulog,*), 'Excess carbon, npp_Nretrans,freeretrans',excess_carbon_acc/dt,npp_Nretrans(p),free_retransn_to_npool(p) + do ipath = 1,npath6 + write(iulog,*) 'ERROR nppaths_ecm:',ipath, npp_paths_acc(p,1,ipath) + write(iulog,*) 'ERROR nppaths_am:',ipath, npp_paths_acc(p,2,ipath) + enddo call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & msg= errMsg(sourcefile, __LINE__)) endif @@ -1410,60 +1358,64 @@ subroutine updateCNFUNMIMICSplus (bounds, num_soilc, filter_soilc, & real(r8), intent(in) :: n_nonmyc_no3_vr(:,:) ! Layer non-myc no3 uptake (gN/m2) real(r8), intent(in) :: n_active_nh4_vr(:,:) ! Layer mycorrhizal nh4 uptake (gN/m2) real(r8), intent(in) :: n_nonmyc_nh4_vr(:,:) ! Layer non-myc nh4 uptake (gN/m2) + + associate( cnfun => cnfunmimicsplus_inst , & + scf => soilbiogeochem_carbonflux_inst , & + snf => soilbiogeochem_nitrogenflux_inst , & + cf => cnveg_carbonflux_inst , & + nf => cnveg_nitrogenflux_inst ) !!! soilc_change_col is not used anywhere - call p2c(bounds, num_soilc, filter_soilc, & - cnveg_carbonflux_inst%soilc_change_patch(bounds%begp:bounds%endp), & - soilbiogeochem_carbonflux_inst%soilc_change_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, cf%soilc_change_patch(bounds%begp:bounds%endp), & + scf%soilc_change_col(bounds%begc:bounds%endc)) - call p2c(bounds, num_soilc, filter_soilc, & - cnveg_nitrogenflux_inst%Nfix_patch(bounds%begp:bounds%endp), & - soilbiogeochem_nitrogenflux_inst%nfix_to_sminn_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, nf%Nfix_patch(bounds%begp:bounds%endp), & + snf%nfix_to_sminn_col(bounds%begc:bounds%endc)) if (use_nitrif_denitrif) then ! plant fluxes call p2c(bounds,nlevdecomp, & n_active_no3_vr(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%no3_myc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& + cnfun%no3_myc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & n_nonmyc_no3_vr(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%sminno3_nonmyc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & n_active_nh4_vr(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%nh4_myc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& + cnfun%nh4_myc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & n_nonmyc_nh4_vr(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%sminnh4_nonmyc_to_plant_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') ! mycorrhyza fluxes call p2c(bounds,nlevdecomp, & sminno3_to_ecm_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%sminno3_to_ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%sminno3_to_ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & sminnh4_to_ecm_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%sminnh4_to_ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%sminnh4_to_ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & sminno3_to_am_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%sminno3_to_am_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%sminno3_to_am_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & sminnh4_to_am_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%sminnh4_to_am_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%sminnh4_to_am_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') else call p2c(bounds, nlevdecomp, & - cnveg_nitrogenflux_inst%sminn_to_plant_fun_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - soilbiogeochem_nitrogenflux_inst%sminn_to_plant_fun_vr_col(bounds%begc:bounds%endc,1:nlevdecomp), & + nf%sminn_to_plant_fun_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& + snf%sminn_to_plant_fun_vr_col(bounds%begc:bounds%endc,1:nlevdecomp), & 'unity') ! add sminn for mycorrhiza when fun can work with nitrification/dinitrification off @@ -1472,60 +1424,62 @@ subroutine updateCNFUNMIMICSplus (bounds, num_soilc, filter_soilc, & ! fluxes that will be used in decomposition: call p2c(bounds,nlevdecomp, & c_am_resp_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_am_resp_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_am_resp_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & c_ecm_resp_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_ecm_resp_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_ecm_resp_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & c_am_growth_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_am_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_am_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & c_ecm_growth_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_ecm_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_ecm_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') ! these nitrogen fluxes might not bee needed since C:N ratio for growth is constant call p2c(bounds,nlevdecomp, & n_am_growth_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%n_am_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%n_am_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & n_ecm_growth_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%n_ecm_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%n_ecm_growth_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & c_ecm_enz_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_ecm_enz_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_ecm_enz_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') ! mining fluxes call p2c(bounds,nlevdecomp, & n_somc2ecm_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%n_somc2ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%n_somc2ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & n_somp2ecm_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%n_somp2ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + snf%n_somp2ecm_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & c_somc2soma_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_somc2soma_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_somc2soma_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') call p2c(bounds,nlevdecomp, & c_somp2soma_vr_patch(bounds%begp:bounds%endp,1:nlevdecomp),& - cnfunmimicsplus_inst%c_somp2soma_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& + scf%c_somp2soma_vr_col(bounds%begc:bounds%endc,1:nlevdecomp),& 'unity') - end subroutine updateCNFUNMIMICSplus + + end associate +end subroutine updateCNFUNMIMICSplus !========================================================================================= real(r8) function fun_cost_fix(fixer,a_fix,b_fix,c_fix,big_cost,crootfr,s_fix, tc_soisno) diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90 index 1d9bfd515c..45a99c91b7 100644 --- a/src/biogeochem/CNVegNitrogenFluxType.F90 +++ b/src/biogeochem/CNVegNitrogenFluxType.F90 @@ -272,11 +272,6 @@ module CNVegNitrogenFluxType real(r8), pointer :: cost_nretrans_patch (:) ! Average cost of retranslocation (gN/m2/s) real(r8), pointer :: nuptake_npp_fraction_patch (:) ! frac of npp spent on N acquisition (gN/m2/s) - real(r8), pointer :: sminno3_nonmyc_to_plant_col(:,:) ! No3 flux from min soil to plant (only nonmyc pathway can do this) - real(r8), pointer :: sminnh4_nonmyc_to_plant_col(:,:) ! NH4 flux from min soil to plant (only nonmyc pathway can do this) - real(r8), pointer :: no3_myc_to_plant_col(:,:) ! No3 flux from min soil to plant by mycorrhiza - real(r8), pointer :: nh4_myc_to_plant_col(:,:) ! NH4 flux from min soil to plant by mycorrhiza - ! Matrix solution variables diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index 4db9f9ab5c..e268a9416a 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -395,8 +395,6 @@ subroutine clm_instInit(bounds) call init_decompcascade_mimicsplus(bounds, soilbiogeochem_state_inst, & soilstate_inst) end if - ! init this all the time, so we don't have to pass it as optional. - call cnfunmimicsplus_inst%Init(bounds) ! Initalize soilbiogeochem carbon types @@ -432,7 +430,7 @@ subroutine clm_instInit(bounds) c14_soilbiogeochem_carbonstate_inst, soilbiogeochem_nitrogenstate_inst) if (decomp_method == mimicsplus_decomp ) then - call cnfunmimicsplus_inst%Init(bounds) !ECW + call cnfunmimicsplus_inst%Init(bounds,soilbiogeochem_carbonflux_inst,soilbiogeochem_nitrogenflux_inst) end if end if if_decomp diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index 5a58e8278a..393b618528 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -54,6 +54,7 @@ module SoilBiogeochemCarbonFluxType real(r8), pointer :: hr_col (:) ! (gC/m2/s) total heterotrophic respiration real(r8), pointer :: michr_col (:) ! (gC/m2/s) microbial heterotrophic respiration: donor-pool based definition, so expect it to be zero with MIMICS; microbial decomposition is responsible for heterotrophic respiration of donor pools (litter and soil), but in the accounting we assign it to the donor pool for consistency with CENTURY + real(r8), pointer :: mychr_col (:) ! (gC/m2/s) mycorrhiza heterotrophic respiration (mimicsplus): since the pathways is not part of decomp_cascade it's treated differently than other hr real(r8), pointer :: cwdhr_col (:) ! (gC/m2/s) coarse woody debris heterotrophic respiration: donor-pool based definition real(r8), pointer :: lithr_col (:) ! (gC/m2/s) litter heterotrophic respiration: donor-pool based definition real(r8), pointer :: somhr_col (:) ! (gC/m2/s) soil organic matter heterotrophic res: donor-pool based definition @@ -164,6 +165,7 @@ subroutine InitAllocate(this, bounds) allocate(this%hr_col (begc:endc)) ; this%hr_col (:) = nan allocate(this%michr_col (begc:endc)) ; this%michr_col (:) = nan + allocate(this%mychr_col (begc:endc)) ; this%mychr_col (:) = nan allocate(this%cwdhr_col (begc:endc)) ; this%cwdhr_col (:) = nan allocate(this%lithr_col (begc:endc)) ; this%lithr_col (:) = nan allocate(this%somhr_col (begc:endc)) ; this%somhr_col (:) = nan @@ -249,6 +251,12 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='microbial C heterotrophic respiration: donor-pool based, so expect zero with MIMICS', & ptr_col=this%michr_col, default='inactive') end if + if (decomp_method == mimicsplus_decomp) then + this%mychr_col(begc:endc) = spval + call hist_addfld1d (fname='MYCC_HR', units='gC/m^2/s', & + avgflag='A', long_name='mycorrhizal C heterotrophic respiration: donor-pool based, so expect zero with MIMICSplus', & + ptr_col=this%mychr_col, default='inactive') + end if this%cwdhr_col(begc:endc) = spval call hist_addfld1d (fname='CWDC_HR', units='gC/m^2/s', & @@ -470,6 +478,12 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='C13 microbial heterotrophic respiration', & ptr_col=this%michr_col, default='inactive') end if + if (decomp_method == mimicsplus_decomp) then + this%mychr_col(begc:endc) = spval + call hist_addfld1d (fname='C13_MYCC_HR', units='gC/m^2/s', & + avgflag='A', long_name='C13 mycorrhizal heterotrophic respiration', & + ptr_col=this%mychr_col, default='inactive') + end if this%cwdhr_col(begc:endc) = spval call hist_addfld1d (fname='C13_CWDC_HR', units='gC/m^2/s', & @@ -545,13 +559,18 @@ subroutine InitHistory(this, bounds, carbon_type) avgflag='A', long_name='C14 total heterotrophic respiration', & ptr_col=this%hr_col) - if (decomp_method == mimics_decomp .or. decomp_method == mimicsplus_decomp) then + if (decomp_method == mimics_decomp .or. decomp_method == mimicsplus_decomp) then this%michr_col(begc:endc) = spval call hist_addfld1d (fname='C14_MICC_HR', units='gC13/m^2/s', & avgflag='A', long_name='C14 microbial heterotrophic respiration', & ptr_col=this%michr_col, default='inactive') end if - + if (decomp_method == mimicsplus_decomp) then + this%mychr_col(begc:endc) = spval + call hist_addfld1d (fname='C14_MYCC_HR', units='gC/m^2/s', & + avgflag='A', long_name='C14 mycorrhizal heterotrophic respiration', & + ptr_col=this%mychr_col, default='inactive') + end if this%cwdhr_col(begc:endc) = spval call hist_addfld1d (fname='C14_CWDC_HR', units='gC/m^2/s', & avgflag='A', long_name='C14 cwd C heterotrophic respiration', & @@ -766,6 +785,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column) this%lithr_col(i) = value_column this%cwdhr_col(i) = value_column this%michr_col(i) = value_column + this%mychr_col(i) = value_column this%soilc_change_col(i) = value_column end do @@ -852,15 +872,6 @@ subroutine Summary(this, bounds, & end do end do - ! we need to explicitly add mycorrhizal respiration, since that is due to the flux to plant and not part of the cascade. - if (decomp_method == mimicsplus_decomp) then - do j = 1,nlevdecomp - do fc = 1,num_bgc_soilc - c = filter_bgc_soilc(fc) - this%hr_vr_col(c,j) = & - this%hr_vr_col(c,j) + - end do - end do ! add up all vertical transport tendency terms and calculate total som leaching loss as the sum of these do l = 1, ndecomp_pools do fc = 1,num_bgc_soilc @@ -927,8 +938,20 @@ subroutine Summary(this, bounds, & end if end do end associate - - + ! mycorrhiza hr is treated differently because it is not part of the decomp cascade + if (decomp_method == mimicsplus_decomp) then + do j = 1, nlevdecomp + do fc = 1,num_bgc_soilc + c = filter_bgc_soilc(fc) + this%mychr_col(c) = this%michr_col(c) + (this%c_am_resp_vr_col(c,j) + this%c_ecm_resp_vr_col(c,j)) * dzsoi_decomp(j) + end do + end do + else + do fc = 1,num_bgc_soilc + c = filter_bgc_soilc(fc) + this%mychr_col(c) = 0.0_r8 + end do + endif ! total heterotrophic respiration (HR) do fc = 1,num_bgc_soilc c = filter_bgc_soilc(fc) @@ -937,8 +960,8 @@ subroutine Summary(this, bounds, & this%michr_col(c) + & this%cwdhr_col(c) + & this%lithr_col(c) + & - this%somhr_col(c) - + this%somhr_col(c) + & + this%mychr_col(c) end do ! Calculate ligninNratio diff --git a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 index 855d2cc135..18d92e24e6 100644 --- a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 @@ -59,7 +59,8 @@ subroutine SoilBiogeochemNStateUpdate1(num_bgc_soilc, filter_bgc_soilc, & nfixation_prof => soilbiogeochem_state_inst%nfixation_prof_col , & ! Input: [real(r8) (:,:) ] profile over which N fixation is distributed through column (1/m) nf => soilbiogeochem_nitrogenflux_inst , & ! Output: - ns => soilbiogeochem_nitrogenstate_inst & ! Output: + ns => soilbiogeochem_nitrogenstate_inst , & ! Output: + cnfun => cnfunmimicsplus_inst & ) ! set time steps diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 index 9b9cd864dd..b2e8ca2f5c 100644 --- a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 @@ -141,6 +141,8 @@ module SoilBiogeochemNitrogenFluxType real(r8), pointer :: sminno3_to_am_vr_col(:,:) ! No3 flux from soil NO3 to AM real(r8), pointer :: sminnh4_to_ecm_vr_col(:,:) ! No3 flux from soil NO3 to ECM real(r8), pointer :: sminnh4_to_am_vr_col(:,:) ! No3 flux from soil NO3 to AM + real(r8), pointer :: sminno3_nonmyc_to_plant_col(:,:) ! No3 flux from min soil to plant (only nonmyc pathway can do this) + real(r8), pointer :: sminnh4_nonmyc_to_plant_col(:,:) ! NH4 flux from min soil to plant (only nonmyc pathway can do this) ! track tradiagonal matrix contains @@ -292,6 +294,28 @@ subroutine InitAllocate(this, bounds) allocate(this%fates_litter_flux(0:0)); this%fates_litter_flux(:) = nan end if + ! MIMICSplus variables: + allocate(this%n_am_growth_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%n_ecm_growth_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%n_somc2ecm_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%n_somp2ecm_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%sminno3_to_am_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%sminno3_to_ecm_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%sminno3_nonmyc_to_plant_col (begc:endc,1:nlevdecomp_full )) + allocate(this%sminnh4_to_am_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%sminnh4_to_ecm_vr_col (begc:endc,1:nlevdecomp_full )) + allocate(this%sminnh4_nonmyc_to_plant_col (begc:endc,1:nlevdecomp_full )) + this%n_am_growth_vr_col(:,:) = nan + this%n_ecm_growth_vr_col(:,:) = nan + this%n_somc2ecm_vr_col(:,:) = nan + this%n_somp2ecm_vr_col(:,:) = nan + this%sminno3_to_am_vr_col(:,:) = nan + this%sminno3_to_ecm_vr_col(:,:) = nan + this%sminno3_nonmyc_to_plant_col(:,:) = nan + this%sminnh4_to_am_vr_col(:,:) = nan + this%sminnh4_to_ecm_vr_col(:,:) = nan + this%sminnh4_nonmyc_to_plant_col(:,:) = nan + ! Allocate soil Matrix setug if(use_soil_matrixcn)then end if @@ -1059,6 +1083,21 @@ subroutine SetValues ( this, & end do end do + do j = 1, nlevdecomp_full + do fi = 1,num_column + i = filter_column(fi) + this%n_am_growth_vr_col(i,j) = value_column + this%n_ecm_growth_vr_col(i,j) = value_column + this%n_somc2ecm_vr_col(i,j) = value_column + this%n_somp2ecm_vr_col(i,j) = value_column + this%sminno3_to_am_vr_col(i,j) = value_column + this%sminno3_to_ecm_vr_col(i,j) = value_column + this%sminno3_nonmyc_to_plant_col(i,j) = value_column + this%sminnh4_to_am_vr_col(i,j) = value_column + this%sminnh4_to_ecm_vr_col(i,j) = value_column + this%sminnh4_nonmyc_to_plant_col(i,j) = value_column + end do + end do end subroutine SetValues !----------------------------------------------------------------------- From 1f821aac8c13f217d88fba8c574f8548a021a243 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 19 Sep 2024 19:31:10 +0200 Subject: [PATCH 09/17] Fix bug with decomp --- .../SoilBiogeochemCompetitionMod.F90 | 16 +- ...ilBiogeochemDecompCascadeMIMICSplusMod.F90 | 258 ------------------ .../SoilBiogeochemDecompMod.F90 | 26 +- 3 files changed, 23 insertions(+), 277 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 index b86cdd2592..a8aac05951 100644 --- a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 @@ -821,17 +821,21 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu ! sum up N fluxes to plant after initial competition sminn_to_plant(c) = 0._r8 !this isn't use in fun. do j = 1, nlevdecomp - if ((cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%sminno3_to_ecm_vr_col(c,j) + & - cnfunmimicsplus_inst%sminno3_to_am_vr_col(c,j) - smin_no3_to_plant_vr(c,j)).gt.0.0000000000001_r8) then + if ((soilbiogeochem_nitrogenflux_inst%sminno3_nonmyc_to_plant_col(c,j) + & + soilbiogeochem_nitrogenflux_inst%sminno3_to_ecm_vr_col(c,j) + & + soilbiogeochem_nitrogenflux_inst%sminno3_to_am_vr_col(c,j) - & + smin_no3_to_plant_vr(c,j)).gt.0.0000000000001_r8) then write(iulog,*) 'problem with limitations on no3 uptake', & - cnfunmimicsplus_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%no3_myc_to_plant_col(c,j), & + soilbiogeochem_nitrogenflux_inst%sminno3_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%no3_myc_to_plant_col(c,j), & smin_no3_to_plant_vr(c,j) call endrun("too much NO3 uptake predicted by CNFUNMIMICSplus") end if - if ((cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%sminnh4_to_ecm_vr_col(c,j) + & - cnfunmimicsplus_inst%sminno3_to_am_vr_col(c,j) - smin_nh4_to_plant_vr(c,j)).gt.0.0000000000001_r8) then + if ((soilbiogeochem_nitrogenflux_inst%sminnh4_nonmyc_to_plant_col(c,j) + & + soilbiogeochem_nitrogenflux_inst%sminnh4_to_ecm_vr_col(c,j) + & + soilbiogeochem_nitrogenflux_inst%sminnh4_to_am_vr_col(c,j) - & + smin_nh4_to_plant_vr(c,j)).gt.0.0000000000001_r8) then write(iulog,*) 'problem with limitations on nh4 uptake', & - cnfunmimicsplus_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%nh4_myc_to_plant_col(c,j), & + soilbiogeochem_nitrogenflux_inst%sminnh4_nonmyc_to_plant_col(c,j) + cnfunmimicsplus_inst%nh4_myc_to_plant_col(c,j), & smin_nh4_to_plant_vr(c,j) call endrun("too much NH4 uptake predicted by CNFUNMIMICSplus") end if diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index cc3461f7ba..0b588237f5 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -2389,264 +2389,6 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, end subroutine fun_fluxes_myc_update1 - subroutine fun_fluxes_myc_update2 (cpool_myc, npool_myc, cpool_somp, cpool_soma,cpool_somc, & - npool_somp, npool_somc, sminn, sminfrc_no3, myc_type, dz, & - fc_veg2myc_no3, fc_veg2myc_nh4, & - no3_from_nonmyc,nh4_from_nonmyc, & - no3_from_myc, nh4_from_myc, & - fn_smin_no3_2myc, fn_smin_nh4_2myc, c_myc_resp,c_myc_growth,n_myc_growth,c_ecm_enz, & - fc_somp2soma, fc_somc2soma, fn_mining_somp,fn_mining_somc) - - ! ! DESCRIPTION: - ! Updating Nitrogen and Carbon fluxes into mycorrhizal pools, to let them grow - ! - ! ! USES: - use clm_time_manager, only: get_step_size_real - - ! - ! !ARGUMENTS: - - real(r8), intent(in) :: cpool_myc ! Carbon pool of mycorrhiza [gC/m3] - real(r8), intent(in) :: npool_myc ! Nitrogen pool of mycorrhiza [gN/m3] - real(r8), intent(in) :: cpool_somp ! physically protected SOM pool [gC/m3] - real(r8), intent(in) :: cpool_soma ! available SOM pool [gC/m3] - real(r8), intent(in) :: cpool_somc ! chemically protected SOM pool [gC/m3] - real(r8), intent(in) :: npool_somp ! physically protected SOM pool [gN/m3] - real(r8), intent(in) :: npool_somc ! chemically protected SOM pool [gN/m3] - real(r8), intent(in) :: sminn ! soil mineral nitrogen (NO3+NH4) [gN/m2] - real(r8), intent(in) :: sminfrc_no3 ! fraction of soil mineral nitrogen NO3 [-] - integer, intent(in) :: myc_type ! type of mycorrhiza EcM=1, AM=2 [-] - real(r8), intent(in) :: dz ! layer thickness [m] - - ! FUN fluxes - real(r8), intent(inout) :: fc_veg2myc_no3 ! Carbon flux from plant to mycorrhiza [gC/m2] - real(r8), intent(inout) :: fc_veg2myc_nh4 ! Carbon flux from plant to mycorrhiza [gC/m2] - real(r8), intent(inout) :: no3_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NO3) [gN/m3] - real(r8), intent(inout) :: nh4_from_nonmyc ! nitrogen flux from non mycorrhizal pool to vegetation (NH4) [gN/m3] - real(r8), intent(inout) :: no3_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NO3) [gN/m3] - real(r8), intent(inout) :: nh4_from_myc ! nitrogen flux from mycorrhizal pool to vegetation (NH4) [gN/m3] - - real(r8), intent(inout) :: fn_smin_no3_2myc ! nitrogen flux from inorganic NO3 pool to mycorrhiza [gN/m2] - real(r8), intent(inout) :: fn_smin_nh4_2myc ! nitrogen flux from inorganic NH4 pool to mycorrhiza [gN/m2] - - ! Mycorrhiza internal fluxes - real(r8), intent(inout) :: c_myc_resp ! carbon respiration flux for AM mycorrhiza [gC/m3/s] - real(r8), intent(inout) :: c_myc_growth ! carbon growth flux for AM mycorrhiza [gC/m3/s] - real(r8), intent(inout) :: n_myc_growth ! nitrogen growth flux for AM mycorrhiza [gN/m3/s] - real(r8), intent(inout), optional :: c_ecm_enz ! carbon enzyme production flux for ECM mycorrhiza [gC/m3/s] - - ! Mining fluxes - real(r8), intent(inout), optional :: fc_somp2soma ! carbon fluxes somp to soma due to mining [gC/m3/s] - real(r8), intent(inout), optional :: fc_somc2soma ! carbon fluxes somc to soma due to mining [gC/m3/s] - real(r8) ,intent(inout), optional :: fn_mining_somp ! nitrogen fluxes to somp to myc (mining + scavenging) [gN/m3/s] - real(r8) ,intent(inout), optional :: fn_mining_somc ! nitrogen fluxes to somc to myc (mining + scavenging) [gN/m3/s] - - ! LOCAL VARIABLES - real(r8) :: secphr = 60.0_r8 * 60.0_r8 - real(r8) :: dt ! timestep size (seconds) - real(r8), parameter :: f_enz = 0.1_r8 ! [-]Fraction of C from vegetation to EcM, that goes into SOMa for mining - real(r8), parameter :: f_growth = 0.5_r8 ! [-] Fraction of mycorrhizal N uptake that needs to stay within the fungi (not given to plant) - real(r8) :: fc_veg2myc ! carbon flux vegetation to mycorrhiza [] - real(r8) :: fn_myc2veg ! nitrogen fluxes mycorrhiza to vegetation [gN/m3/s] - real(r8) :: l_c_ecm_enz, l_fc_somp2soma, l_fc_somc2soma, l_fn_mining_somp, l_fn_mining_somc !locals of optional args - real(r8) :: N_uptake_myc ! [gN/m3/s] - real(r8) :: N_demand_myc ! [gN/m3/s] - real(r8) :: c_use_eff ! carbon use efficiency [-] - real(r8) :: frac_no3_myc, frac_no3_nonmyc ! [-] - real(r8) :: fn_smin2myc, fno3_myc2veg,fnh4_myc2veg ! local fluxes for balancing [gN/m3/s] - real(r8) :: no3_unpaid, nh4_unpaid ! nitrogen that did not actually reach the plant [gN/m2] - real(r8) :: smin_overflow ! How much N mycorrhiza and non mycorrhiza promised to take out of soil and give to plant - real(r8) :: l_no3_frac - real(r8), parameter :: small_value =1.0e-7_r8 - - character(len=256) :: message - - dt = get_step_size_real() - - ! If statements check, if mining is happening. Mining includes: C Enzymes production flux from EcM, - ! C fluxes from SOMp and c to SOMa, and N fluxes from SOMp and c to EcM. - ! If no mining occurs eg. only AM is present those fluxes are set to 0. - if (present(c_ecm_enz)) then - l_c_ecm_enz = c_ecm_enz - else - l_c_ecm_enz = 0.0_r8 - end if - - if (present(fc_somp2soma)) then - l_fc_somp2soma = fc_somp2soma - else - l_fc_somp2soma = 0.0_r8 - end if - - if (present(fc_somc2soma)) then - l_fc_somc2soma = fc_somc2soma - else - l_fc_somc2soma = 0.0_r8 - end if - - if (present(fn_mining_somp)) then - l_fn_mining_somp = fn_mining_somp - else - l_fn_mining_somp = 0.0_r8 - end if - - if (present(fn_mining_somc)) then - l_fn_mining_somc = fn_mining_somc - else - l_fn_mining_somc = 0.0_r8 - end if - - ! Initialize carbon use efficiencies - if (myc_type == 1) then - c_use_eff = params_inst%mimicsplus_mge_ecm - else - c_use_eff = params_inst%mimicsplus_mge_am - endif - - ! Get no3/total N fraction - if (no3_from_myc + nh4_from_myc > 0.0_r8) then - frac_no3_myc = no3_from_myc / (no3_from_myc + nh4_from_myc) - else - frac_no3_myc = 1.0_r8 - end if - if (no3_from_nonmyc + nh4_from_nonmyc > 0.0_r8) then - frac_no3_nonmyc = no3_from_nonmyc / (no3_from_nonmyc + nh4_from_nonmyc) - else - frac_no3_nonmyc = 1.0_r8 - end if - - ! Soil mineral nitrogen flux to mycorrhiza, split into NO3 and NH4 - fn_smin2myc = (params_inst%mimicsplus_vmax_myc / secphr) * sminn * & - (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) * dt ! multiplied by dt to get it in same units as no3_from_nonmyc - fn_smin_no3_2myc = fn_smin2myc * sminfrc_no3 - fn_smin_nh4_2myc = fn_smin2myc * (1.0_r8 - sminfrc_no3) - if (sminn * sminfrc_no3 <= small_value) then - fn_smin_no3_2myc = 0.0_r8 - no3_from_nonmyc = 0.0_r8 - else - ! If there is not enough nitrogen in the soil mineral, NO3 and NH4 - if (fn_smin_no3_2myc + no3_from_nonmyc > sminn * sminfrc_no3) then - smin_overflow = (fn_smin_no3_2myc + no3_from_nonmyc) - sminn * sminfrc_no3! NO3 that is actually in soil - - fn_smin_no3_2myc = fn_smin_no3_2myc - smin_overflow * fn_smin_no3_2myc / (sminn * sminfrc_no3 + smin_overflow ) ! mycorrhiza limit uptake from inorganic N pools - no3_from_nonmyc = no3_from_nonmyc - smin_overflow * no3_from_nonmyc / (sminn * sminfrc_no3 + smin_overflow) ! non mycorrhiza limit uptake from inorganic N pools - if (& - no3_from_nonmyc < 0.0_r8 .or. fn_smin_no3_2myc < 0.0_r8) then - write(iulog,*) 'ERROR: type,myc, nonmyc, sminno3', myc_type, fn_smin_no3_2myc, no3_from_nonmyc, sminn *sminfrc_no3 - smin_overflow, sminfrc_no3 * sminn, fn_smin2myc - call endrun( msg= errMsg(sourcefile, __LINE__)) - end if - endif - end if - if (sminn *(1.0_r8 - sminfrc_no3) <= small_value) then - nh4_from_nonmyc = 0.0_r8 - fn_smin_nh4_2myc = 0.0_r8 - else - if (fn_smin_nh4_2myc + nh4_from_nonmyc > sminn * (1.0_r8 - sminfrc_no3)) then - smin_overflow = (fn_smin_nh4_2myc + nh4_from_nonmyc) - sminn * (1.0_r8 - sminfrc_no3) - fn_smin_nh4_2myc = fn_smin_nh4_2myc - smin_overflow * fn_smin_nh4_2myc / (sminn * (1.0_r8 - sminfrc_no3) + smin_overflow) - nh4_from_nonmyc = nh4_from_nonmyc - smin_overflow * nh4_from_nonmyc / (sminn * (1.0_r8 - sminfrc_no3) + smin_overflow) - if ( & - nh4_from_nonmyc < 0.0_r8 .or. fn_smin_nh4_2myc < 0.0_r8) then - write(iulog,*) 'ERROR: type,myc, nonmyc, sminnh4', myc_type, fn_smin_nh4_2myc, nh4_from_nonmyc, sminn * (1.0_r8 - sminfrc_no3) - smin_overflow, (1.0_r8 - sminfrc_no3) * sminn, fn_smin2myc - call endrun( msg= errMsg(sourcefile, __LINE__)) - end if - endif - endif - - - - ! use new fraction and sminn if they got limited - fn_smin2myc = (fn_smin_no3_2myc + fn_smin_nh4_2myc) /dz /dt ! put it back to gN/m3/s to be consistent with mining fluxes - if(fn_smin2myc > 0.0_r8) then - l_no3_frac = fn_smin_no3_2myc / fn_smin2myc - else - l_no3_frac = 1.0_r8 - endif - - fc_veg2myc=fc_veg2myc_no3 + fc_veg2myc_nh4 - if (myc_type == 1) then ! EcM - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp) - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) - if ( cpool_somc < 0.0_r8 .or. cpool_myc < 0.0_r8 .or. & - npool_myc < 0.0_r8 .or. cpool_somp < 0.0_r8) then - write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp - call endrun( msg= errMsg(sourcefile, __LINE__)) - end if - N_demand_myc = c_use_eff * (1 - f_enz) * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt - N_uptake_myc = fn_smin2myc + l_fn_mining_somp + l_fn_mining_somc - if (N_uptake_myc > N_demand_myc) then - fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg - n_myc_growth = N_demand_myc ! How much N the need to grow - l_c_ecm_enz = fc_veg2myc * f_enz - ! we add the enzymes here into the EcM pool because we first took them away, but now add them again - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + l_c_ecm_enz - ! enzyme flux will go to soma pool in the next update routine - c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow - else ! less N in soil, so we limit N flux to vegetaion and mycorrhiza N demand so their sum is equal to N uptake - fn_myc2veg = (1-f_growth) * N_uptake_myc - n_myc_growth = f_growth * N_uptake_myc - l_c_ecm_enz = fc_veg2myc * f_enz - ! we add the enzymes here into the EcM pool because we first took them away, but now add them again - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + l_c_ecm_enz - c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow - end if - - ! update inout optional arguments - if (present(c_ecm_enz)) then - c_ecm_enz = l_c_ecm_enz - endif - if (present(fc_somp2soma)) then - fc_somp2soma = l_fc_somp2soma - end if - if (present(fc_somc2soma)) then - fc_somc2soma = l_fc_somc2soma - end if - if (present(fn_mining_somp)) then - fn_mining_somp = l_fn_mining_somp - end if - if (present(fn_mining_somc)) then - fn_mining_somc = l_fn_mining_somc - end if - - else ! AM - N_demand_myc = c_use_eff * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt - N_uptake_myc = fn_smin2myc - if (N_uptake_myc > N_demand_myc) then - fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg - n_myc_growth = N_demand_myc ! How much N the need to grow - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc ! How much C they need to grow - c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow - - else - fn_myc2veg = (1-f_growth) * N_uptake_myc - n_myc_growth = f_growth * N_uptake_myc - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc / fc_veg2myc - c_myc_resp = fc_veg2myc - c_myc_growth - end if - endif - - fno3_myc2veg = fn_myc2veg * l_no3_frac ! Amount of NO3 / NH4 mycorrhiza could give to plant - fnh4_myc2veg = fn_myc2veg * (1 - l_no3_frac) - no3_unpaid = fno3_myc2veg * dz * dt - no3_from_myc ! plants did not actually get all the promised nitrogen (NO3 / NH4) - nh4_unpaid = fnh4_myc2veg * dz * dt - nh4_from_myc - - !if (no3_unpaid + nh4_unpaid < 0) then - ! message = "N flux from AM mycorrhiza to plant is greater than mycorrhiza can actually give to the plant" - ! call endrun(msg=message) - !else - ! Bringing nitrogen fluxes to vegetation back to gN/m2 - no3_from_myc = fno3_myc2veg * dz * dt ! if we can give more nitrogen than we promised just give it - nh4_from_myc = fnh4_myc2veg * dz * dt - !endif - if ( no3_from_myc < 0.0_r8 .or. nh4_from_myc < 0.0_r8 & - ) then - write(iulog,*) 'ERROR: type,no3_from_myc, nh4_from_myc',myc_type, no3_from_myc, nh4_from_myc, fc_veg2myc_no3,fc_veg2myc_nh4, l_no3_frac, l_fn_mining_somp,l_fn_mining_somc - call endrun( msg= errMsg(sourcefile, __LINE__)) - end if - end subroutine fun_fluxes_myc_update2 - - - - !Moisture function, based on testbed code: https://github.com/wwieder/biogeochem_testbed/blob/957a5c634b9f2d0b4cdba0faa06b5a91216ace33/SOURCE_CODE/mimics_cycle.f90#L401-L419 real(r8) function r_moist(h2osoi_liq,watsat, h2osoi_ice, dz) !As in testbed (and CLM) version of MIMICS diff --git a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 index e22333a26b..dd1dc15766 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 @@ -139,8 +139,6 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, phr_vr => soilbiogeochem_carbonflux_inst%phr_vr_col , & ! Input: [real(r8) (:,:) ] potential HR (gC/m3/s) fphr => soilbiogeochem_carbonflux_inst%fphr_col , & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic - c_am_resp_vr => soilbiogeochem_carbonflux_inst%c_am_resp_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C respiration flux for AM mycorrhiza (gC/m3/s) - c_ecm_resp_vr => soilbiogeochem_carbonflux_inst%c_ecm_resp_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C respiration flux for ECM mycorrhiza (gC/m3/s) c_am_growth_vr => soilbiogeochem_carbonflux_inst%c_am_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C growth flux for AM mycorrhiza (gC/m3/s) c_ecm_growth_vr => soilbiogeochem_carbonflux_inst%c_ecm_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C growth flux for ECM mycorrhiza (gC/m3/s) n_am_growth_vr => soilbiogeochem_nitrogenflux_inst%n_am_growth_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved N growth flux for AM mycorrhiza (gC/m3/s) @@ -148,7 +146,8 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, c_ecm_enz_vr => soilbiogeochem_carbonflux_inst%c_ecm_enz_vr_col , & ! Input: [real(r8) (:,:) ] vertically resolved C enzyme flux for ECM mycorrhiza (goes from plant) (gC/m3/s) n_somc2ecm_vr => soilbiogeochem_nitrogenflux_inst%n_somc2ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:) ]nitrogen mining from ECM mycorrhiza n_somp2ecm_vr => soilbiogeochem_nitrogenflux_inst%n_somp2ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:) ]nitrogen mining from ECM mycorrhiza - c_somc2soma_vr => soilbiogeochem_carbonflux_inst%c_somc2soma_vr_col(:,:) , & ! Input: [real(r8) (:,:) carbon release from mining from somp pool + c_somc2soma_vr => soilbiogeochem_carbonflux_inst%c_somc2soma_vr_col(:,:) , & ! Input: [real(r8) (:,:) carbon release from mining from somс pool + c_somp2soma_vr => soilbiogeochem_carbonflux_inst%c_somp2soma_vr_col(:,:) , & ! Input: [real(r8) (:,:) carbon release from mining from somp pool sminno3_to_ecm_vr => soilbiogeochem_nitrogenflux_inst%sminno3_to_ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to ECM sminno3_to_am_vr => soilbiogeochem_nitrogenflux_inst%sminno3_to_am_vr_col(:,:) , & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to AM sminnh4_to_ecm_vr => soilbiogeochem_nitrogenflux_inst%sminnh4_to_ecm_vr_col(:,:) , & ! Input: [real(r8) (:,:)No3 flux from soil NO3 to ECM @@ -314,8 +313,8 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, else if (cascade_receiver_pool(k) == i_phys_som) then decomp_cascade_ntransfer_vr(c,j,k) = decomp_cascade_ntransfer_vr(c,j,k) - n_somp2ecm_vr(c,j) end if - - elseif (cascade_receiver_pool(k) == i_avl_som) then + endif + if (cascade_receiver_pool(k) == i_avl_som) then ! carbon release associated with mining if (cascade_donor_pool(k) == i_chem_som) then decomp_cascade_ctransfer_vr(c,j,k) = decomp_cascade_ctransfer_vr(c,j,k) + c_somc2soma_vr(c,j) @@ -323,15 +322,16 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, decomp_cascade_ctransfer_vr(c,j,k) = decomp_cascade_ctransfer_vr(c,j,k) + c_somp2soma_vr(c,j) end if end if - ! fluxes that are not part of the cascade. - decomp_cpools_vr(c,j,i_ecm_myc) = decomp_cpools_vr(c,j,i_ecm_myc) + c_ecm_growth_vr(c,j) * dt - decomp_npools_vr(c,j,i_ecm_myc) = decomp_npools_vr(c,j,i_ecm_myc) + (n_ecm_growth_vr(c,j) + & - sminno3_to_ecm_vr(c,j) + sminnh4_to_ecm_vr(c,j)) * dt - decomp_cpools_vr(c,j,i_am_myc) = decomp_cpools_vr(c,j,i_am_myc) + c_am_growth_vr(c,j) * dt - decomp_npools_vr(c,j,i_am_myc) = decomp_npools_vr(c,j,i_am_myc) + (n_ecm_growth_vr(c,j) + & - sminno3_to_am_vr(c,j) + sminnh4_to_am_vr(c,j)) * dt - decomp_cpools_vr(c,j,i_avl_som) = decomp_cpools_vr(c,j,i_avl_som) + c_ecm_enz_vr(c,j) * dt + end do ! transitions + ! fluxes that are not part of the cascade. + decomp_cpools_vr(c,j,i_ecm_myc) = decomp_cpools_vr(c,j,i_ecm_myc) + c_ecm_growth_vr(c,j) * dt + decomp_npools_vr(c,j,i_ecm_myc) = decomp_npools_vr(c,j,i_ecm_myc) + (n_ecm_growth_vr(c,j) + & + sminno3_to_ecm_vr(c,j) + sminnh4_to_ecm_vr(c,j)) * dt + decomp_cpools_vr(c,j,i_am_myc) = decomp_cpools_vr(c,j,i_am_myc) + c_am_growth_vr(c,j) * dt + decomp_npools_vr(c,j,i_am_myc) = decomp_npools_vr(c,j,i_am_myc) + (n_ecm_growth_vr(c,j) + & + sminno3_to_am_vr(c,j) + sminnh4_to_am_vr(c,j)) * dt + decomp_cpools_vr(c,j,i_avl_som) = decomp_cpools_vr(c,j,i_avl_som) + c_ecm_enz_vr(c,j) * dt end do ! layer enddo !column From 7a650f160c94828789ef821f09c517990fef71fd Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 20 Sep 2024 18:22:31 +0200 Subject: [PATCH 10/17] fix enzymes. --- src/biogeochem/CNFUNMIMICSplusMod.F90 | 7 ++--- ...ilBiogeochemDecompCascadeMIMICSplusMod.F90 | 27 +++++++++---------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index dc1bc3d5dc..3ada20d3ff 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -791,7 +791,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s unmetDemand = .TRUE. plant_ndemand_pool_step(p,imyc) = plant_ndemand_pool(p) * n_uptake_myc_frac(p,imyc) - npp_remaining(p,imyc) = availc(p)*dt * n_uptake_myc_frac(p,imyc) + npp_remaining(p,imyc) = availc(p)*dt * n_uptake_myc_frac(p,imyc) ! gC/m2 ! COST FIXATION PATHWAY ! checks which photosyntetic pathway plant has (C3 / C4) and if they can do nitrogen fixation @@ -840,9 +840,6 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s ,big_cost,kc_nonmyc(ivt(p)),kn_nonmyc(ivt(p)) ,rootc_dens_step,crootfr(p,j),smallValue) end do - ! Remove C required to pair with N from passive uptake from the available pool. - npp_remaining(p,imyc) = npp_remaining(p,imyc) - total_N_conductance = 0.0_r8 fix_loop: do FIX =plants_are_fixing, plants_not_fixing !loop around percentages of fixers and nonfixers, with differnt costs. @@ -1114,7 +1111,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s if(FIX == plants_are_fixing)then n_paths_acc(p,imyc,ipfix) = n_paths_acc(p,imyc,ipfix) + n_from_paths(p,j,ipfix) - npp_paths_acc(p,imyc,ipfix) = npp_paths_acc(p,imyc,ipfix) + npp_to_paths(p,j,ipfix) + npp_paths_acc(p,imyc,ipfix) = npp_paths_acc(p,imyc,ipfix) + npp_to_paths(p,j,ipfix) end if end do diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 0b588237f5..1d46f1e969 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -2015,10 +2015,9 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ !LOCAL VARIABLES real(r8), parameter :: secphr = 60.0_r8 * 60.0_r8 real(r8), parameter :: f_enz = 0.1_r8 ! [-]Fraction of C from vegetation to EcM, that goes into SOMa for mining - real(r8), parameter :: f_growth = 0.5_r8 ! [-] Fraction of mycorrhizal N uptake that needs to stay within the fungi (not given to plant) real(r8), parameter :: small_Value = 1.0e-6_r8 real(r8) :: dt - + real(r8) :: f_growth ! [-] Fraction of mycorrhizal N uptake that needs to stay within the fungi (not given to plant) real(r8) :: fn_myc2veg ! nitrogen fluxes mycorrhiza to vegetation real(r8) :: fn_smin2myc ! nitrogen flux from mineral soil to myc [gN/m3/s] real(r8) :: fc_somp2soma,fc_somc2soma ! carbon fluxes som to som due to mining [gC/m3/s] @@ -2035,7 +2034,7 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ else c_use_eff = params_inst%mimicsplus_mge_am endif - + f_growth = c_use_eff ! in original mimics+ code this is used for some reasom, so here it is for consistency fn_smin2myc = (params_inst%mimicsplus_vmax_myc / secphr) * sminn / dz * & (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) @@ -2306,7 +2305,7 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, l_no3_frac = 1.0_r8 endif - fc_veg2myc=fc_veg2myc_no3 + fc_veg2myc_nh4 + fc_veg2myc=(fc_veg2myc_no3 + fc_veg2myc_nh4)/dz/dt if (myc_type == 1) then ! EcM call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp) call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) @@ -2315,23 +2314,23 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp call endrun( msg= errMsg(sourcefile, __LINE__)) end if - N_demand_myc = c_use_eff * (1 - f_enz) * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt + N_demand_myc = c_use_eff * (1.0_r8 - f_enz) * fc_veg2myc / params_inst%mimicsplus_cn_myc N_uptake_myc = fn_smin2myc + l_fn_mining_somp + l_fn_mining_somc if (N_uptake_myc > N_demand_myc) then fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg n_myc_growth = N_demand_myc ! How much N the need to grow - l_c_ecm_enz = fc_veg2myc * f_enz + l_c_ecm_enz = fc_veg2myc * f_enz * c_use_eff ! we add the enzymes here into the EcM pool because we first took them away, but now add them again - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + l_c_ecm_enz - ! enzyme flux will go to soma pool in the next update routine - c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + ! enzyme flux will go to soma pool in the next update + c_myc_resp = fc_veg2myc - (c_myc_growth + l_c_ecm_enz) ! C that they don't need to grow else ! less N in soil, so we limit N flux to vegetaion and mycorrhiza N demand so their sum is equal to N uptake fn_myc2veg = (1-f_growth) * N_uptake_myc + c_use_eff = f_growth * N_uptake_myc * params_inst%mimicsplus_cn_myc / (1.0_r8 - f_enz) / fc_veg2myc n_myc_growth = f_growth * N_uptake_myc - l_c_ecm_enz = fc_veg2myc * f_enz - ! we add the enzymes here into the EcM pool because we first took them away, but now add them again - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + l_c_ecm_enz - c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow + l_c_ecm_enz = fc_veg2myc * f_enz * c_use_eff + c_myc_growth = c_use_eff * fc_veg2myc + c_myc_resp = fc_veg2myc - (c_myc_growth + l_c_ecm_enz) ! C that they don't need to grow end if ! update inout optional arguments @@ -2352,7 +2351,7 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, end if else ! AM - N_demand_myc = c_use_eff * (fc_veg2myc_no3 + fc_veg2myc_nh4) / params_inst%mimicsplus_cn_myc / dz / dt + N_demand_myc = c_use_eff * (fc_veg2myc) / params_inst%mimicsplus_cn_myc N_uptake_myc = fn_smin2myc if (N_uptake_myc > N_demand_myc) then fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg From 5afe2590543a50aba9bb1e2fe130dc81eb11548b Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 20 Sep 2024 18:32:37 +0200 Subject: [PATCH 11/17] fix mining --- src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 1d46f1e969..96337969db 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -2120,7 +2120,7 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_myc, fc_som2soma ! Nitrogen mining flux if (fc_som2soma > small_value) then if (npool_myc > small_value) then - fn_mining_som = fc_som2soma * (npool_myc / cpool_myc ) + fn_mining_som = fc_som2soma * (npool_som / cpool_som ) else fn_mining_som = 0.0_r8 fc_som2soma = 0.0_r8 From 8ae356881c41c361792ad47554679878a0745ef6 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 20 Sep 2024 18:59:54 +0200 Subject: [PATCH 12/17] another mining fix --- ...oilBiogeochemDecompCascadeMIMICSplusMod.F90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 96337969db..b3fcc24de5 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -1952,8 +1952,8 @@ subroutine calc_myc_roi(cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_somc, & fn_mining_somc = 0.0_r8 if (myc_type == 1) then ! check units - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,fc_somp2soma,fn_mining_somp) !,r_myc) - call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_myc,fc_somc2soma,fn_mining_somc) !,r_myc) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somp,fc_somp2soma,fn_mining_somp) !,r_myc) + call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_somc,fc_somc2soma,fn_mining_somc) !,r_myc) endif @@ -2044,8 +2044,8 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ fn_mining_somp = 0.0_r8 fn_mining_somc = 0.0_r8 if (myc_type == 1) then - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,fc_somp2soma,fn_mining_somp) ! gN/m3/s - call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_myc,fc_somc2soma,fn_mining_somc) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somp,fc_somp2soma,fn_mining_somp) ! gN/m3/s + call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_somc,fc_somc2soma,fn_mining_somc) endif @@ -2093,7 +2093,7 @@ end subroutine cost_FUN - subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_myc, fc_som2soma,fn_mining_som) + subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_som, fc_som2soma,fn_mining_som) ! DESCRIPTION: ! Calculates mining of ectomycorrhizal fungi for nitrogen in soil organic matter pools. @@ -2106,7 +2106,7 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_myc, fc_som2soma ! ARGUMENTS: real(r8), intent(in) :: cpool_som ! SOM pool [gC/m3] real(r8), intent(in) :: cpool_myc ! Carbon pool of mycorrhiza [gC/m3] - real(r8), intent(in) :: npool_myc ! Nitrogen pool of mycorrhiza [gC/m3] + real(r8), intent(in) :: npool_som ! Nitrogen pool of soil [gC/m3] real(r8), intent(in) :: dz ! layer thickness [m] real(r8), intent(inout) :: fc_som2soma ! carbon flux to available SOM pool [gC/m3/s] real(r8), intent(inout) :: fn_mining_som ! nitrogen mining flux [gN/m3/s] @@ -2119,7 +2119,7 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_myc, fc_som2soma fc_som2soma = (params_inst%mimicsplus_k_mo / secphr) * dz * cpool_myc * cpool_som ! Nitrogen mining flux if (fc_som2soma > small_value) then - if (npool_myc > small_value) then + if (npool_som > small_value) then fn_mining_som = fc_som2soma * (npool_som / cpool_som ) else fn_mining_som = 0.0_r8 @@ -2307,8 +2307,8 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, fc_veg2myc=(fc_veg2myc_no3 + fc_veg2myc_nh4)/dz/dt if (myc_type == 1) then ! EcM - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp) - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_myc,l_fc_somc2soma,l_fn_mining_somc) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somp,l_fc_somp2soma,l_fn_mining_somp) + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somc,l_fc_somc2soma,l_fn_mining_somc) if ( cpool_somc < 0.0_r8 .or. cpool_myc < 0.0_r8 .or. & npool_myc < 0.0_r8 .or. cpool_somp < 0.0_r8) then write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp From 26b7c9684de0a043c7f0c324e604980a4aed9c72 Mon Sep 17 00:00:00 2001 From: elisacw Date: Mon, 23 Sep 2024 18:44:27 +0200 Subject: [PATCH 13/17] availc changes --- src/biogeochem/CNBalanceCheckMod.F90 | 2 +- src/biogeochem/CNFUNMIMICSplusMod.F90 | 6 +++--- .../SoilBiogeochemDecompCascadeMIMICSplusMod.F90 | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index 9ef0a2bed8..2b360e3ec1 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -76,7 +76,7 @@ subroutine Init(this, bounds) this%cwarning = 1.e-8_r8 this%nwarning = 1.e-7_r8 this%nerror = 1.e-3_r8 - this%cerror = 1.e-7_r8 + this%cerror = 1.e-9_r8 ! original 1.e-7_r8 end subroutine Init !----------------------------------------------------------------------- diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 3ada20d3ff..594ffecb83 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -566,7 +566,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s npp_Nfix => cnveg_carbonflux_inst%npp_Nfix_patch , & ! Output: [real(r8) (:) ] Symbiotic BNF used C (gC/m2/s) npp_Nretrans => cnveg_carbonflux_inst%npp_Nretrans_patch , & ! Output: [real(r8) (:) ] Retranslocation N uptake used C (gC/m2/s) npp_Nuptake => cnveg_carbonflux_inst%npp_Nuptake_patch , & ! Output: [real(r8) (:) ] Total N uptake of FUN used C (gC/m2/s) - npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! Output: [real(r8) (:) ] Total N uptake of FUN used C (gC/m2/s) + npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! Output: [real(r8) (:) ] Total C used for growth in FUN (gC/m2/s) npp_burnedoff => cnveg_carbonflux_inst%npp_burnedoff_patch , & ! Output: [real(r8) (:) ] C that cannot be used for N uptake(gC/m2/s) leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ] plant_ndemand => cnveg_nitrogenflux_inst%plant_ndemand_patch , & ! Iutput: [real(r8) (:) ] N flux required to support initial GPP (gN/m2/s) @@ -774,7 +774,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end if ! end for deciduous ! Avaliable carbon for growth or Nitrogen uptake - !availc_pool(p) = availc(p) * dt + availc(p) = availc(p) * dt !! if (availc(p) > 0._r8) then do j = 1, nlevdecomp @@ -791,7 +791,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s unmetDemand = .TRUE. plant_ndemand_pool_step(p,imyc) = plant_ndemand_pool(p) * n_uptake_myc_frac(p,imyc) - npp_remaining(p,imyc) = availc(p)*dt * n_uptake_myc_frac(p,imyc) ! gC/m2 + npp_remaining(p,imyc) = availc(p) * n_uptake_myc_frac(p,imyc) ! gC/m2 !og availc(p) *dt ! COST FIXATION PATHWAY ! checks which photosyntetic pathway plant has (C3 / C4) and if they can do nitrogen fixation diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index b3fcc24de5..898be32f18 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -2035,6 +2035,7 @@ subroutine cost_FUN(fc_veg2myc,cpool_myc, npool_myc,cpool_somp,cpool_soma,cpool_ c_use_eff = params_inst%mimicsplus_mge_am endif f_growth = c_use_eff ! in original mimics+ code this is used for some reasom, so here it is for consistency + ! Change this back to 0.5 coming from parameter file at some point fn_smin2myc = (params_inst%mimicsplus_vmax_myc / secphr) * sminn / dz * & (cpool_myc / (cpool_myc + params_inst%mimicsplus_k_m_emyc)) From 4e31b794f9a27f9322415e7bcc62ad51d3217e6e Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 24 Sep 2024 18:27:00 +0200 Subject: [PATCH 14/17] rename paths, add more out. --- .../testmods_dirs/clm/mimicsplus/user_nl_clm | 2 +- src/biogeochem/CNFUNMIMICSplusMod.F90 | 109 +++++++++--------- 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm index adb5db0421..555e670e35 100644 --- a/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsplus/user_nl_clm @@ -16,7 +16,7 @@ hist_dov2xy = .true., .true. hist_fincl3 = 'TOTMYCC', 'SOILC_vr', 'TOTMICC', 'TOTMYCC', 'TOTLITC', 'TOTSOMC', 'TOTLITC_1m', 'TOTSOMC_1m', 'DYN_COL_SOIL_ADJUSTMENTS_C', 'TOTCOLC', 'TOTECOSYSC', 'LIT_MET_C_vr', 'LIT_STR_C_vr', 'SOM_AVL_C_vr', - 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr' + 'SOM_CHEM_C_vr', 'SOM_PHYS_C_vr', 'MIC_COP_C_vr', 'MIC_OLI_C_vr', 'MYC_ECM_C_vr', 'MYC_AM_C_vr', 'AVAILC' hist_fincl5 = 'L1_RESP_FRAC_M1_vr', 'L1_RESP_FRAC_M2_vr', 'L2_RESP_FRAC_M1_vr', 'L2_RESP_FRAC_M2_vr', 'M1_RESP_FRAC_S1_vr', 'M1_RESP_FRAC_S2_vr', 'M1_RESP_FRAC_S3_vr', diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 594ffecb83..8ddd0babc2 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -61,9 +61,8 @@ module CNFUNMIMICSplusMod integer, parameter :: ipnmno3 = 3 ! Process number for active nonmyc uptake of NO3. integer, parameter :: ipnmnh4 = 4 ! Process number for active nonmyc uptake of NH4. integer, parameter :: ipfix = 5 ! Process number for fixing. orginal version in FUN: [icost...] - integer, parameter :: ipret = 6 ! Process number for retranslocation. - real(r8), parameter :: big_cost = 5.e+7_r8! An arbitrarily large cost + real(r8), parameter :: big_cost = 5.e+6_r8! An arbitrarily large cost ! array index when plant is fixing integer, parameter :: plants_are_fixing = 1 @@ -74,7 +73,7 @@ module CNFUNMIMICSplusMod integer, parameter :: am_step = 2 integer, private, parameter :: nmyc = 2 ! Number of calculation part orginal version in FUN: [nstp] - integer, private, parameter :: npath6 = 6 ! Number of N transport pathways orginal version in FUN: [ncost6] + integer, private, parameter :: npaths = 5 ! Number of N transport pathways orginal version in FUN: [ncost6] retranslocation is handled differently ! ! populated in readParamsMod type, public :: cnfunmimicsplus_type @@ -199,7 +198,7 @@ subroutine InitAllocate (this, bounds) allocate(this%npp_uptake(bounds%begp:bounds%endp,1:nmyc)); this%npp_uptake(:,:) = spval - allocate(this%costs_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%costs_paths(:,:,:) = spval + allocate(this%costs_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npaths)); this%costs_paths(:,:,:) = spval allocate(this%sminn_layer(bounds%begc:bounds%endc,1:nlevdecomp)); this%sminn_layer(:,:) = spval @@ -215,15 +214,15 @@ subroutine InitAllocate (this, bounds) ! Uptake fluxes for COST_METHOD=2 ! actual npp to each layer for each uptake process - allocate(this%npp_to_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_to_paths(:,:,:) = spval + allocate(this%npp_to_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npaths)); this%npp_to_paths(:,:,:) = spval - allocate(this%npp_frac_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%npp_frac_paths(:,:,:) = spval + allocate(this%npp_frac_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npaths)); this%npp_frac_paths(:,:,:) = spval - allocate(this%n_from_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npath6)); this%n_from_paths(:,:,:) = spval + allocate(this%n_from_paths(bounds%begp:bounds%endp,1:nlevdecomp,1:npaths)); this%n_from_paths(:,:,:) = spval - allocate(this%n_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6)); this%n_paths_acc(:,:,:) = spval + allocate(this%n_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npaths)); this%n_paths_acc(:,:,:) = spval - allocate(this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6)); this%npp_paths_acc(:,:,:) = spval + allocate(this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npaths)); this%npp_paths_acc(:,:,:) = spval allocate(this%no3_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%no3_myc_to_plant_col(:,:) = spval allocate(this%nh4_myc_to_plant_col(bounds%begc:bounds%endc, 1:nlevdecomp)); this%nh4_myc_to_plant_col(:,:) = spval @@ -263,12 +262,12 @@ subroutine SetZeros (this, bounds, soilbiogeochem_carbonflux_inst,soilbiogeochem this%litterfall_n_step(begp:endp,1:nmyc) = 0._r8 this%litterfall_c_step(begp:endp,1:nmyc) = 0._r8 this%npp_remaining(begp:endp,1:nmyc) = 0._r8 - this%costs_paths(begp:endp,1:nlevdecomp,1:npath6) = big_cost - this%npp_to_paths(begp:endp,1:nlevdecomp,1:npath6) = 0._r8 - this%npp_frac_paths(begp:endp,1:nlevdecomp,1:npath6) = 0._r8 - this%n_from_paths(begp:endp,1:nlevdecomp,1:npath6) = 0._r8 - this%n_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6) = 0._r8 - this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npath6) = 0._r8 + this%costs_paths(begp:endp,1:nlevdecomp,1:npaths) = big_cost + this%npp_to_paths(begp:endp,1:nlevdecomp,1:npaths) = 0._r8 + this%npp_frac_paths(begp:endp,1:nlevdecomp,1:npaths) = 0._r8 + this%n_from_paths(begp:endp,1:nlevdecomp,1:npaths) = 0._r8 + this%n_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npaths) = 0._r8 + this%npp_paths_acc(bounds%begp:bounds%endp,1:nmyc,1:npaths) = 0._r8 this%n_retrans_acc(bounds%begp:bounds%endp,1:nmyc) = 0._r8 this%free_nretrans_acc(bounds%begp:bounds%endp,1:nmyc) = 0._r8 this%npp_retrans_acc(bounds%begp:bounds%endp,1:nmyc) = 0._r8 @@ -467,8 +466,8 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s real(r8) :: ndays_off ! number of days to complete leaf offset real(r8) :: frac_ideal_C_use ! How much less C do we use for 'buying' N than that needed to get to the ideal ratio? fraction. real(r8) :: N_acquired - real(r8) :: N_before_corr - real(r8) :: N_bc(1:npath6) + real(r8) :: N_before_corr(1:npaths) + real(r8) :: C_before_corr(1:npaths) real(r8) :: C_spent real(r8) :: leaf_narea ! leaf n per unit leaf area in gN/m2 (averaged across canopy, which is OK for the cost calculation) real(r8) :: sum_n_acquired ! Sum N aquired from one unit of C (unitless) @@ -839,8 +838,8 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s costs_paths(p,j,ipnmnh4) = fun_cost_nonmyc(sminn_layer_step(p,j,imyc) * (1.0_r8 -sminfrc (c,j)) & ,big_cost,kc_nonmyc(ivt(p)),kn_nonmyc(ivt(p)) ,rootc_dens_step,crootfr(p,j),smallValue) end do - - total_N_conductance = 0.0_r8 + npp_to_spend = 0.0_r8 + total_N_conductance = 1.0_r8/ (npaths * nlevdecomp * big_cost) fix_loop: do FIX =plants_are_fixing, plants_not_fixing !loop around percentages of fixers and nonfixers, with differnt costs. if(FIX==plants_are_fixing)then ! How much of the carbon in this PFT can in principle be used for fixation? @@ -854,22 +853,23 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s ! has to be zeroed since depend on accumula n_from_paths(p,:,:) = 0.0_r8 !act and nonmyc boths nh4 and no3 npp_frac_paths(p,:,:) = 0.0_r8 + npp_to_paths(p,:,:) = 0.0_r8 ! Calculate Integrated Resistance OF WHOLE SOIL COLUMN sum_n_acquired = 0.0_r8 - total_N_conductance = 0.0_r8 + total_N_conductance = 1.0_r8/ (npaths * nlevdecomp * big_cost) do j = 1, nlevdecomp ! Method changed from FUN-resistors method to a method which allocates fluxs based on conductance. rosief ! Sum the conductances total_N_conductance = total_N_conductance + 1._r8/ costs_paths(p,j,ipano3) & + 1._r8/ costs_paths(p,j,ipanh4) + 1._r8/ costs_paths(p,j,ipnmno3) & - + 1._r8/ costs_paths(p,j,ipnmnh4) + + 1._r8/ costs_paths(p,j,ipnmnh4) !N/C if(FIX==plants_are_fixing)then - total_N_conductance = total_N_conductance + 1._r8 * 1._r8/ costs_paths(p,j,ipfix) + total_N_conductance = total_N_conductance + 1._r8/ costs_paths(p,j,ipfix) end if end do - do j = 1, nlevdecomp + do j = 1, nlevdecomp ! Calculate npp allocation to pathways proportional to their exchange rate (N/C) @@ -897,9 +897,9 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end if end do if (sum_n_acquired>0.0_r8) then - total_N_resistance = max(1.0_r8/sum_n_acquired,1.0_r8/big_cost) + total_N_resistance = 1.0_r8/sum_n_acquired else - total_N_resistance = 1.0_r8/big_cost + total_N_resistance = 1.0_r8/total_N_conductance !C/N endif free_n_retrans = 0.0_r8 @@ -975,7 +975,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s ! Had to add growth respiration here to balance carbon pool. if (total_N_resistance <= 1.0e-10_r8) then write(iulog,*) 'ERROR: total_N_resistance=', total_N_resistance - do ipath = 1, npath6 + do ipath = 1, npaths do j = 1,nlevdecomp write(iulog,*) 'n_from_paths:', n_from_paths(p,j,ipath), npp_to_paths(p,j,ipath) enddo @@ -984,20 +984,20 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s msg= errMsg(sourcefile, __LINE__)) end if dnpp = npp_to_spend / ( (1.0_r8+grperc(ivt(p)))*(plantCN(p) / total_N_resistance) + 1._r8) - dnpp = dnpp * frac_ideal_C_use + dnpp = dnpp * frac_ideal_C_use !hypothetical amount of N acquired. - dn = dnpp / total_N_resistance + dn = dnpp / total_N_resistance ! do j = 1,nlevdecomp ! RF How much of this NPP carbon do we allocate to the different pathways? fraction x gC/m2/s? ! Could this code now be put in a matrix? - npp_to_paths(p,j,ipano3:ipnmnh4) = npp_frac_paths(p,j,ipano3:ipnmnh4) * dNPP + npp_to_paths(p,j,ipano3:ipnmnh4) = npp_frac_paths(p,j,ipano3:ipnmnh4) * dnpp if(FIX==plants_are_fixing)then - npp_to_paths(p,j,ipfix) = npp_frac_paths(p,j,ipfix) * dNPP + npp_to_paths(p,j,ipfix) = npp_frac_paths(p,j,ipfix) * dnpp else npp_to_paths(p,j,ipfix) = 0.0_r8 end if @@ -1011,13 +1011,11 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end if end do - N_bc=0.0_r8 ! Check if LIMITS of pools were exceeded: do j = 1,nlevdecomp - N_before_corr = sum(n_from_paths(p,j,ipano3:ipnmnh4)) - N_bc=n_from_paths(p,j,:) - C_spent = sum(npp_to_paths(p,j,ipano3:ipnmnh4)) - if ((sminn_layer_step(p,j,imyc)) > 0.0_r8) then + N_before_corr(1:npaths) = n_from_paths(p,j,1:npaths) + C_before_corr(1:npaths) = npp_to_paths(p,j,1:npaths) + if ((sminn_layer_step(p,j,imyc)) > 0.0_r8 .or. imyc == ecm_step) then if (imyc == ecm_step) then sminno3_to_ecm_vr_patch(p,j) = 0.0_r8 sminnh4_to_ecm_vr_patch(p,j) = 0.0_r8 @@ -1043,32 +1041,36 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s sminno3_to_am_vr_patch(p,j), sminnh4_to_am_vr_patch(p,j), & c_am_resp_vr_patch(p,j), c_am_growth_vr_patch(p,j), n_am_growth_vr_patch(p,j)) endif + sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) + sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) + sminnh4_to_am_vr_patch(p,j) = sminnh4_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) + sminnh4_to_ecm_vr_patch(p,j) = sminnh4_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) if (sminno3_to_am_vr_patch(p,j) + sminno3_to_am_vr_patch(p,j) + & sminnh4_to_ecm_vr_patch(p,j) + sminnh4_to_ecm_vr_patch(p,j) + & n_from_paths(p,j,ipnmno3) + n_from_paths(p,j,ipnmnh4) > sminn_layer_step(p,j,imyc) ) then - write(iulog,*) 'ERROR: myc_type is=',imyc, N_before_corr - sum(n_from_paths(p,j,ipano3:ipnmnh4)) - write(iulog,*) 'ERROR: N before corrections=',N_before_corr, N_bc + write(iulog,*) 'ERROR: myc_type is=',imyc + write(iulog,*) 'ERROR: N before corrections=',N_before_corr write(iulog,*) 'ERROR: More N acquired before correcting for sminn diff: ', sum(n_from_paths(p,j,ipano3:ipnmnh4)), n_from_paths(p,j,:) - write(iulog,*) 'ERROR: More cost_paths: ', N_before_corr,costs_paths(p,j,ipano3:ipnmnh4) + write(iulog,*) 'ERROR: More cost_paths: ', costs_paths(p,j,ipano3:ipnmnh4) write(iulog,*) 'ERROR: More cost_paths: ', '0.0',costs_paths(p,j,ipano3:ipnmnh4) write(iulog,*) 'ERROR: C_spent and npp: ', C_spent,npp_to_paths(p,j,ipano3:ipnmnh4) write(iulog,*) 'ERROR: Cpent diff:', C_spent - sum(npp_to_paths(p,j,ipano3:ipnmnh4)) call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & msg= errMsg(sourcefile, __LINE__)) endif - npp_to_paths(p,j,ipnmno3) = n_from_paths(p,j,ipnmno3) * costs_paths(p,j,ipnmno3) - npp_to_paths(p,j,ipnmnh4) = n_from_paths(p,j,ipnmnh4) * costs_paths(p,j,ipnmnh4) - - if ( sum(npp_to_paths(p,j,ipano3:ipnmnh4)) > C_spent) then - write(iulog,*) 'ERROR: C spent before correcting for sminn diff: ', C_spent ,npp_to_paths(p,j,ipano3:ipnmnh4) - call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & - msg= errMsg(sourcefile, __LINE__)) + if (n_from_paths(p,j,ipnmno3) > 0.0_r8 .and. N_before_corr(ipnmno3) > 0.0_r8) then + npp_to_paths(p,j,ipnmno3) = n_from_paths(p,j,ipnmno3) - C_before_corr(ipnmno3) * & + (N_before_corr(ipnmno3)-n_from_paths(p,j,ipnmno3)) / N_before_corr(ipnmno3) + else + npp_to_paths(p,j,ipnmno3) = 0.0_r8 + endif + if (n_from_paths(p,j,ipnmnh4) > 0.0_r8 .and. N_before_corr(ipnmnh4) > 0.0_r8) then + npp_to_paths(p,j,ipnmnh4) = n_from_paths(p,j,ipnmnh4) - C_before_corr(ipnmnh4) * & + (N_before_corr(ipnmnh4)-n_from_paths(p,j,ipnmnh4)) / N_before_corr(ipnmnh4) + else + npp_to_paths(p,j,ipnmnh4) = 0.0_r8 endif ! switch units to gN/m3/s for use in other routines - sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - sminnh4_to_am_vr_patch(p,j) = sminnh4_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) - sminnh4_to_ecm_vr_patch(p,j) = sminnh4_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) else do ipath = ipano3,ipnmnh4 npp_to_paths(p,imyc,ipath) = 0.0_r8 @@ -1164,7 +1166,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s write(iulog,*) 'n_uptake_myc_frac_ecm=', n_uptake_myc_frac(p,am_step) write(iulog,*) ' sminn_layer_step_ecm=', sminn_layer_step(p,j,ecm_step) write(iulog,*) ' sminn_layer_step_am=', sminn_layer_step(p,j,am_step) - do ipath = 1, npath6 + do ipath = 1, npaths write(iulog,*) 'n_from_paths:', n_from_paths(p,j,ipath), npp_to_paths(p,j,ipath) end do call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & @@ -1233,7 +1235,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s write(iulog,*) 'ERROR: npp_Nretrans(p): ', npp_Nretrans(p) write(iulog,*) 'npp_growth(p): ',npp_growth(p) - do ipath = 1,npath6 + do ipath = 1,npaths write(iulog,*) 'ERROR nppaths_ecm:',ipath, npp_paths_acc(p,1,ipath) write(iulog,*) 'ERROR nppaths_am:',ipath, npp_paths_acc(p,1,ipath) enddo @@ -1252,11 +1254,12 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, & msg= errMsg(sourcefile, __LINE__)) endif - if (availc(p) - npp_Nuptake(p) - npp_growth(p) < 0._r8) then + if (availc(p) - npp_Nuptake(p) - npp_growth(p) < -1.e-8_r8) then write(iulog,*) 'ERROR: balance Cfun is negative: ' write(iulog,*) 'Acailc, npp_Nuptake/growth:',availc(p), npp_Nuptake(p),npp_growth(p) + write(iulog,*) 'soilchange, burned off c', soilc_change(p), burned_off_carbon/dt write(iulog,*), 'Excess carbon, npp_Nretrans,freeretrans',excess_carbon_acc/dt,npp_Nretrans(p),free_retransn_to_npool(p) - do ipath = 1,npath6 + do ipath = 1,npaths write(iulog,*) 'ERROR nppaths_ecm:',ipath, npp_paths_acc(p,1,ipath) write(iulog,*) 'ERROR nppaths_am:',ipath, npp_paths_acc(p,2,ipath) enddo From d5450eb1b4eef08b41e5939f4ca32a42acc9e9ab Mon Sep 17 00:00:00 2001 From: elisacw Date: Wed, 25 Sep 2024 23:27:25 +0200 Subject: [PATCH 15/17] revert --- src/biogeochem/CNFUNMIMICSplusMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 8ddd0babc2..29369f320b 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -829,7 +829,7 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s end if end if end do - + ! Non-mycorrhizal Uptake Cost do j = 1,nlevdecomp rootc_dens_step = rootc_dens(p,j) * n_uptake_myc_frac(p,imyc) From 1f25020373cf688258af908df2fd3897e2dd3544 Mon Sep 17 00:00:00 2001 From: elisacw Date: Fri, 25 Oct 2024 16:47:06 +0200 Subject: [PATCH 16/17] add myc tmp variables --- src/biogeochem/CNFUNMIMICSplusMod.F90 | 73 +++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/biogeochem/CNFUNMIMICSplusMod.F90 b/src/biogeochem/CNFUNMIMICSplusMod.F90 index 29369f320b..cbe6648193 100644 --- a/src/biogeochem/CNFUNMIMICSplusMod.F90 +++ b/src/biogeochem/CNFUNMIMICSplusMod.F90 @@ -506,6 +506,24 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s real(r8) :: c_somc2soma_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp) ! carbon release from mining from somc pool real(r8) :: c_somp2soma_vr_patch(bounds%begp:bounds%endp, 1:nlevdecomp) ! carbon release from mining from somp pool + ! Update mycorrhizal variables + real(r8) :: n_ecm_growth_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: c_ecm_growth_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: c_ecm_resp_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: c_ecm_enz_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: n_am_growth_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: c_am_growth_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: c_am_resp_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: sminno3_to_ecm_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: sminno3_to_am_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: sminnh4_to_ecm_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: sminnh4_to_am_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: n_somc2ecm_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: n_somp2ecm_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) + real(r8) :: c_somc2soma_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) ! carbon release from mining from somc pool + real(r8) :: c_somp2soma_vr_patch_tmp(bounds%begp:bounds%endp, 1:nlevdecomp) ! carbon release from mining from somp pool + + real(r8) :: n_active_no3_vr(bounds%begp:bounds%endp, 1:nlevdecomp) ! Layer mycorrhizal no3 uptake (gN/m2) real(r8) :: n_nonmyc_no3_vr(bounds%begp:bounds%endp, 1:nlevdecomp) ! Layer non-myc no3 uptake (gN/m2) real(r8) :: n_active_nh4_vr(bounds%begp:bounds%endp, 1:nlevdecomp) ! Layer mycorrhizal nh4 uptake (gN/m2) @@ -690,6 +708,22 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s sminnh4_to_ecm_vr_patch(p,j) =0.0_r8 ! NH4 flux from soil to ECM sminnh4_to_am_vr_patch(p,j) =0.0_r8 ! NH4 flux from soil to AM + n_ecm_growth_vr_patch_tmp(p,j)=0.0_r8 + c_ecm_growth_vr_patch_tmp(p,j)=0.0_r8 + c_ecm_resp_vr_patch_tmp(p,j) =0.0_r8 + c_ecm_enz_vr_patch_tmp(p,j) =0.0_r8 + n_am_growth_vr_patch_tmp(p,j) =0.0_r8 + c_am_growth_vr_patch_tmp(p,j) =0.0_r8 + c_am_resp_vr_patch_tmp(p,j) =0.0_r8 + sminno3_to_ecm_vr_patch_tmp(p,j) =0.0_r8 + sminno3_to_am_vr_patch_tmp(p,j) =0.0_r8 + sminnh4_to_ecm_vr_patch_tmp(p,j) =0.0_r8 + sminnh4_to_am_vr_patch_tmp(p,j) =0.0_r8 + n_somc2ecm_vr_patch_tmp(p,j) =0.0_r8 + n_somp2ecm_vr_patch_tmp(p,j) =0.0_r8 + c_somc2soma_vr_patch_tmp(p,j) =0.0_r8 + c_somp2soma_vr_patch_tmp(p,j) =0.0_r8 + call calc_myc_roi(decomp_cpools_vr(c,j,i_ecm_myc),decomp_npools_vr(c,j,i_ecm_myc) , & decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & @@ -1017,30 +1051,51 @@ subroutine CNFUNMIMICSplus (bounds, num_soilc, filter_soilc, num_soilp ,filter_s C_before_corr(1:npaths) = npp_to_paths(p,j,1:npaths) if ((sminn_layer_step(p,j,imyc)) > 0.0_r8 .or. imyc == ecm_step) then if (imyc == ecm_step) then - sminno3_to_ecm_vr_patch(p,j) = 0.0_r8 - sminnh4_to_ecm_vr_patch(p,j) = 0.0_r8 + sminno3_to_ecm_vr_patch_tmp(p,j) = 0.0_r8 + sminnh4_to_ecm_vr_patch_tmp(p,j) = 0.0_r8 call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_ecm_myc),decomp_npools_vr(c,j,i_ecm_myc), & decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & sminn_layer_step(p,j,imyc), sminfrc(c,j), ecm_step, dzsoi_decomp(j), & npp_to_paths(p,j,ipano3), npp_to_paths(p,j,ipanh4), & n_from_paths(p,j,ipnmno3), n_from_paths(p,j,ipnmnh4),n_from_paths(p,j,ipano3), n_from_paths(p,j,ipanh4), & - sminno3_to_ecm_vr_patch(p,j), sminnh4_to_ecm_vr_patch(p,j), & - c_ecm_resp_vr_patch(p,j), c_ecm_growth_vr_patch(p,j), n_ecm_growth_vr_patch(p,j), c_ecm_enz_vr_patch(p,j), & - c_somp2soma_vr_patch(p,j), c_somc2soma_vr_patch(p,j), n_somp2ecm_vr_patch(p,j), n_somc2ecm_vr_patch(p,j)) + sminno3_to_ecm_vr_patch_tmp(p,j), sminnh4_to_ecm_vr_patch_tmp(p,j), & + c_ecm_resp_vr_patch_tmp(p,j), c_ecm_growth_vr_patch_tmp(p,j), n_ecm_growth_vr_patch_tmp(p,j), c_ecm_enz_vr_patch_tmp(p,j), & + c_somp2soma_vr_patch_tmp(p,j), c_somc2soma_vr_patch_tmp(p,j), n_somp2ecm_vr_patch_tmp(p,j), n_somc2ecm_vr_patch_tmp(p,j)) ! update npp_to_nonmyc with cost else - sminno3_to_am_vr_patch(p,j) = 0.0_r8 - sminnh4_to_am_vr_patch(p,j) = 0.0_r8 + sminno3_to_am_vr_patch_tmp(p,j) = 0.0_r8 + sminnh4_to_am_vr_patch_tmp(p,j) = 0.0_r8 call fun_fluxes_myc_update1 (decomp_cpools_vr(c,j,i_am_myc),decomp_npools_vr(c,j,i_am_myc), & decomp_cpools_vr(c,j,i_phys_som),decomp_cpools_vr(c,j,i_avl_som),decomp_cpools_vr(c,j,i_chem_som), & decomp_npools_vr(c,j,i_phys_som),decomp_npools_vr(c,j,i_chem_som), & sminn_layer_step(p,j,imyc), sminfrc(c,j), ecm_step, dzsoi_decomp(j), & npp_to_paths(p,j,ipano3), npp_to_paths(p,j,ipanh4), & n_from_paths(p,j,ipnmno3), n_from_paths(p,j,ipnmnh4),n_from_paths(p,j,ipano3), n_from_paths(p,j,ipanh4), & - sminno3_to_am_vr_patch(p,j), sminnh4_to_am_vr_patch(p,j), & - c_am_resp_vr_patch(p,j), c_am_growth_vr_patch(p,j), n_am_growth_vr_patch(p,j)) + sminno3_to_am_vr_patch_tmp(p,j), sminnh4_to_am_vr_patch_tmp(p,j), & + c_am_resp_vr_patch_tmp(p,j), c_am_growth_vr_patch_tmp(p,j), n_am_growth_vr_patch_tmp(p,j)) endif + + n_ecm_growth_vr_patch(p,j) = n_ecm_growth_vr_patch(p,j) + n_ecm_growth_vr_patch_tmp(p,j) + c_ecm_growth_vr_patch(p,j) = c_ecm_growth_vr_patch(p,j) + c_ecm_growth_vr_patch_tmp(p,j) + c_ecm_resp_vr_patch(p,j) = c_ecm_resp_vr_patch(p,j) + c_ecm_resp_vr_patch_tmp(p,j) + c_ecm_enz_vr_patch(p,j) = c_ecm_enz_vr_patch(p,j) + c_ecm_enz_vr_patch_tmp(p,j) + + n_am_growth_vr_patch(p,j) = n_am_growth_vr_patch(p,j) + n_am_growth_vr_patch_tmp(p,j) + c_am_growth_vr_patch(p,j) = c_am_growth_vr_patch(p,j) + c_am_growth_vr_patch_tmp(p,j) + c_am_resp_vr_patch(p,j) = c_am_resp_vr_patch(p,j) + c_am_resp_vr_patch_tmp(p,j) + + sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j) + sminno3_to_ecm_vr_patch_tmp(p,j) + sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j) + sminno3_to_am_vr_patch_tmp(p,j) + sminnh4_to_ecm_vr_patch(p,j) = sminnh4_to_ecm_vr_patch(p,j) + sminnh4_to_ecm_vr_patch_tmp(p,j) + sminnh4_to_am_vr_patch(p,j) = sminnh4_to_am_vr_patch(p,j) + sminnh4_to_am_vr_patch_tmp(p,j) + n_somc2ecm_vr_patch(p,j) = n_somc2ecm_vr_patch(p,j) + n_somc2ecm_vr_patch_tmp(p,j) + n_somp2ecm_vr_patch(p,j) = n_somp2ecm_vr_patch(p,j) + n_somp2ecm_vr_patch_tmp(p,j) + c_somc2soma_vr_patch(p,j) = c_somc2soma_vr_patch(p,j) + c_somc2soma_vr_patch_tmp(p,j) + c_somp2soma_vr_patch(p,j) = c_somp2soma_vr_patch(p,j) + c_somp2soma_vr_patch_tmp(p,j) + + + sminno3_to_am_vr_patch(p,j) = sminno3_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) sminno3_to_ecm_vr_patch(p,j) = sminno3_to_ecm_vr_patch(p,j)/(dzsoi_decomp(j)*dt) sminnh4_to_am_vr_patch(p,j) = sminnh4_to_am_vr_patch(p,j)/(dzsoi_decomp(j)*dt) From b550b564df2ec6f3b164c033bf3a12fe90f25201 Mon Sep 17 00:00:00 2001 From: elisacw Date: Mon, 28 Oct 2024 20:10:53 +0100 Subject: [PATCH 17/17] try --- ...ilBiogeochemDecompCascadeMIMICSplusMod.F90 | 183 +++++++++++------- 1 file changed, 112 insertions(+), 71 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 index 898be32f18..9fa34ea8c9 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSplusMod.F90 @@ -2103,6 +2103,7 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_som, fc_som2soma ! During this process carbon is release from the chemmically and physically protected SOM pools which enters the avaliable SOM pool. ! USES: + use clm_time_manager, only: get_step_size_real ! ARGUMENTS: real(r8), intent(in) :: cpool_som ! SOM pool [gC/m3] @@ -2113,9 +2114,12 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_som, fc_som2soma real(r8), intent(inout) :: fn_mining_som ! nitrogen mining flux [gN/m3/s] ! LOCAL VARIABLES: - real(r8) :: secphr = 60.0_r8 * 60.0_r8 + real(r8) :: secphr = 60.0_r8 * 60.0_r8 real(r8), parameter :: small_value = 1.e-10_r8 + real(r8) :: dt + dt = get_step_size_real() + ! SOM carbon flux fc_som2soma = (params_inst%mimicsplus_k_mo / secphr) * dz * cpool_myc * cpool_som ! Nitrogen mining flux @@ -2130,6 +2134,16 @@ subroutine calc_myc_mining_rates(dz, cpool_som,cpool_myc, npool_som, fc_som2soma fn_mining_som = 0.0_r8 fc_som2soma = 0.0_r8 endif + ! we need to check that we do not take too much. + if (cpool_som < fc_som2soma * dt) then + fn_mining_som = 0.0_r8 + fc_som2soma = 0.0_r8 + endif + ! same for nitrogen + if (npool_som < fn_mining_som * dt) then + fn_mining_som = 0.0_r8 + fc_som2soma = 0.0_r8 + endif end subroutine calc_myc_mining_rates @@ -2307,87 +2321,114 @@ subroutine fun_fluxes_myc_update1 (cpool_myc, npool_myc, cpool_somp, cpool_soma, endif fc_veg2myc=(fc_veg2myc_no3 + fc_veg2myc_nh4)/dz/dt - if (myc_type == 1) then ! EcM - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somp,l_fc_somp2soma,l_fn_mining_somp) - call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somc,l_fc_somc2soma,l_fn_mining_somc) - if ( cpool_somc < 0.0_r8 .or. cpool_myc < 0.0_r8 .or. & - npool_myc < 0.0_r8 .or. cpool_somp < 0.0_r8) then - write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp - call endrun( msg= errMsg(sourcefile, __LINE__)) - end if - N_demand_myc = c_use_eff * (1.0_r8 - f_enz) * fc_veg2myc / params_inst%mimicsplus_cn_myc - N_uptake_myc = fn_smin2myc + l_fn_mining_somp + l_fn_mining_somc - if (N_uptake_myc > N_demand_myc) then - fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg - n_myc_growth = N_demand_myc ! How much N the need to grow - l_c_ecm_enz = fc_veg2myc * f_enz * c_use_eff - ! we add the enzymes here into the EcM pool because we first took them away, but now add them again - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc - ! enzyme flux will go to soma pool in the next update - c_myc_resp = fc_veg2myc - (c_myc_growth + l_c_ecm_enz) ! C that they don't need to grow - else ! less N in soil, so we limit N flux to vegetaion and mycorrhiza N demand so their sum is equal to N uptake - fn_myc2veg = (1-f_growth) * N_uptake_myc - c_use_eff = f_growth * N_uptake_myc * params_inst%mimicsplus_cn_myc / (1.0_r8 - f_enz) / fc_veg2myc - n_myc_growth = f_growth * N_uptake_myc - l_c_ecm_enz = fc_veg2myc * f_enz * c_use_eff - c_myc_growth = c_use_eff * fc_veg2myc - c_myc_resp = fc_veg2myc - (c_myc_growth + l_c_ecm_enz) ! C that they don't need to grow + if (fc_veg2myc > 0) then + if (myc_type == 1) then ! EcM + call calc_myc_mining_rates(dz, cpool_somp,cpool_myc, npool_somp,l_fc_somp2soma,l_fn_mining_somp) + call calc_myc_mining_rates(dz, cpool_somc,cpool_myc, npool_somc,l_fc_somc2soma,l_fn_mining_somc) + if ( cpool_somc < 0.0_r8 .or. cpool_myc < 0.0_r8 .or. & + npool_myc < 0.0_r8 .or. cpool_somp < 0.0_r8) then + write(iulog,*) 'ERROR: cpool_som,cpool_myc,npool_my',cpool_somp,cpool_somc,cpool_myc, npool_myc,l_fc_somp2soma,l_fn_mining_somp + call endrun( msg= errMsg(sourcefile, __LINE__)) end if - - ! update inout optional arguments - if (present(c_ecm_enz)) then - c_ecm_enz = l_c_ecm_enz + N_demand_myc = c_use_eff * (1.0_r8 - f_enz) * fc_veg2myc / params_inst%mimicsplus_cn_myc + N_uptake_myc = fn_smin2myc + l_fn_mining_somp + l_fn_mining_somc + if (N_uptake_myc > N_demand_myc) then + fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg + n_myc_growth = N_demand_myc ! How much N the need to grow + l_c_ecm_enz = fc_veg2myc * f_enz * c_use_eff + ! we add the enzymes here into the EcM pool because we first took them away, but now add them again + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc + ! enzyme flux will go to soma pool in the next update + c_myc_resp = fc_veg2myc - (c_myc_growth + l_c_ecm_enz) ! C that they don't need to grow + else ! less N in soil, so we limit N flux to vegetaion and mycorrhiza N demand so their sum is equal to N uptake + fn_myc2veg = (1-f_growth) * N_uptake_myc + c_use_eff = f_growth * N_uptake_myc * params_inst%mimicsplus_cn_myc / (1.0_r8 - f_enz) / fc_veg2myc + n_myc_growth = f_growth * N_uptake_myc + l_c_ecm_enz = fc_veg2myc * f_enz * c_use_eff + c_myc_growth = c_use_eff * fc_veg2myc + c_myc_resp = fc_veg2myc - (c_myc_growth + l_c_ecm_enz) ! C that they don't need to grow + end if + + ! update inout optional arguments + if (present(c_ecm_enz)) then + c_ecm_enz = l_c_ecm_enz + endif + if (present(fc_somp2soma)) then + fc_somp2soma = l_fc_somp2soma + end if + if (present(fc_somc2soma)) then + fc_somc2soma = l_fc_somc2soma + end if + if (present(fn_mining_somp)) then + fn_mining_somp = l_fn_mining_somp + end if + if (present(fn_mining_somc)) then + fn_mining_somc = l_fn_mining_somc + end if + + else ! AM + N_demand_myc = c_use_eff * (fc_veg2myc) / params_inst%mimicsplus_cn_myc + N_uptake_myc = fn_smin2myc + if (N_uptake_myc > N_demand_myc) then + fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg + n_myc_growth = N_demand_myc ! How much N the need to grow + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc ! How much C they need to grow + c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow + + else + fn_myc2veg = (1-f_growth) * N_uptake_myc + n_myc_growth = f_growth * N_uptake_myc + c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc / fc_veg2myc + c_myc_resp = fc_veg2myc - c_myc_growth + end if endif - if (present(fc_somp2soma)) then - fc_somp2soma = l_fc_somp2soma - end if - if (present(fc_somc2soma)) then - fc_somc2soma = l_fc_somc2soma - end if - if (present(fn_mining_somp)) then - fn_mining_somp = l_fn_mining_somp - end if - if (present(fn_mining_somc)) then - fn_mining_somc = l_fn_mining_somc - end if - - else ! AM - N_demand_myc = c_use_eff * (fc_veg2myc) / params_inst%mimicsplus_cn_myc - N_uptake_myc = fn_smin2myc - if (N_uptake_myc > N_demand_myc) then - fn_myc2veg = N_uptake_myc - N_demand_myc ! N flux myc -> veg - n_myc_growth = N_demand_myc ! How much N the need to grow - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc ! How much C they need to grow - c_myc_resp = fc_veg2myc - c_myc_growth ! C that they don't need to grow - - else - fn_myc2veg = (1-f_growth) * N_uptake_myc - n_myc_growth = f_growth * N_uptake_myc - c_myc_growth = n_myc_growth * params_inst%mimicsplus_cn_myc / fc_veg2myc - c_myc_resp = fc_veg2myc - c_myc_growth - end if - endif - - fno3_myc2veg = fn_myc2veg * l_no3_frac ! Amount of NO3 / NH4 mycorrhiza could give to plant - fnh4_myc2veg = fn_myc2veg * (1 - l_no3_frac) - no3_unpaid = fno3_myc2veg * dz * dt - no3_from_myc ! plants did not actually get all the promised nitrogen (NO3 / NH4) - nh4_unpaid = fnh4_myc2veg * dz * dt - nh4_from_myc + + fno3_myc2veg = fn_myc2veg * l_no3_frac ! Amount of NO3 / NH4 mycorrhiza could give to plant + fnh4_myc2veg = fn_myc2veg * (1 - l_no3_frac) + no3_unpaid = fno3_myc2veg * dz * dt - no3_from_myc ! plants did not actually get all the promised nitrogen (NO3 / NH4) + nh4_unpaid = fnh4_myc2veg * dz * dt - nh4_from_myc - !if (no3_unpaid + nh4_unpaid < 0) then + !if (no3_unpaid + nh4_unpaid < 0) then ! message = "N flux from AM mycorrhiza to plant is greater than mycorrhiza can actually give to the plant" ! call endrun(msg=message) !else ! Bringing nitrogen fluxes to vegetation back to gN/m2 no3_from_myc = fno3_myc2veg * dz * dt ! if we can give more nitrogen than we promised just give it nh4_from_myc = fnh4_myc2veg * dz * dt - !endif - if ( no3_from_myc < 0.0_r8 .or. nh4_from_myc < 0.0_r8 & - ) then - write(iulog,*) 'ERROR: type,no3_from_myc, nh4_from_myc',myc_type, no3_from_myc, nh4_from_myc, fc_veg2myc_no3,fc_veg2myc_nh4, l_no3_frac, l_fn_mining_somp,l_fn_mining_somc - call endrun( msg= errMsg(sourcefile, __LINE__)) + !endif + if ( no3_from_myc < 0.0_r8 .or. nh4_from_myc < 0.0_r8 & + ) then + write(iulog,*) 'ERROR: type,no3_from_myc, nh4_from_myc',myc_type, no3_from_myc, nh4_from_myc, fc_veg2myc_no3,fc_veg2myc_nh4, l_no3_frac, l_fn_mining_somp,l_fn_mining_somc + call endrun( msg= errMsg(sourcefile, __LINE__)) + end if + + else + !fc_veg2myc_no3 = 0.0_r8 + !fc_veg2myc_nh4 = 0.0_r8 + !no3_from_nonmyc = 0.0_r8 + !nh4_from_nonmyc = 0.0_r8 + !no3_from_myc = 0.0_r8 + !nh4_from_myc = 0.0_r8 + + !fn_smin_no3_2myc = 0.0_r8 + !fn_smin_nh4_2myc = 0.0_r8 + + ! Mycorrhiza internal fluxes + !c_myc_resp = 0.0_r8 + !c_myc_growth = 0.0_r8 + !n_myc_growth = 0.0_r8 + !c_ecm_enz = 0.0_r8 + + ! Mining fluxes + fc_somp2soma = 0.0_r8 + fc_somc2soma = 0.0_r8 + fn_mining_somp = 0.0_r8 + fn_mining_somc = 0.0_r8 + end if + + end subroutine fun_fluxes_myc_update1 - !Moisture function, based on testbed code: https://github.com/wwieder/biogeochem_testbed/blob/957a5c634b9f2d0b4cdba0faa06b5a91216ace33/SOURCE_CODE/mimics_cycle.f90#L401-L419