diff --git a/cime/config/acme/machines/Makefile b/cime/config/acme/machines/Makefile
index e5e7608facf2..701cd2add737 100644
--- a/cime/config/acme/machines/Makefile
+++ b/cime/config/acme/machines/Makefile
@@ -251,8 +251,9 @@ ifeq ($(strip $(USE_PETSC)), TRUE)
$(error PETSC_PATH must be defined when USE_PETSC is TRUE)
endif
- # Get the "PETSC_LIB" list an env var
- include $(PETSC_PATH)/conf/variables
+ # Get the "PETSC_LIB" list an env var
+ include $(PETSC_PATH)/lib/petsc/conf/variables
+
endif
# Set Trilinos info if it is being used
@@ -564,7 +565,7 @@ endif
# Add PETSc libraries
ifeq ($(strip $(USE_PETSC)), TRUE)
- SLIBS += -L${LIB_PETSC} ${PETSC_LIB}
+ SLIBS += ${PETSC_LIB}
endif
# Add trilinos libraries; too be safe, we include all libraries included in the trilinos build,
@@ -904,7 +905,7 @@ cleanrof:
$(RM) -fr $(EXEROOT)/rof/obj
cleanlnd:
- $(RM) -f $(LIBROOT)/liblnd.a
+ $(RM) -f $(LIBROOT)/$(LNDLIB)
$(RM) -fr $(EXEROOT)/lnd/obj
cleancsmshare:
diff --git a/cime/config/acme/machines/config_compilers.xml b/cime/config/acme/machines/config_compilers.xml
index 05d7cc5c753b..91039fc856f3 100644
--- a/cime/config/acme/machines/config_compilers.xml
+++ b/cime/config/acme/machines/config_compilers.xml
@@ -82,6 +82,18 @@ for mct, etc.
-D_USE_FLOW_CONTROL
+
+
+
+
+ -I$(CLM_PFLOTRAN_SOURCE_DIR)
+ -DCLM_PFLOTRAN
+ -DCOLUMN_MODE
+ -L$(CLM_PFLOTRAN_SOURCE_DIR) -lpflotran $(PETSC_LIB)
+
+
+
+
+
+ /software/user_tools/current/cades-ccsi/petsc4pf/openmpi-1.10-gcc-5.3
+
+ FALSE
+ FALSE
+
+ /lustre/or-hydra/cades-ccsi/$USER/models/pflotran-interface/src/clm-pflotran
+
diff --git a/cime/config/acme/testmods_dirs/allactive/clm/bgcinterface/user_nl_clm b/cime/config/acme/testmods_dirs/allactive/clm/bgcinterface/user_nl_clm
new file mode 100644
index 000000000000..2b5ce8492090
--- /dev/null
+++ b/cime/config/acme/testmods_dirs/allactive/clm/bgcinterface/user_nl_clm
@@ -0,0 +1,2 @@
+use_clm_interface = .true.
+use_clm_bgc = .true.
diff --git a/cime/scripts/lib/update_acme_tests.py b/cime/scripts/lib/update_acme_tests.py
index 0207dfd1e387..de1e98a3b1fb 100644
--- a/cime/scripts/lib/update_acme_tests.py
+++ b/cime/scripts/lib/update_acme_tests.py
@@ -73,6 +73,7 @@
("SMS_Ld4.f45_f45.ICLM45ED","clm-fates"),
("ERS.f19_g16.I1850CLM45","clm-betr"),
("ERS.f19_g16.I1850CLM45","clm-vst"),
+ ("ERS.f09_g16.I1850CLM45CN","clm-bgcinterface"),
"ERS.ne11_oQU240.I20TRCLM45",
"ERS.f09_g16.IMCLM45BC")
),
diff --git a/components/clm/bld/namelist_files/namelist_definition_clm4_5.xml b/components/clm/bld/namelist_files/namelist_definition_clm4_5.xml
index 58d008e78544..00a5d0b213da 100644
--- a/components/clm/bld/namelist_files/namelist_definition_clm4_5.xml
+++ b/components/clm/bld/namelist_files/namelist_definition_clm4_5.xml
@@ -1599,7 +1599,7 @@ Specifies the method for decomposing CLM grids across processors.
-
Runtime flag to turn on/off bgc interface.
diff --git a/components/clm/src/biogeochem/CNAllocationBetrMod.F90 b/components/clm/src/biogeochem/CNAllocationBetrMod.F90
index 6147c22870b1..30befa38fc2c 100644
--- a/components/clm/src/biogeochem/CNAllocationBetrMod.F90
+++ b/components/clm/src/biogeochem/CNAllocationBetrMod.F90
@@ -30,7 +30,6 @@ module CNAllocationBeTRMod
use ColumnType , only : col_pp
use VegetationType , only : veg_pp
! bgc interface & pflotran module switches
- use clm_varctl , only: use_bgc_interface,use_clm_bgc, use_pflotran, pf_cmode
use clm_varctl , only : nu_com
use SoilStatetype , only : soilstate_type
use WaterStateType , only : waterstate_type
diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90
index e6711180c0fb..7a971b4730b2 100755
--- a/components/clm/src/biogeochem/CNAllocationMod.F90
+++ b/components/clm/src/biogeochem/CNAllocationMod.F90
@@ -30,7 +30,7 @@ module CNAllocationMod
use ColumnType , only : col_pp
use VegetationType , only : veg_pp
! bgc interface & pflotran module switches
- use clm_varctl , only: use_bgc_interface,use_clm_bgc, use_pflotran, pf_cmode
+ use clm_varctl , only: use_clm_interface,use_clm_bgc, use_pflotran, pf_cmode
use clm_varctl , only : nu_com
use SoilStatetype , only : soilstate_type
use WaterStateType , only : waterstate_type
@@ -46,12 +46,12 @@ module CNAllocationMod
public :: readCNAllocParams
public :: CNAllocationInit ! Initialization
! public :: CNAllocation ! run method
- !!-----------------------------------------------------------------------------------------------------
- !! CNAllocation is divided into 3 subroutines/phases:
- public :: CNAllocation1_PlantNPDemand !!Plant N/P Demand; called in CNEcosystemDynNoLeaching1
- public :: CNAllocation2_ResolveNPLimit !!Resolve N/P Limitation; called in CNDecompAlloc
- public :: CNAllocation3_PlantCNPAlloc !!Plant C/N/P Allocation; called in CNDecompAlloc2
- !!-----------------------------------------------------------------------------------------------------
+ !-----------------------------------------------------------------------------------------------------
+ ! CNAllocation is divided into 3 subroutines/phases:
+ public :: CNAllocation1_PlantNPDemand !Plant N/P Demand; called in CNEcosystemDynNoLeaching1
+ public :: CNAllocation2_ResolveNPLimit !Resolve N/P Limitation; called in CNDecompAlloc
+ public :: CNAllocation3_PlantCNPAlloc !Plant C/N/P Allocation; called in CNDecompAlloc2
+ !-----------------------------------------------------------------------------------------------------
public :: dynamic_plant_alloc ! dynamic plant carbon allocation based on different nutrient stress
type :: CNAllocParamsType
@@ -283,13 +283,13 @@ subroutine CNAllocationInit ( bounds)
end subroutine CNAllocationInit
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNAllocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
photosyns_vars, crop_vars, canopystate_vars, cnstate_vars, &
carbonstate_vars, carbonflux_vars, c13_carbonflux_vars, c14_carbonflux_vars, &
nitrogenstate_vars, nitrogenflux_vars,&
phosphorusstate_vars,phosphorusflux_vars)
- !! PHASE-1 of CNAllocation: loop over patches to assess the total plant N demand and P demand
+ ! PHASE-1 of CNAllocation: loop over patches to assess the total plant N demand and P demand
! !USES:
use shr_sys_mod , only: shr_sys_flush
use clm_varctl , only: iulog,cnallocate_carbon_only,cnallocate_carbonnitrogen_only,&
@@ -1034,7 +1034,7 @@ subroutine CNAllocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soi
end do
! pflotran will need an input from CN: modified 'sum_ndemand_vr' ('potential_immob' excluded).
- if (use_bgc_interface.and.use_pflotran .and. pf_cmode) then
+ if (use_clm_interface.and.use_pflotran .and. pf_cmode) then
do j = 1, nlevdecomp
do fc=1, num_soilc
c = filter_soilc(fc)
@@ -1048,7 +1048,7 @@ subroutine CNAllocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soi
end subroutine CNAllocation1_PlantNPDemand
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
num_soilp, filter_soilp , &
@@ -1057,13 +1057,13 @@ subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
nitrogenstate_vars, nitrogenflux_vars , &
phosphorusstate_vars,phosphorusflux_vars , &
soilstate_vars,waterstate_vars)
- !! PHASE-2 of CNAllocation: resolving N/P limitation
+ ! PHASE-2 of CNAllocation: resolving N/P limitation
! !USES:
use shr_sys_mod , only: shr_sys_flush
use clm_varctl , only: iulog,cnallocate_carbon_only,cnallocate_carbonnitrogen_only,&
cnallocate_carbonphosphorus_only
! use pftvarcon , only: npcropmin, declfact, bfact, aleaff, arootf, astemf
-! use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean !!
+! use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean
use pftvarcon , only: noveg
use clm_varpar , only: nlevdecomp, ndecomp_cascade_transitions
use clm_varcon , only: nitrif_n2o_loss_frac, secspday
@@ -1076,14 +1076,9 @@ subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
integer , intent(in) :: num_soilp ! number of soil patches in filter
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
-! type(photosyns_type) , intent(in) :: photosyns_vars
-! type(crop_type) , intent(in) :: crop_vars
-! type(canopystate_type) , intent(in) :: canopystate_vars
type(cnstate_type) , intent(inout) :: cnstate_vars
type(carbonstate_type) , intent(in) :: carbonstate_vars
type(carbonflux_type) , intent(inout) :: carbonflux_vars
-! type(carbonflux_type) , intent(inout) :: c13_carbonflux_vars
-! type(carbonflux_type) , intent(inout) :: c14_carbonflux_vars
type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
! !! add phosphorus -X.YANG
@@ -1161,10 +1156,10 @@ subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
associate( &
ivt => veg_pp%itype , & ! Input: [integer (:) ] pft vegetation type
- !! new variables due to partition of CNAllocation to 3 subroutines: BEG
+ ! new variables due to partition of CNAllocation to 3 subroutines: BEG
plant_ndemand_col => nitrogenflux_vars%plant_ndemand_col , & ! Output: [real(r8) (:,:) ]
plant_pdemand_col => phosphorusflux_vars%plant_pdemand_col , & ! Output: [real(r8) (:,:) ]
- !! new variables due to partition of CNAllocation to 3 subroutines: END
+ ! new variables due to partition of CNAllocation to 3 subroutines: END
fpg => cnstate_vars%fpg_col , & ! Output: [real(r8) (:) ] fraction of potential gpp (no units)
fpi => cnstate_vars%fpi_col , & ! Output: [real(r8) (:) ] fraction of potential immobilization (no units)
@@ -1276,7 +1271,7 @@ subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
ndep_prof => cnstate_vars%ndep_prof_col , &
gross_pmin_vr => phosphorusflux_vars%gross_pmin_vr_col , &
- !!! add phosphorus variables - X. YANG
+ !! add phosphorus variables - X. YANG
! sminp_vr => phosphorusstate_vars%sminp_vr_col , & ! Input: [real(r8) (:,:) ] (gP/m3) soil mineral P
solutionp_vr => phosphorusstate_vars%solutionp_vr_col , & ! Input: [real(r8) (:,:) ] (gP/m3) soil mineral P
@@ -1304,7 +1299,7 @@ subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
if (nu_com .eq. 'RD') then ! 'RD' : relative demand approach
- !!local var = flux_type%var
+ !local var = flux_type%var
do fc=1, num_soilc
c = filter_soilc(fc)
col_plant_ndemand(c) = plant_ndemand_col(c)
@@ -2892,7 +2887,7 @@ subroutine CNAllocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , &
end subroutine CNAllocation2_ResolveNPLimit
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNAllocation3_PlantCNPAlloc (bounds , &
num_soilc, filter_soilc, num_soilp, filter_soilp , &
canopystate_vars , &
@@ -2900,7 +2895,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
c13_carbonflux_vars, c14_carbonflux_vars , &
nitrogenstate_vars, nitrogenflux_vars , &
phosphorusstate_vars, phosphorusflux_vars)
- !! PHASE-3 of CNAllocation: start new pft loop to distribute the available N/P between the
+ ! PHASE-3 of CNAllocation: start new pft loop to distribute the available N/P between the
! competing patches on the basis of relative demand, and allocate C/N/P to new growth and storage
! !USES:
@@ -2911,10 +2906,10 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
! use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean
use pftvarcon , only: noveg
use pftvarcon , only: npcropmin, grperc, grpnow
- use clm_varpar , only: nlevdecomp !!nlevsoi,
+ use clm_varpar , only: nlevdecomp
use clm_varcon , only: nitrif_n2o_loss_frac, secspday
! use landunit_varcon , only: istsoil, istcrop
-! use clm_time_manager , only: get_step_size
+ use clm_time_manager , only: get_step_size
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
@@ -2922,8 +2917,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
integer , intent(in) :: num_soilp ! number of soil patches in filter
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
-! type(photosyns_type) , intent(in) :: photosyns_vars
-! type(crop_type) , intent(in) :: crop_vars
+
type(canopystate_type) , intent(in) :: canopystate_vars
type(cnstate_type) , intent(inout) :: cnstate_vars
type(carbonstate_type) , intent(in) :: carbonstate_vars
@@ -2938,7 +2932,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
!
! !LOCAL VARIABLES:
!
- integer :: c,p,j !!l,pi, !indices
+ integer :: c,p,j !indices
integer :: fp !lake filter pft index
integer :: fc !lake filter column index
real(r8):: mr !maintenance respiration (gC/m2/s)
@@ -2969,6 +2963,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
real(r8):: cp_stoich_var=0.4 ! variability of CP ratio
real(r8):: curmr, curmr_ratio !xsmrpool temporary variables
real(r8):: xsmr_ratio ! ratio of mr comes from non-structue carobn hydrate pool
+ real(r8):: dt
!-----------------------------------------------------------------------
associate( &
@@ -3139,6 +3134,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
!
! !-------------------------------------------------------------------
+ ! set time steps
+ dt = real( get_step_size(), r8 )
! debug
do fc=1,num_soilc
@@ -3926,22 +3923,22 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
if (nu_com .eq. 'RD') then
if(suplphos == suplpNon) then !!! No supplemental Phosphorus
- call p2c(bounds,num_soilc,filter_soilc, &
+ call p2c(bounds,num_soilc,filter_soilc, &
sminn_to_npool(bounds%begp:bounds%endp), &
sminn_to_plant(bounds%begc:bounds%endc))
- call calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitrogenstate_vars, nuptake_prof)
- do j = 1, nlevdecomp
+ call calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitrogenstate_vars, nuptake_prof)
+ do j = 1, nlevdecomp
do fc=1,num_soilc
c = filter_soilc(fc)
sminn_to_plant_vr(c,j) = sminn_to_plant(c) * nuptake_prof(c,j)
end do
- end do
- end if
+ end do
+ end if
- !! Phosphorus
+ !! Phosphorus
- if( .not. use_nitrif_denitrif) then
+ if( .not. use_nitrif_denitrif) then
call p2c(bounds,num_soilc,filter_soilc, &
sminp_to_ppool(bounds%begp:bounds%endp), &
@@ -3955,23 +3952,25 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
end do
end do
- else ! use_nitrif_denitrif
+ else ! use_nitrif_denitrif
- if( .not.cnallocate_carbonphosphorus_only().and. .not.cnallocate_carbonnitrogen_only().and. .not.cnallocate_carbon_only() )then
+ if( .not.cnallocate_carbonphosphorus_only() .and. &
+ .not.cnallocate_carbonnitrogen_only().and. &
+ .not.cnallocate_carbon_only() )then
temp_sminn_to_plant = sminn_to_plant
temp_sminp_to_plant = sminp_to_plant
- call p2c(bounds,num_soilc,filter_soilc, &
+ call p2c(bounds,num_soilc,filter_soilc, &
sminn_to_npool(bounds%begp:bounds%endp), &
sminn_to_plant(bounds%begc:bounds%endc))
- call p2c(bounds,num_soilc,filter_soilc, &
+ call p2c(bounds,num_soilc,filter_soilc, &
sminp_to_ppool(bounds%begp:bounds%endp), &
sminp_to_plant(bounds%begc:bounds%endc))
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp
do fc=1,num_soilc
c = filter_soilc(fc)
if ( temp_sminn_to_plant(c) > 0._r8) then
@@ -3990,20 +3989,20 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
sminp_to_plant_vr(c,j) = 0._r8
endif
end do
- end do
+ end do
- end if ! carbonnitrogenphosphorus
+ end if ! carbonnitrogenphosphorus
- if( cnallocate_carbonnitrogen_only() )then
+ if( cnallocate_carbonnitrogen_only() )then
temp_sminp_to_plant = sminp_to_plant
- call p2c(bounds,num_soilc,filter_soilc, &
+ call p2c(bounds,num_soilc,filter_soilc, &
sminp_to_ppool(bounds%begp:bounds%endp), &
sminp_to_plant(bounds%begc:bounds%endc))
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp
do fc=1,num_soilc
c = filter_soilc(fc)
@@ -4013,11 +4012,13 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
sminp_to_plant_vr(c,j) = 0._r8
endif
end do
- end do
- end if ! carbonnitrogen
+ end do
+ end if ! carbonnitrogen
+
+ end if ! use_nitrif_denitrif
+
end if ! nu_com .eq. RD
- end if !
!----------------------------------------------------------------
@@ -4025,11 +4026,10 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , &
end subroutine CNAllocation3_PlantCNPAlloc
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitrogenstate_vars, nuptake_prof)
-! use clm_varcon , only : dzsoi_decomp !! declared in module CNAllocationMod
- !! bgc interface & pflotran:
- !! nuptake_prof is used in CNAllocation1, 2, 3
+ ! bgc interface & pflotran:
+ ! nuptake_prof is used in CNAllocation1, 2, 3
! !USES:
use clm_varpar , only: nlevdecomp
! !ARGUMENTS:
@@ -4070,7 +4070,12 @@ subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitr
else
sminn_vr_loc(c,j) = smin_no3_vr(c,j) + smin_nh4_vr(c,j)
end if
- sminn_tot(c) = sminn_tot(c) + sminn_vr_loc(c,j) * dzsoi_decomp(j) !!original: if (use_nitrif_denitrif): sminn_tot(c) = sminn_tot(c) + (smin_no3_vr(c,j) + smin_nh4_vr(c,j)) * dzsoi_decomp(j)
+ if(use_pflotran .and. pf_cmode) then
+ sminn_tot(c) = sminn_tot(c) + sminn_vr_loc(c,j) * dzsoi_decomp(j) &
+ *(nfixation_prof(c,j)*dzsoi_decomp(j)) ! weighted by froot fractions in annual max. active layers
+ else
+ sminn_tot(c) = sminn_tot(c) + sminn_vr_loc(c,j) * dzsoi_decomp(j)
+ end if
end do
end do
@@ -4078,12 +4083,16 @@ subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitr
do fc=1,num_soilc
c = filter_soilc(fc)
if (sminn_tot(c) > 0.) then
- nuptake_prof(c,j) = sminn_vr_loc(c,j) / sminn_tot(c) !!original: if (use_nitrif_denitrif): nuptake_prof(c,j) = sminn_vr(c,j) / sminn_tot(c)
+ if(use_pflotran .and. pf_cmode) then
+ nuptake_prof(c,j) = sminn_vr_loc(c,j) / sminn_tot(c) &
+ *(nfixation_prof(c,j)*dzsoi_decomp(j)) ! weighted by froot fractions in annual max. active layers
+ else
+ nuptake_prof(c,j) = sminn_vr_loc(c,j) / sminn_tot(c) !original: if (use_nitrif_denitrif): nuptake_prof(c,j) = sminn_vr(c,j) / sminn_tot(c)
+ end if
else
nuptake_prof(c,j) = nfixation_prof(c,j)
- endif
- !! sum_ndemand_vr will be calculated after calling calc_nuptake_prof
-! sum_ndemand_vr(c,j) = col_plant_ndemand(c) * nuptake_prof(c,j) + potential_immob_vr(c,j)
+ end if
+
end do
end do
@@ -4091,11 +4100,10 @@ subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitr
end subroutine calc_nuptake_prof
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine calc_puptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, phosphorusstate_vars, puptake_prof)
-! use clm_varcon , only : dzsoi_decomp !! declared in module CNAllocationMod
- !! bgc interface & pflotran:
- !! puptake_prof is used in CNAllocation1, 2, & 3
+ ! bgc interface & pflotran:
+ ! puptake_prof is used in CNAllocation1, 2, & 3
! !USES:
use clm_varpar , only: nlevdecomp
! !ARGUMENTS:
@@ -4114,7 +4122,7 @@ subroutine calc_puptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, phos
associate( &
nfixation_prof => cnstate_vars%nfixation_prof_col , & ! Output: [real(r8) (:,:) ]
- solutionp_vr => phosphorusstate_vars%solutionp_vr_col & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral N
+ solutionp_vr => phosphorusstate_vars%solutionp_vr_col & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral N
)
@@ -4139,10 +4147,9 @@ subroutine calc_puptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, phos
if (solutionp_tot(c) > 0.) then
puptake_prof(c,j) = solutionp_vr(c,j) / solutionp_tot(c)
else
- puptake_prof(c,j) = nfixation_prof(c,j) !!!! need modifications !!!!
+ puptake_prof(c,j) = nfixation_prof(c,j) ! need modifications
endif
- !! sum_pdemand_vr will be calculated after calling calc_puptake_prof
-! sum_pdemand_vr(c,j) = col_plant_pdemand(c) * puptake_prof(c,j) + potential_immob_p_vr(c,j)
+
end do
end do
end associate
diff --git a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 b/components/clm/src/biogeochem/CNBalanceCheckMod.F90
index 36b147dc7780..ba46eeade070 100644
--- a/components/clm/src/biogeochem/CNBalanceCheckMod.F90
+++ b/components/clm/src/biogeochem/CNBalanceCheckMod.F90
@@ -132,14 +132,14 @@ subroutine BeginPBalance(bounds, num_soilc, filter_soilc, &
integer :: fc ! lake filter indices
!-----------------------------------------------------------------------
- associate( &
+ associate( &
totcolp => phosphorusstate_vars%totcolp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
!X.YANG - checking P balance problem, starting from VEGP
totpftp => phosphorusstate_vars%totpftp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
totsomp => phosphorusstate_vars%totsomp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
- cwdp => phosphorusstate_vars%cwdp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
+ cwdp => phosphorusstate_vars%cwdp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
totlitp => phosphorusstate_vars%totlitp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
- sminp => phosphorusstate_vars%sminp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
+ sminp => phosphorusstate_vars%sminp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
col_begpb => phosphorusstate_vars%begpb_col & ! Output: [real(r8) (:)] phosphorus mass, beginning of time step (gP/m**2)
)
@@ -186,7 +186,7 @@ subroutine CBalanceCheck(bounds, &
gpp => carbonflux_vars%gpp_col , & ! Input: [real(r8) (:) ] (gC/m2/s) gross primary production
er => carbonflux_vars%er_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total ecosystem respiration, autotrophic + heterotrophic
- col_fire_closs => carbonflux_vars%fire_closs_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total column-level fire C loss
+ col_fire_closs => carbonflux_vars%fire_closs_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total column-level fire C loss
col_hrv_xsmrpool_to_atm => carbonflux_vars%hrv_xsmrpool_to_atm_col , & ! Input: [real(r8) (:) ] (gC/m2/s) excess MR pool harvest mortality
dwt_closs => carbonflux_vars%dwt_closs_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total carbon loss from product pools and conversion
product_closs => carbonflux_vars%product_closs_col , & ! Input: [real(r8) (:) ] (gC/m2/s) total wood product carbon loss
@@ -254,6 +254,11 @@ subroutine CBalanceCheck(bounds, &
write(iulog,*)'begcb = ',col_begcb(c)
write(iulog,*)'endcb = ',col_endcb(c),carbonstate_vars%totsomc_col(c)
write(iulog,*)'delta store = ',col_endcb(c)-col_begcb(c)
+
+ if (use_pflotran .and. pf_cmode) then
+ write(iulog,*)'pf_delta_decompc = ',col_decompc_delta(c)*dt
+ end if
+
call endrun(msg=errMsg(__FILE__, __LINE__))
end if
end if !use_ed
@@ -286,7 +291,7 @@ subroutine NBalanceCheck(bounds, &
real(r8):: dt ! radiation time step (seconds)
!-----------------------------------------------------------------------
- associate( &
+ associate( &
totcoln => nitrogenstate_vars%totcoln_col , & ! Input: [real(r8) (:)] (gN/m2) total column nitrogen, incl veg
ndep_to_sminn => nitrogenflux_vars%ndep_to_sminn_col , & ! Input: [real(r8) (:)] atmospheric N deposition to soil mineral N (gN/m2/s)
nfix_to_sminn => nitrogenflux_vars%nfix_to_sminn_col , & ! Input: [real(r8) (:)] symbiotic/asymbiotic N fixation to soil mineral N (gN/m2/s)
@@ -298,16 +303,15 @@ subroutine NBalanceCheck(bounds, &
smin_no3_leached => nitrogenflux_vars%smin_no3_leached_col , & ! Input: [real(r8) (:)] soil mineral NO3 pool loss to leaching (gN/m2/s)
smin_no3_runoff => nitrogenflux_vars%smin_no3_runoff_col , & ! Input: [real(r8) (:)] soil mineral NO3 pool loss to runoff (gN/m2/s)
f_n2o_nit => nitrogenflux_vars%f_n2o_nit_col , & ! Input: [real(r8) (:)] flux of N2o from nitrification [gN/m^2/s]
- col_fire_nloss => nitrogenflux_vars%fire_nloss_col , & ! Input: [real(r8) (:)] total column-level fire N loss (gN/m2/s)
+ col_fire_nloss => nitrogenflux_vars%fire_nloss_col , & ! Input: [real(r8) (:)] total column-level fire N loss (gN/m2/s)
dwt_nloss => nitrogenflux_vars%dwt_nloss_col , & ! Input: [real(r8) (:)] (gN/m2/s) total nitrogen loss from product pools and conversion
product_nloss => nitrogenflux_vars%product_nloss_col , & ! Input: [real(r8) (:)] (gN/m2/s) total wood product nitrogen loss
som_n_leached => nitrogenflux_vars%som_n_leached_col , & ! Input: [real(r8) (:)] total SOM N loss from vertical transport
! pflotran:
- col_decompn_delta => nitrogenflux_vars%externaln_to_decomp_delta_col, & ! Input: [real(r8) (:) ] (gN/m2/s) summarized net change of whole column N i/o to decomposing pool bwtn time-step
- col_no3_delta => nitrogenflux_vars%no3_net_transport_delta_col , & ! Input: [real(r8) (:) ] (gN/m2/s) summarized net change of whole column NO3 leaching bwtn time-step
+ col_decompn_delta => nitrogenflux_vars%externaln_to_decomp_delta_col , & ! Input: [real(r8) (:) ] (gN/m2/s) summarized net change of whole column N i/o to decomposing pool bwtn time-step
- col_ninputs => nitrogenflux_vars%ninputs_col , & ! Output: [real(r8) (:)] column-level N inputs (gN/m2/s)
- col_noutputs => nitrogenflux_vars%noutputs_col , & ! Output: [real(r8) (:)] column-level N outputs (gN/m2/s)
+ col_ninputs => nitrogenflux_vars%ninputs_col , & ! Output: [real(r8) (:)] column-level N inputs (gN/m2/s)
+ col_noutputs => nitrogenflux_vars%noutputs_col , & ! Output: [real(r8) (:)] column-level N outputs (gN/m2/s)
col_begnb => nitrogenstate_vars%begnb_col , & ! Output: [real(r8) (:)] nitrogen mass, beginning of time step (gN/m**2)
col_endnb => nitrogenstate_vars%endnb_col , & ! Output: [real(r8) (:)] nitrogen mass, end of time step (gN/m**2)
col_errnb => nitrogenstate_vars%errnb_col & ! Output: [real(r8) (:)] nitrogen balance error for the timestep (gN/m**2)
@@ -342,7 +346,15 @@ subroutine NBalanceCheck(bounds, &
else
col_noutputs(c) = col_noutputs(c) + f_n2o_nit(c)
- col_noutputs(c) = col_noutputs(c) + smin_no3_leached(c) + smin_no3_runoff(c)
+ if(use_pflotran .and. pf_cmode) then
+ ! inclusion of aq. NH4 transport by PFLOTRAN-bgc
+ col_noutputs(c) = col_noutputs(c) + sminn_leached(c)
+ else
+
+ col_noutputs(c) = col_noutputs(c) + smin_no3_leached(c) + smin_no3_runoff(c)
+
+ endif
+
end if
endif
@@ -358,10 +370,6 @@ subroutine NBalanceCheck(bounds, &
if (use_pflotran .and. pf_cmode) then
col_errnb(c) = col_errnb(c) - col_decompn_delta(c)*dt
! here is '-' adjustment. It says that the adding to PF decomp n pools was less.
-
- ! if not hydrology-coupled, NO3 leaching/runoff at previous time-step used as 'source' (out, -) to PFLOTRAN bgc
- if (.not.pf_hmode) col_errnb(c) = col_errnb(c) + col_no3_delta(c)*dt
- ! here is '+' adjustment. It says that the taking to PF no3 pools was more.
end if
if (abs(col_errnb(c)) > 1e-8_r8) then
@@ -394,7 +402,14 @@ subroutine NBalanceCheck(bounds, &
write(iulog,*)'fire = ',col_fire_nloss(c)*dt
write(iulog,*)'dwt = ',dwt_nloss(c)*dt
write(iulog,*)'prod = ',product_nloss(c)*dt
+
+ if (use_pflotran .and. pf_cmode) then
+ write(iulog,*)'pf_delta_decompn = ',col_decompn_delta(c)*dt
+ end if
+
call endrun(msg=errMsg(__FILE__, __LINE__))
+
+
end if
end associate
@@ -426,37 +441,37 @@ subroutine PBalanceCheck(bounds, &
real(r8) :: leafp_to_litter_col(bounds%begc:bounds%endc)
real(r8) :: frootp_to_litter_col(bounds%begc:bounds%endc)
- real(r8):: flux_mineralization_col(bounds%begc:bounds%endc) !! local temperary variable
+ real(r8):: flux_mineralization_col(bounds%begc:bounds%endc) ! local temperary variable
!-----------------------------------------------------------------------
- associate( &
+ associate( &
totcolp => phosphorusstate_vars%totcolp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
supplement_to_sminp => phosphorusflux_vars%supplement_to_sminp_col , & ! Input: [real(r8) (:)] supplemental P supply (gP/m2/s)
sminp_leached => phosphorusflux_vars%sminp_leached_col , & ! Input: [real(r8) (:)] soil mineral P pool loss to leaching (gP/m2/s)
- col_fire_ploss => phosphorusflux_vars%fire_ploss_col , & ! Input: [real(r8) (:)] total column-level fire P loss (gP/m2/s)
+ col_fire_ploss => phosphorusflux_vars%fire_ploss_col , & ! Input: [real(r8) (:)] total column-level fire P loss (gP/m2/s)
dwt_ploss => phosphorusflux_vars%dwt_ploss_col , & ! Input: [real(r8) (:)] (gP/m2/s) total phosphorus loss from product pools and conversion
product_ploss => phosphorusflux_vars%product_ploss_col , & ! Input: [real(r8) (:)] (gP/m2/s) total wood product phosphorus loss
- primp_to_labilep=> phosphorusflux_vars%primp_to_labilep_col , &
- secondp_to_occlp=> phosphorusflux_vars%secondp_to_occlp_col , &
- fert_p_to_sminp => phosphorusflux_vars%fert_p_to_sminp_col , &
+ primp_to_labilep => phosphorusflux_vars%primp_to_labilep_col , &
+ secondp_to_occlp => phosphorusflux_vars%secondp_to_occlp_col , &
+ fert_p_to_sminp => phosphorusflux_vars%fert_p_to_sminp_col , &
- col_pinputs => phosphorusflux_vars%pinputs_col , & ! Output: [real(r8) (:)] column-level P inputs (gP/m2/s)
- col_poutputs => phosphorusflux_vars%poutputs_col , & ! Output: [real(r8) (:)] column-level P outputs (gP/m2/s)
+ col_pinputs => phosphorusflux_vars%pinputs_col , & ! Output: [real(r8) (:)] column-level P inputs (gP/m2/s)
+ col_poutputs => phosphorusflux_vars%poutputs_col , & ! Output: [real(r8) (:)] column-level P outputs (gP/m2/s)
col_begpb => phosphorusstate_vars%begpb_col , & ! Output: [real(r8) (:)] phosphorus mass, beginning of time step (gP/m**2)
col_endpb => phosphorusstate_vars%endpb_col , & ! Output: [real(r8) (:)] phosphorus mass, end of time step (gP/m**2)
- col_errpb => phosphorusstate_vars%errpb_col , & ! Output: [real(r8) (:)] phosphorus balance error for the timestep (gP/m**2)
+ col_errpb => phosphorusstate_vars%errpb_col , & ! Output: [real(r8) (:)] phosphorus balance error for the timestep (gP/m**2)
!X.YANG testing P Balance, from VEGP
totpftp => phosphorusstate_vars%totpftp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
totsomp => phosphorusstate_vars%totsomp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
- cwdp => phosphorusstate_vars%cwdp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
- totlitp => phosphorusstate_vars%totlitp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
- sminp => phosphorusstate_vars%sminp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
- leafp_to_litter => phosphorusflux_vars%leafp_to_litter_patch , & ! Input: [real(r8) (:)] soil mineral P pool loss to leaching (gP/m2/s)
- frootp_to_litter => phosphorusflux_vars%frootp_to_litter_patch , & ! Input: [real(r8) (:)] soil mineral P pool loss to leaching (gP/m2/s)
- sminp_to_plant => phosphorusflux_vars%sminp_to_plant_col ,&
- cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool , &
- pf => phosphorusflux_vars &
+ cwdp => phosphorusstate_vars%cwdp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
+ totlitp => phosphorusstate_vars%totlitp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
+ sminp => phosphorusstate_vars%sminp_col , & ! Input: [real(r8) (:)] (gP/m2) total column phosphorus, incl veg
+ leafp_to_litter => phosphorusflux_vars%leafp_to_litter_patch , & ! Input: [real(r8) (:)] soil mineral P pool loss to leaching (gP/m2/s)
+ frootp_to_litter => phosphorusflux_vars%frootp_to_litter_patch , & ! Input: [real(r8) (:)] soil mineral P pool loss to leaching (gP/m2/s)
+ sminp_to_plant => phosphorusflux_vars%sminp_to_plant_col , &
+ cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool , &
+ pf => phosphorusflux_vars &
)
! set time steps
@@ -473,18 +488,18 @@ subroutine PBalanceCheck(bounds, &
!! immobilization/mineralization in litter-to-SOM and SOM-to-SOM fluxes
!! - X.YANG
- ! column loop
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- flux_mineralization_col(c) = 0._r8
- enddo
+ ! column loop
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ flux_mineralization_col(c) = 0._r8
+ enddo
do k = 1, ndecomp_cascade_transitions
if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
! column loop
do fc = 1,num_soilc
c = filter_soilc(fc)
- flux_mineralization_col(c) = flux_mineralization_col(c) - &
+ flux_mineralization_col(c) = flux_mineralization_col(c) - &
pf%decomp_cascade_sminp_flux_col(c,k)*dt
end do
else
@@ -498,6 +513,12 @@ subroutine PBalanceCheck(bounds, &
endif
end do
+ ! column loop
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ flux_mineralization_col(c) = flux_mineralization_col(c) + &
+ pf%biochem_pmin_col(c)
+ end do
! column loop
diff --git a/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 b/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90
index 8646ebc78130..43d69440fc37 100644
--- a/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90
+++ b/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90
@@ -12,7 +12,7 @@ module CNCStateUpdate3Mod
use clm_varpar , only : nlevdecomp, ndecomp_pools, i_cwd, i_met_lit, i_cel_lit, i_lig_lit
use CNCarbonStateType, only : carbonstate_type
use CNCarbonFluxType , only : carbonflux_type
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
!
implicit none
@@ -59,18 +59,20 @@ subroutine CStateUpdate3( num_soilc, filter_soilc, num_soilp, filter_soilp, &
if ( .not.is_active_betr_bgc )then
! column level carbon fluxes from fire
- do j = 1, nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- ! pft-level wood to column-level CWD (uncombusted wood)
- cs%decomp_cpools_vr_col(c,j,i_cwd) = cs%decomp_cpools_vr_col(c,j,i_cwd) + cf%fire_mortality_c_to_cwdc_col(c,j) * dt
-
- ! pft-level wood to column-level litter (uncombusted wood)
- cs%decomp_cpools_vr_col(c,j,i_met_lit) = cs%decomp_cpools_vr_col(c,j,i_met_lit) + cf%m_c_to_litr_met_fire_col(c,j)* dt
- cs%decomp_cpools_vr_col(c,j,i_cel_lit) = cs%decomp_cpools_vr_col(c,j,i_cel_lit) + cf%m_c_to_litr_cel_fire_col(c,j)* dt
- cs%decomp_cpools_vr_col(c,j,i_lig_lit) = cs%decomp_cpools_vr_col(c,j,i_lig_lit) + cf%m_c_to_litr_lig_fire_col(c,j)* dt
- end do
- end do
+ if (.not.(use_pflotran .and. pf_cmode)) then
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ ! pft-level wood to column-level CWD (uncombusted wood)
+ cs%decomp_cpools_vr_col(c,j,i_cwd) = cs%decomp_cpools_vr_col(c,j,i_cwd) + cf%fire_mortality_c_to_cwdc_col(c,j) * dt
+
+ ! pft-level wood to column-level litter (uncombusted wood)
+ cs%decomp_cpools_vr_col(c,j,i_met_lit) = cs%decomp_cpools_vr_col(c,j,i_met_lit) + cf%m_c_to_litr_met_fire_col(c,j)* dt
+ cs%decomp_cpools_vr_col(c,j,i_cel_lit) = cs%decomp_cpools_vr_col(c,j,i_cel_lit) + cf%m_c_to_litr_cel_fire_col(c,j)* dt
+ cs%decomp_cpools_vr_col(c,j,i_lig_lit) = cs%decomp_cpools_vr_col(c,j,i_lig_lit) + cf%m_c_to_litr_lig_fire_col(c,j)* dt
+ end do
+ end do
+ end if !(.not.(use_pflotran .and. pf_cmode))
! litter and CWD losses to fire
do l = 1, ndecomp_pools
diff --git a/components/clm/src/biogeochem/CNCarbonFluxType.F90 b/components/clm/src/biogeochem/CNCarbonFluxType.F90
index 42b4db144d3d..768d68bf7317 100644
--- a/components/clm/src/biogeochem/CNCarbonFluxType.F90
+++ b/components/clm/src/biogeochem/CNCarbonFluxType.F90
@@ -17,7 +17,7 @@ module CNCarbonFluxType
use LandunitType , only : lun_pp
use clm_varctl , only : nu_com
! bgc interface & pflotran
- use clm_varctl , only : use_bgc_interface, use_pflotran, pf_cmode, use_vertsoilc
+ use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, use_vertsoilc
!
! !PUBLIC TYPES:
implicit none
@@ -394,7 +394,7 @@ module CNCarbonFluxType
real(r8), pointer :: allocation_stem (:) ! check allocation to stem for dynamic allocation scheme
real(r8), pointer :: allocation_froot (:) ! check allocation to fine root for dynamic allocation scheme
- ! new variables for clm_bgc_interface & pflotran
+ ! new variables for clm_interface_funcsMod & pflotran
!------------------------------------------------------------------------
real(r8), pointer :: externalc_to_decomp_cpools_col (:,:,:) ! col (gC/m3/s) net C fluxes associated with litter/som-adding/removal to decomp pools
! (sum of all external C additions and removals, excluding decomposition/hr).
@@ -787,7 +787,7 @@ subroutine InitAllocate(this, bounds)
allocate(this%allocation_stem (begp:endp)) ; this%allocation_stem (:) = nan
allocate(this%allocation_froot (begp:endp)) ; this%allocation_froot (:) = nan
- ! clm_bgc_interface & pflotran
+ ! clm_interface & pflotran
!------------------------------------------------------------------------
allocate(this%externalc_to_decomp_cpools_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)); this%externalc_to_decomp_cpools_col(:,:,:) = spval
allocate(this%externalc_to_decomp_delta_col (begc:endc)); this%externalc_to_decomp_delta_col (:) = spval
@@ -3919,7 +3919,7 @@ subroutine Restart ( this, bounds, ncid, flag )
interpinic_flag='interp', readvar=readvar, data=this%annsum_litfall_patch)
end if
- ! clm_bgc_interface & pflotran
+ ! clm_interface & pflotran
!------------------------------------------------------------------------
if (use_pflotran .and. pf_cmode) then
! externalc_to_decomp_npools_col
@@ -4377,6 +4377,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
use subgridAveMod , only : p2c
use tracer_varcon , only : is_active_betr_bgc
use MathfuncMod , only : dot_sum
+ use clm_varpar , only : nlevdecomp_full
!
! !ARGUMENTS:
class(carbonflux_type) :: this
@@ -4392,6 +4393,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
integer :: c,p,j,k,l ! indices
integer :: fp,fc ! lake filter indices
real(r8) :: maxdepth ! depth to integrate soil variables
+ integer :: nlev
!-----------------------------------------------------------------------
associate(&
@@ -4772,6 +4774,9 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
endif
! column soil variables
+ ! column variables
+ nlev = nlevdecomp
+ if (use_pflotran .and. pf_cmode) nlev = nlevdecomp_full
! some zeroing
do fc = 1,num_soilc
@@ -4786,9 +4791,9 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
! vertically integrate HR and decomposition cascade fluxes
do k = 1, ndecomp_cascade_transitions
- do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
+ do j = 1,nlev
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
this%decomp_cascade_ctransfer_col(c,k) = &
this%decomp_cascade_ctransfer_col(c,k) + &
@@ -4818,10 +4823,10 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
! bgc interface & pflotran:
!----------------------------------------------------------------
- if (use_bgc_interface) then
- call CSummary_interface(this, bounds, num_soilc, filter_soilc)
+ if (use_clm_interface) then
+ call CSummary_interface(this, bounds, num_soilc, filter_soilc)
end if
- !! CSummary_interface: hr_col(c) will be used below
+ ! CSummary_interface: hr_col(c) will be used below
!----------------------------------------------------------------
do fc = 1,num_soilc
@@ -4857,7 +4862,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
! vertically integrate column-level carbon fire losses
do l = 1, ndecomp_pools
- do j = 1,nlevdecomp
+ do j = 1,nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%m_decomp_cpools_to_fire_col(c,l) = &
@@ -4914,10 +4919,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
this%landuseflux_col(c)
end do
- ! for vertically-resolved soil biogeochemistry, calculate some diagnostics of carbon pools to a given depth
-
- if ( (.not. is_active_betr_bgc) .and. &
- (.not.(use_pflotran .and. pf_cmode)) ) then
+ if (.not. is_active_betr_bgc) then
! _col(cWDC_HR) - coarse woody debris heterotrophic respiration
do fc = 1,num_soilc
@@ -4948,99 +4950,104 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end if
end do
- ! (LITTERC_LOSS) - litter C loss
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- this%litterc_loss_col(c) = this%lithr_col(c)
- end do
+ if (.not.(use_pflotran .and. pf_cmode)) then
+ ! (LITTERC_LOSS) - litter C loss
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ this%litterc_loss_col(c) = this%lithr_col(c)
+ end do
+ end if !(.not.(use_pflotran .and. pf_cmode))
+
do l = 1, ndecomp_pools
if ( is_litter(l) ) then
do fc = 1,num_soilc
- c = filter_soilc(fc)
- this%litterc_loss_col(c) = &
- this%litterc_loss_col(c) + &
- this%m_decomp_cpools_to_fire_col(c,l)
+ c = filter_soilc(fc)
+ this%litterc_loss_col(c) = &
+ this%litterc_loss_col(c) + &
+ this%m_decomp_cpools_to_fire_col(c,l)
end do
end if
end do
-
-
+
+
do k = 1, ndecomp_cascade_transitions
- if ( is_litter(decomp_cascade_con%cascade_donor_pool(k)) ) then
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- this%litterc_loss_col(c) = &
- this%litterc_loss_col(c) + &
- this%decomp_cascade_ctransfer_col(c,k)
- end do
- end if
+ if ( is_litter(decomp_cascade_con%cascade_donor_pool(k)) ) then
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ this%litterc_loss_col(c) = &
+ this%litterc_loss_col(c) + &
+ this%decomp_cascade_ctransfer_col(c,k)
+ end do
+ end if
end do
- else if ((use_pflotran .and. pf_cmode)) then
-
- ! 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_soilc
- c = filter_soilc(fc)
- this%decomp_cpools_leached_col(c,l) = 0._r8
- end do
- do j = 1, nlevdecomp
+ if (use_pflotran .and. pf_cmode) then
+ ! note: the follwoing should be useful to non-pflotran-coupled, but seems cause 1 BFB test unmatching.
+ ! 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_soilc
c = filter_soilc(fc)
- this%decomp_cpools_leached_col(c,l) = &
+ this%decomp_cpools_leached_col(c,l) = 0._r8
+ end do
+ do j = 1, nlev
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ this%decomp_cpools_leached_col(c,l) = &
this%decomp_cpools_leached_col(c,l) + &
this%decomp_cpools_transport_tendency_col(c,j,l) * dzsoi_decomp(j)
+ end do
+ end do
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ this%som_c_leached_col(c) = &
+ this%som_c_leached_col(c) + &
+ this%decomp_cpools_leached_col(c,l)
end do
end do
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- this%som_c_leached_col(c) = &
- this%som_c_leached_col(c) + &
- this%decomp_cpools_leached_col(c,l)
- end do
- end do
- endif
+ end if
+ end if
+
! debug
do fc = 1,num_soilc
- c = filter_soilc(fc)
- this%plant_to_litter_cflux(c) = 0._r8
- this%plant_to_cwd_cflux(c) = 0._r8
- do j = 1, nlevdecomp
- this%plant_to_litter_cflux(c) = &
- this%plant_to_litter_cflux(c) + &
- this%phenology_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + &
- this%phenology_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + &
- this%phenology_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + &
- this%gap_mortality_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + &
- this%gap_mortality_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + &
- this%gap_mortality_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + &
- this%m_c_to_litr_met_fire_col(c,j)* dzsoi_decomp(j) + &
- this%m_c_to_litr_cel_fire_col(c,j)* dzsoi_decomp(j) + &
- this%m_c_to_litr_lig_fire_col(c,j)* dzsoi_decomp(j)
- this%plant_to_cwd_cflux(c) = &
- this%plant_to_cwd_cflux(c) + &
- this%gap_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j) + &
- this%fire_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j)
- end do
+ c = filter_soilc(fc)
+ this%plant_to_litter_cflux(c) = 0._r8
+ this%plant_to_cwd_cflux(c) = 0._r8
+ do j = 1, nlev
+ this%plant_to_litter_cflux(c) = &
+ this%plant_to_litter_cflux(c) + &
+ this%phenology_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + &
+ this%phenology_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + &
+ this%phenology_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + &
+ this%gap_mortality_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + &
+ this%gap_mortality_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + &
+ this%gap_mortality_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + &
+ this%m_c_to_litr_met_fire_col(c,j)* dzsoi_decomp(j) + &
+ this%m_c_to_litr_cel_fire_col(c,j)* dzsoi_decomp(j) + &
+ this%m_c_to_litr_lig_fire_col(c,j)* dzsoi_decomp(j)
+ this%plant_to_cwd_cflux(c) = &
+ this%plant_to_cwd_cflux(c) + &
+ this%gap_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j) + &
+ this%fire_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j)
+ end do
end do
end associate
end subroutine Summary
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
! !INTERFACE:
subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
!
! !DESCRIPTION:
-!! bgc interface & pflotran:
+! bgc interface & pflotran:
! On the radiation time step, perform column-level carbon
! summary calculations, which mainly from PFLOTRAN bgc
!
! !USES:
use shr_sys_mod, only: shr_sys_flush
- use clm_varpar , only: nlevdecomp,ndecomp_pools,ndecomp_cascade_transitions
+ use clm_varpar , only: nlevdecomp_full,ndecomp_pools,ndecomp_cascade_transitions
use clm_varpar , only: i_met_lit, i_cel_lit, i_lig_lit, i_cwd
use clm_time_manager , only : get_step_size
!
@@ -5054,10 +5061,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
! !CALLED FROM:
! subroutine Summary (if plotran bgc coupled with CLM-CN
!
-! !REVISION HISTORY:
-!!06/17/2015: modified by Gangsheng Wang
-! !
-! !LOCAL VARIABLES:
+! LOCAL VARIABLES:
real(r8) :: dtime ! time-step (s)
integer :: c,j,l ! indices
integer :: fc ! column filter indices
@@ -5069,11 +5073,10 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
)
dtime = get_step_size()
-!!---------------------------------------------------------------------------------------------------
- if (use_pflotran.and.pf_cmode) then
- ! total heterotrophic respiration (HR)
+!---------------------------------------------------------------------------------------------------
+ ! total heterotrophic respiration (HR)
this%hr_col(:) = 0._r8
- do j = 1,nlevdecomp
+ do j = 1,nlevdecomp_full
do fc = 1,num_soilc
c = filter_soilc(fc)
this%hr_col(c) = this%hr_col(c) + &
@@ -5086,7 +5089,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
c = filter_soilc(fc)
this%f_co2_soil_col(c) = 0._r8
end do
- do j = 1,nlevdecomp
+ do j = 1,nlevdecomp_full
do fc = 1,num_soilc
c = filter_soilc(fc)
this%f_co2_soil_col(c) = this%f_co2_soil_col(c) + &
@@ -5107,7 +5110,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
if ( is_cwd(l) ) then
do fc = 1,num_soilc
c = filter_soilc(fc)
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
this%cwdc_loss_col(c) = &
this%cwdc_loss_col(c) + &
this%decomp_cpools_sourcesink_col(c,j,l) / dtime
@@ -5118,7 +5121,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
if ( is_litter(l) ) then
do fc = 1,num_soilc
c = filter_soilc(fc)
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
this%litterc_loss_col(c) = &
this%litterc_loss_col(c) + &
this%decomp_cpools_sourcesink_col(c,j,l) / dtime
@@ -5127,7 +5130,6 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
end if
end do
- end if !!if (use_pflotran.and.pf_cmode)
! add up all vertically-resolved addition/removal rates (gC/m3/s) of decomp_pools for PFLOTRAN-bgc
! (note: this can be for general purpose, although here added an 'if...endif' block for PF-bgc)
@@ -5135,7 +5137,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
! for calculating the net changes, which are used to do balance check
this%externalc_to_decomp_delta_col(:) = 0._r8
do l = 1, ndecomp_pools
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
do fc = 1, num_soilc
c = filter_soilc(fc)
this%externalc_to_decomp_delta_col(c) = this%externalc_to_decomp_delta_col(c) + &
@@ -5143,14 +5145,13 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
end do
end do
end do
-!write(*,'(A40,E14.6)')">>>DEBUG | externC[t-1]=",this%externalc_to_decomp_delta_col(1)*dtime
!
! do the initialization for the following variable here.
! DON'T do so in the beginning of CLM-CN time-step (otherwise the above saved will not work)
this%externalc_to_decomp_cpools_col(:,:,:) = 0._r8
do l = 1, ndecomp_pools
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
do fc = 1,num_soilc
c = filter_soilc(fc)
@@ -5161,10 +5162,8 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
+ this%phenology_c_to_litr_met_c_col(c,j) &
+ this%dwt_frootc_to_litr_met_c_col(c,j) &
+ this%gap_mortality_c_to_litr_met_c_col(c,j) &
- + this%harvest_c_to_litr_met_c_col(c,j) !!&
-! + this%m_c_to_litr_met_fire_col(c,j) &
-! + this%decomp_cpools_transport_tendency_col(c,j,l) &
-! - this%m_decomp_cpools_to_fire_vr_col(c,j,l)
+ + this%harvest_c_to_litr_met_c_col(c,j) &
+ + this%m_c_to_litr_met_fire_col(c,j)
elseif (l==i_cel_lit) then
this%externalc_to_decomp_cpools_col(c,j,l) = &
@@ -5172,10 +5171,8 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
+ this%phenology_c_to_litr_cel_c_col(c,j) &
+ this%dwt_frootc_to_litr_cel_c_col(c,j) &
+ this%gap_mortality_c_to_litr_cel_c_col(c,j) &
- + this%harvest_c_to_litr_cel_c_col(c,j) !!&
-! + this%m_c_to_litr_cel_fire_col(c,j) &
-! + this%decomp_cpools_transport_tendency_col(c,j,l) &
-! - this%m_decomp_cpools_to_fire_vr_col(c,j,l)
+ + this%harvest_c_to_litr_cel_c_col(c,j) &
+ + this%m_c_to_litr_cel_fire_col(c,j)
elseif (l==i_lig_lit) then
this%externalc_to_decomp_cpools_col(c,j,l) = &
@@ -5183,10 +5180,8 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
+ this%phenology_c_to_litr_lig_c_col(c,j) &
+ this%dwt_frootc_to_litr_lig_c_col(c,j) &
+ this%gap_mortality_c_to_litr_lig_c_col(c,j) &
- + this%harvest_c_to_litr_lig_c_col(c,j) !!&
-! + this%m_c_to_litr_lig_fire_col(c,j) &
-! + this%decomp_cpools_transport_tendency_col(c,j,l) &
-! - this%m_decomp_cpools_to_fire_vr_col(c,j,l)
+ + this%harvest_c_to_litr_lig_c_col(c,j) &
+ + this%m_c_to_litr_lig_fire_col(c,j)
! for cwd
elseif (l==i_cwd) then
@@ -5195,18 +5190,8 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
+ this%dwt_livecrootc_to_cwdc_col(c,j) &
+ this%dwt_deadcrootc_to_cwdc_col(c,j) &
+ this%gap_mortality_c_to_cwdc_col(c,j) &
- + this%harvest_c_to_cwdc_col(c,j) !!&
-! + this%fire_mortality_c_to_cwdc_col(c,j) &
-! + this%decomp_cpools_transport_tendency_col(c,j,l) &
-! - this%m_decomp_cpools_to_fire_vr_col(c,j,l)
-
- ! for som
- ! no external input to som
-! else
-! this%externalc_to_decomp_cpools_col(c,j,l) = &
-! this%externalc_to_decomp_cpools_col(c,j,l) &
-! + this%decomp_cpools_transport_tendency_col(c,j,l) &
-! - this%m_decomp_cpools_to_fire_vr_col(c,j,l)
+ + this%harvest_c_to_cwdc_col(c,j) &
+ + this%fire_mortality_c_to_cwdc_col(c,j)
end if
@@ -5233,7 +5218,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc)
end associate
end subroutine CSummary_interface
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
!------------------------------------------------------------
subroutine summary_rr(this, bounds, num_soilp, filter_soilp, num_soilc, filter_soilc)
@@ -5338,7 +5323,11 @@ subroutine summary_cflux_for_ch4( this, bounds, num_soilp, filter_soilp, num_soi
this%somhr_col(c) = 0._r8
this%lithr_col(c) = 0._r8
this%decomp_cascade_hr_col(c,1:ndecomp_cascade_transitions)= 0._r8
- this%hr_vr_col(c,1:nlevdecomp) = 0._r8
+ if (.not. (use_pflotran .and. pf_cmode)) then
+ ! pflotran has returned 'hr_vr_col(begc:endc,1:nlevdecomp)' to ALM before this subroutine is called in CNEcosystemDynNoLeaching2
+ ! thus 'hr_vr_col' should NOT be set to 0
+ this%hr_vr_col(c,1:nlevdecomp) = 0._r8
+ end if
enddo
if ( (.not. is_active_betr_bgc ) .and. &
diff --git a/components/clm/src/biogeochem/CNCarbonStateType.F90 b/components/clm/src/biogeochem/CNCarbonStateType.F90
index 4862e06982a2..8844f87c8c3f 100644
--- a/components/clm/src/biogeochem/CNCarbonStateType.F90
+++ b/components/clm/src/biogeochem/CNCarbonStateType.F90
@@ -20,6 +20,9 @@ module CNCarbonStateType
use ColumnType , only : col_pp
use clm_varctl , only : nu_com, use_ed
use VegetationType , only : veg_pp
+
+ ! bgc interface & pflotran
+ use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode
!
! !PUBLIC TYPES:
@@ -2735,13 +2738,13 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, c12_carbonstate_var
do k = 1, ndecomp_pools
do c = bounds%begc, bounds%endc
do j = 1, nlevdecomp
- if ( exit_spinup ) then
- m = decomp_cascade_con%spinup_factor(k)
- if (decomp_cascade_con%spinup_factor(k) > 1) m = m / cnstate_vars%scalaravg_col(c)
+ if ( exit_spinup ) then
+ m = decomp_cascade_con%spinup_factor(k)
+ if (decomp_cascade_con%spinup_factor(k) > 1) m = m / cnstate_vars%scalaravg_col(c)
else if ( enter_spinup ) then
- m = 1. / decomp_cascade_con%spinup_factor(k)
- if (decomp_cascade_con%spinup_factor(k) > 1) m = m * cnstate_vars%scalaravg_col(c)
- end if
+ m = 1. / decomp_cascade_con%spinup_factor(k)
+ if (decomp_cascade_con%spinup_factor(k) > 1) m = m * cnstate_vars%scalaravg_col(c)
+ end if
this%decomp_cpools_vr_col(c,j,k) = this%decomp_cpools_vr_col(c,j,k) * m
end do
end do
@@ -2901,7 +2904,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
use clm_varctl , only: iulog
use clm_time_manager , only: get_step_size
use clm_varcon , only: secspday
- use clm_varpar , only: nlevdecomp, ndecomp_pools
+ use clm_varpar , only: nlevdecomp, ndecomp_pools, nlevdecomp_full
!
! !ARGUMENTS:
class(carbonstate_type) :: this
@@ -2916,6 +2919,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
integer :: c,p,j,k,l ! indices
integer :: fp,fc ! lake filter indices
real(r8) :: maxdepth ! depth to integrate soil variables
+ integer :: nlev
!-----------------------------------------------------------------------
! calculate patch -level summary of carbon state
@@ -2995,6 +2999,8 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
! column level summary
+ nlev = nlevdecomp
+ if (use_pflotran .and. pf_cmode) nlev = nlevdecomp_full
! vertically integrate each of the decomposing C pools
@@ -3005,7 +3011,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end do
end do
do l = 1, ndecomp_pools
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%decomp_cpools_col(c,l) = &
@@ -3133,7 +3139,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
c = filter_soilc(fc)
this%ctrunc_col(c) = 0._r8
end do
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%ctrunc_col(c) = &
diff --git a/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90 b/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90
index 45d42ee1ef18..4c0ff8a6c8e3 100644
--- a/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90
+++ b/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90
@@ -684,7 +684,8 @@ subroutine decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, &
t_scalar => carbonflux_vars%t_scalar_col , & ! Output: [real(r8) (:,:) ] soil temperature scalar for decomp
w_scalar => carbonflux_vars%w_scalar_col , & ! Output: [real(r8) (:,:) ] soil water scalar for decomp
o_scalar => carbonflux_vars%o_scalar_col , & ! Output: [real(r8) (:,:) ] fraction by which decomposition is limited by anoxia
- decomp_k => carbonflux_vars%decomp_k_col & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
+ decomp_k => carbonflux_vars%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
+ decomp_k_pools => decomp_cascade_con%decomp_k_pools & !(0: ndecomp_pools) ! pflotran (0 for atm. co2)
)
mino2lim = CNParamsShareInst%mino2lim
@@ -738,13 +739,6 @@ subroutine decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, &
! calc ref rate
catanf_30 = catanf(30._r8)
- ! The following code implements the acceleration part of the AD spinup algorithm
-
- if ( spinup_state .eq. 1 ) then
- k_s1 = k_s1 * CNDecompBgcParamsInst%spinup_vector(1)
- k_s2 = k_s2 * CNDecompBgcParamsInst%spinup_vector(2)
- k_s3 = k_s3 * CNDecompBgcParamsInst%spinup_vector(3)
- endif
i_litr1 = 1
i_litr2 = 2
@@ -759,6 +753,23 @@ subroutine decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, &
i_soil3 = 6
end if
+ ! pflotran:beg---saving orignal k (not scaled) for passing to pflotran bgc decomposition sandboxes
+ decomp_k_pools(i_litr1) = k_l1
+ decomp_k_pools(i_litr2) = k_l2_l3
+ decomp_k_pools(i_litr3) = k_l2_l3
+ decomp_k_pools(i_cwd) = k_frag
+ decomp_k_pools(i_soil1) = k_s1
+ decomp_k_pools(i_soil2) = k_s2
+ decomp_k_pools(i_soil3) = k_s3
+ ! pflotran:end
+
+ ! The following code implements the acceleration part of the AD spinup algorithm
+ if ( spinup_state .eq. 1 ) then
+ k_s1 = k_s1 * CNDecompBgcParamsInst%spinup_vector(1)
+ k_s2 = k_s2 * CNDecompBgcParamsInst%spinup_vector(2)
+ k_s3 = k_s3 * CNDecompBgcParamsInst%spinup_vector(3)
+ endif
+
!--- time dependent coefficients-----!
if ( nlevdecomp .eq. 1 ) then
diff --git a/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90 b/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90
index bc16102c2e72..3d6a9ecdecf3 100644
--- a/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90
+++ b/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90
@@ -74,7 +74,7 @@ module CNDecompCascadeCNMod
integer :: nsompools = 4
integer :: nlitpools = 3
integer :: ncwdpools = 1
- real(r8), allocatable :: spinup_vector(:) ! multipliers for soil decomp during accelerated spinup
+ real(r8), allocatable :: spinup_vector(:) ! multipliers for soil decomp during accelerated spinup
end type CNDecompCnParamsType
@@ -694,7 +694,8 @@ subroutine decomp_rate_constants_cn(bounds, &
t_scalar => carbonflux_vars%t_scalar_col , & ! Output: [real(r8) (:,:) ] soil temperature scalar for decomp
w_scalar => carbonflux_vars%w_scalar_col , & ! Output: [real(r8) (:,:) ] soil water scalar for decomp
o_scalar => carbonflux_vars%o_scalar_col , & ! Output: [real(r8) (:,:) ] fraction by which decomposition is limited by anoxia
- decomp_k => carbonflux_vars%decomp_k_col & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
+ decomp_k => carbonflux_vars%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
+ decomp_k_pools => decomp_cascade_con%decomp_k_pools & !(0: ndecomp_pools) ! pflotran (0 for atm. co2)
)
mino2lim = CNParamsShareInst%mino2lim
@@ -744,20 +745,6 @@ subroutine decomp_rate_constants_cn(bounds, &
decomp_depth_efolding = CNParamsShareInst%decomp_depth_efolding
end if
- ! The following code implements the acceleration part of the AD spinup
- ! algorithm, by multiplying all of the SOM decomposition base rates by 10.0.
-
- if ( spinup_state .eq. 1 ) then
- k_l1 = k_l1 * CNDecompCnParamsInst%spinup_vector(1)
- k_l2 = k_l2 * CNDecompCnParamsInst%spinup_vector(2)
- k_l3 = k_l3 * CNDecompCnParamsInst%spinup_vector(3)
- k_s1 = k_s1 * CNDecompCnParamsInst%spinup_vector(4)
- k_s2 = k_s2 * CNDecompCnParamsInst%spinup_vector(5)
- k_s3 = k_s3 * CNDecompCnParamsInst%spinup_vector(6)
- k_s4 = k_s4 * CNDecompCnParamsInst%spinup_vector(7)
- k_frag = k_frag * CNDecompCnParamsInst%spinup_vector(8)
- endif
-
i_litr1 = 1
i_litr2 = 2
i_litr3 = 3
@@ -773,6 +760,31 @@ subroutine decomp_rate_constants_cn(bounds, &
i_soil4 = 7
end if
+ ! pflotran:beg---saving kd (NOT ad scaled) for passing to pflotran bgc decomposition sandboxes
+ decomp_k_pools(i_litr1) = k_l1 / dt
+ decomp_k_pools(i_litr2) = k_l2 / dt
+ decomp_k_pools(i_litr3) = k_l3 / dt
+ if (.not.use_ed) decomp_k_pools(i_cwd) = k_frag / dt
+ decomp_k_pools(i_soil1) = k_s1 / dt
+ decomp_k_pools(i_soil2) = k_s2 / dt
+ decomp_k_pools(i_soil3) = k_s3 / dt
+ decomp_k_pools(i_soil4) = k_s4 / dt
+ ! pflotran:end
+
+ ! The following code implements the acceleration part of the AD spinup
+ ! algorithm, by multiplying all of the SOM decomposition base rates by 10.0.
+
+ if ( spinup_state .eq. 1 ) then
+ k_l1 = k_l1 * CNDecompCnParamsInst%spinup_vector(1)
+ k_l2 = k_l2 * CNDecompCnParamsInst%spinup_vector(2)
+ k_l3 = k_l3 * CNDecompCnParamsInst%spinup_vector(3)
+ k_s1 = k_s1 * CNDecompCnParamsInst%spinup_vector(4)
+ k_s2 = k_s2 * CNDecompCnParamsInst%spinup_vector(5)
+ k_s3 = k_s3 * CNDecompCnParamsInst%spinup_vector(6)
+ k_s4 = k_s4 * CNDecompCnParamsInst%spinup_vector(7)
+ if (.not.use_ed) k_frag = k_frag * CNDecompCnParamsInst%spinup_vector(8)
+ endif
+
!--- time dependent coefficients-----!
if ( nlevdecomp .eq. 1 ) then
@@ -979,8 +991,8 @@ subroutine decomp_rate_constants_cn(bounds, &
call get_curr_date(year, mon, day, sec)
if (year >= 20 .and. year < 40) then
!as a first test, use level 4 (10cm) - this is used to cacluate location-specific acceleration factors
- do fc=1,num_soilc
- c = filter_soilc(fc)
+ do fc=1,num_soilc
+ c = filter_soilc(fc)
cnstate_vars%scalaravg_col(c) = cnstate_vars%scalaravg_col(c) + &
(t_scalar(c,4) * w_scalar(c,4) * o_scalar(c,4) ) * dt / (86400._r8 * 365._r8 * 20._r8)
if (cnstate_vars%scalaravg_col(c) < 1.0e-2) cnstate_vars%scalaravg_col(c) = 1.0e-2
diff --git a/components/clm/src/biogeochem/CNDecompCascadeConType.F90 b/components/clm/src/biogeochem/CNDecompCascadeConType.F90
index 7d85f418e4e8..22266b3bd18d 100644
--- a/components/clm/src/biogeochem/CNDecompCascadeConType.F90
+++ b/components/clm/src/biogeochem/CNDecompCascadeConType.F90
@@ -39,7 +39,8 @@ module CNDecompCascadeConType
logical , pointer :: is_metabolic(:) ! TRUE => pool is metabolic material
logical , pointer :: is_cellulose(:) ! TRUE => pool is cellulose
logical , pointer :: is_lignin(:) ! TRUE => pool is lignin
- real(r8) , pointer :: spinup_factor(:) ! factor by which to scale AD and relevant processes by
+ real(r8) , pointer :: spinup_factor(:) ! factor by which to scale AD and relevant processes
+ real(r8) , pointer :: decomp_k_pools(:) ! Kd in 1/sec for pool
end type decomp_cascade_type
type(decomp_cascade_type), public :: decomp_cascade_con
@@ -76,6 +77,7 @@ subroutine init_decomp_cascade_constants()
allocate(decomp_cascade_con%is_cellulose(0:ndecomp_pools))
allocate(decomp_cascade_con%is_lignin(0:ndecomp_pools))
allocate(decomp_cascade_con%spinup_factor(0:ndecomp_pools))
+ allocate(decomp_cascade_con%decomp_k_pools(0:ndecomp_pools))
!-- properties of each pathway along decomposition cascade
decomp_cascade_con%cascade_step_name(1:ndecomp_cascade_transitions) = ''
@@ -99,6 +101,7 @@ subroutine init_decomp_cascade_constants()
decomp_cascade_con%is_cellulose(0:ndecomp_pools) = .false.
decomp_cascade_con%is_lignin(0:ndecomp_pools) = .false.
decomp_cascade_con%spinup_factor(0:ndecomp_pools) = nan
+ decomp_cascade_con%decomp_k_pools(0:ndecomp_pools) = nan
end subroutine init_decomp_cascade_constants
diff --git a/components/clm/src/biogeochem/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90
index ee3f92b804c7..96228d6c30b8 100644
--- a/components/clm/src/biogeochem/CNDecompMod.F90
+++ b/components/clm/src/biogeochem/CNDecompMod.F90
@@ -35,8 +35,8 @@ module CNDecompMod
use WaterStateType , only : waterstate_type
use ch4Mod , only : ch4_type
use cropType , only : crop_type
- !! bgc interface & pflotran:
- use clm_varctl , only : use_bgc_interface, use_pflotran, pf_cmode
+ ! clm interface & pflotran:
+ use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode
!
implicit none
save
@@ -88,7 +88,7 @@ subroutine readCNDecompParams ( ncid )
end subroutine readCNDecompParams
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
canopystate_vars, soilstate_vars, &
@@ -98,20 +98,20 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !!-----------------------------------------------------------------------------
- !! DESCRIPTION:
- !! Modified for bgc-interface (wgs): 9/12/2015
- !! clm-bgc soil Module, can be called through clm_bgc_interface
- !! ONLY includes SOM decomposition & nitrification/denitrification (if use_nitrif_denitrif)
- !! CNAllocaiton is divided into 3 subroutines:
- !! (1) CNAllocation1_PlantNPDemand is called in CNEcosystemDynNoLeaching1
- !! (2) CNAllocation2_ResolveNPLimit is called in CNDecompAlloc (this subroutine)
- !! (3) CNAllocation3_PlantCNPAlloc is called in CNDecompAlloc2
- !!-----------------------------------------------------------------------------
+ !-----------------------------------------------------------------------------
+ ! DESCRIPTION:
+ ! Modified for clm_interface: 9/12/2015
+ ! clm-bgc soil Module, can be called through clm_bgc_interface
+ ! ONLY includes SOM decomposition & nitrification/denitrification (if use_nitrif_denitrif)
+ ! CNAllocaiton is divided into 3 subroutines:
+ ! (1) CNAllocation1_PlantNPDemand is called in CNEcosystemDynNoLeaching1
+ ! (2) CNAllocation2_ResolveNPLimit is called in CNDecompAlloc (this subroutine)
+ ! (3) CNAllocation3_PlantCNPAlloc is called in CNDecompAlloc2
+ !-----------------------------------------------------------------------------
! !USES:
! use CNAllocationMod , only: CNAllocation
- use CNAllocationMod , only: CNAllocation2_ResolveNPLimit !! Phase-2 of CNAllocation
+ use CNAllocationMod , only: CNAllocation2_ResolveNPLimit ! Phase-2 of CNAllocation
!
! !ARGUMENT:
type(bounds_type) , intent(in) :: bounds
@@ -132,7 +132,7 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
! type(carbonflux_type) , intent(inout) :: c14_carbonflux_vars
type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
- !! add phosphorus --
+ ! add phosphorus --
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
! type(crop_type) , intent(in) :: crop_vars
@@ -186,7 +186,7 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
net_nmin_vr => nitrogenflux_vars%net_nmin_vr_col , & ! Output: [real(r8) (:,:) ]
gross_nmin => nitrogenflux_vars%gross_nmin_col , & ! Output: [real(r8) (:) ] gross rate of N mineralization (gN/m2/s)
net_nmin => nitrogenflux_vars%net_nmin_col , & ! Output: [real(r8) (:) ] net rate of N mineralization (gN/m2/s)
- !!! add phosphorus
+ ! add phosphorus
decomp_cascade_ptransfer_vr => phosphorusflux_vars%decomp_cascade_ptransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vert-res transfer of P from donor to receiver pool along decomp. cascade (gP/m3/s)
decomp_cascade_sminp_flux_vr => phosphorusflux_vars%decomp_cascade_sminp_flux_vr_col , & ! Output: [real(r8) (:,:,:) ] vert-res mineral P flux for transition along decomposition cascade (gP/m3/s)
potential_immob_p_vr => phosphorusflux_vars%potential_immob_p_vr_col , & ! Output: [real(r8) (:,:) ]
@@ -212,16 +212,9 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
actual_immob_p_vr => phosphorusflux_vars%actual_immob_p_vr_col &
)
-!!-------------------------------------------------------------------------------------------------
- ! calculate decomposition rates (originally called in CNEcosystemDynNoLeaching1)
- if (use_century_decomp) then
- call decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, &
- canopystate_vars, soilstate_vars, temperature_vars, ch4_vars, carbonflux_vars)
- else
- call decomp_rate_constants_cn(bounds, num_soilc, filter_soilc, &
- canopystate_vars, soilstate_vars, temperature_vars, ch4_vars, carbonflux_vars, cnstate_vars)
- end if
-!!-------------------------------------------------------------------------------------------------
+ !-------------------------------------------------------------------------------------------------
+ ! call decomp_rate_constants_bgc() or decomp_rate_constants_cn(): now called in CNEcosystemDynNoLeaching1
+ !-------------------------------------------------------------------------------------------------
! set initial values for potential C and N fluxes
p_decomp_cpool_loss(bounds%begc : bounds%endc, :, :) = 0._r8
@@ -391,13 +384,10 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
end do
-!!-------------------------------------------------------------------------------------------------
-!! 'decomp_vertprofiles' (calc nfixation_prof) is moved to CNEcosystemDynNoLeaching1
-!! 'nfixation_prof' is used to 'calc_nuptake_prof' & 'calc_puptake_prof', which are called in CNAllocation1,2,3
-! call decomp_vertprofiles(bounds, &
-! num_soilc, filter_soilc, num_soilp, filter_soilp, &
-! soilstate_vars, canopystate_vars, cnstate_vars)
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
+! 'call decomp_vertprofiles()' (calc nfixation_prof) is moved to CNEcosystemDynNoLeaching1
+! 'nfixation_prof' is used in 'calc_nuptake_prof' & 'calc_puptake_prof', which are called in CNAllocation1,2,3
+!-------------------------------------------------------------------------------------------------
if (use_nitrif_denitrif) then ! calculate nitrification and denitrification rates
call nitrif_denitrif(bounds, &
@@ -424,54 +414,12 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
! column loop to calculate actual immobilization and decomp rates, following
! resolution of plant/heterotroph competition for mineral N
-!!-------------------------------------------------------------------------------------------------
-!! comment out c:n,c:p ratios calculation, they have been calculated at the beginning of this subroutine
-!!-------------------------------------------------------------------------------------------------
- ! calculate c:n ratios of applicable pools
-! do l = 1, ndecomp_pools
-! if ( floating_cn_ratio_decomp_pools(l) ) then
-! do j = 1,nlevdecomp
-! do fc = 1,num_soilc
-! c = filter_soilc(fc)
-! if ( decomp_npools_vr(c,j,l) > 0._r8 ) then
-! cn_decomp_pools(c,j,l) = decomp_cpools_vr(c,j,l) / decomp_npools_vr(c,j,l)
-! end if
-! end do
-! end do
-! else
-! do j = 1,nlevdecomp
-! do fc = 1,num_soilc
-! c = filter_soilc(fc)
-! cn_decomp_pools(c,j,l) = initial_cn_ratio(l)
-! end do
-! end do
-! end if
-! end do
-!
-!
-! !! calculate c:p ratios of applicable pools
-! do l = 1, ndecomp_pools
-! if ( floating_cp_ratio_decomp_pools(l) ) then
-! do j = 1,nlevdecomp
-! do fc = 1,num_soilc
-! c = filter_soilc(fc)
-! if ( decomp_ppools_vr(c,j,l) > 0._r8 ) then
-! cp_decomp_pools(c,j,l) = decomp_cpools_vr(c,j,l) / decomp_ppools_vr(c,j,l)
-! end if
-! end do
-! end do
-! else
-! do j = 1,nlevdecomp
-! do fc = 1,num_soilc
-! c = filter_soilc(fc)
-! cp_decomp_pools(c,j,l) = initial_cp_ratio(l)
-! end do
-! end do
-! end if
-! end do
-!!-------------------------------------------------------------------------------------------------
- ! upon return from CNAllocation, the fraction of potential immobilization
+ !-------------------------------------------------------------------------------------------------
+ ! delete c:n,c:p ratios calculation, they have been calculated at the beginning of this subroutine
+ !-------------------------------------------------------------------------------------------------
+
+ ! upon return from CNAllocation, the fraction of potential immobilization
! has been set (cnstate_vars%fpi_vr_col). now finish the decomp calculations.
! Only the immobilization steps are limited by fpi_vr (pmnf > 0)
! Also calculate denitrification losses as a simple proportion
@@ -631,7 +579,7 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, &
end subroutine CNDecompAlloc
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
photosyns_vars, canopystate_vars, soilstate_vars, temperature_vars, &
@@ -639,16 +587,16 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so
carbonstate_vars, carbonflux_vars, c13_carbonflux_vars, c14_carbonflux_vars, &
nitrogenstate_vars, nitrogenflux_vars, crop_vars, atm2lnd_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !!-----------------------------------------------------------------------------
- !! DESCRIPTION:
- !! bgc interface & pflotran:
- !! (1) Simplified codes of CNDecompAlloc subroutine for coupling with pflotran
- !! (2) call CNAllocation3_PlantCNPAlloc
- !! (3) calculate net_nmin(c), gross_nmin(c), net_pmin(c), gross_pmin(c)
- !!-----------------------------------------------------------------------------
+ !-----------------------------------------------------------------------------
+ ! DESCRIPTION:
+ ! bgc interface & pflotran:
+ ! (1) Simplified codes of CNDecompAlloc subroutine for coupling with pflotran
+ ! (2) call CNAllocation3_PlantCNPAlloc
+ ! (3) calculate net_nmin(c), gross_nmin(c), net_pmin(c), gross_pmin(c)
+ !-----------------------------------------------------------------------------
! !USES:
- use CNAllocationMod , only: CNAllocation3_PlantCNPAlloc !! Phase-3 of CNAllocation
+ use CNAllocationMod , only: CNAllocation3_PlantCNPAlloc ! Phase-3 of CNAllocation
use atm2lndType , only: atm2lnd_type
use clm_time_manager, only: get_step_size
! use clm_varpar , only: nlevdecomp, ndecomp_pools
@@ -682,7 +630,9 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so
! !LOCAL VARIABLES:
integer :: fc, c, j ! indices
! real(r8):: col_plant_ndemand(bounds%begc:bounds%endc) ! column-level vertically-integrated plant N demand (gN/m2/s)
- real(r8):: dt ! time step (seconds)
+ real(r8) :: dt ! time step (seconds)
+ real(r8) :: smin_nh4_to_plant_vr_loc(bounds%begc:bounds%endc,1:nlevdecomp)
+ real(r8) :: smin_no3_to_plant_vr_loc(bounds%begc:bounds%endc,1:nlevdecomp)
! For methane code
real(r8):: hrsum(bounds%begc:bounds%endc,1:nlevdecomp) !sum of HR (gC/m2/s)
@@ -701,12 +651,19 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so
fpi_vr => cnstate_vars%fpi_vr_col , & ! Output: [real(r8) (:,:) ] fraction of potential immobilization (no units)
+ fpi => cnstate_vars%fpi_col , & ! Output: [real(r8) (:) ] fraction of potential immobilization (no units)
potential_immob_vr => nitrogenflux_vars%potential_immob_vr_col , & ! Input:
actual_immob_vr => nitrogenflux_vars%actual_immob_vr_col , & ! Input:
+ potential_immob => nitrogenflux_vars%potential_immob_col , & ! Output: [real(r8) (:) ]
+ actual_immob => nitrogenflux_vars%actual_immob_col , & ! Output: [real(r8) (:) ]
fpg => cnstate_vars%fpg_col , & ! Output: [real(r8) (:) ] fraction of potential gpp (no units)
sminn_to_plant => nitrogenflux_vars%sminn_to_plant_col , & ! Output: [real(r8) (:) ] col N uptake (gN/m2/s)
sminn_to_plant_vr => nitrogenflux_vars%sminn_to_plant_vr_col , & ! Input: [real(r8) (:,:) ] vertically-resolved N uptake (gN/m3/s)
+
+ smin_no3_to_plant_vr => nitrogenflux_vars%smin_no3_to_plant_vr_col , & ! Output: [real(r8) (:,:) ]
+ smin_nh4_to_plant_vr => nitrogenflux_vars%smin_nh4_to_plant_vr_col , & ! Output: [real(r8) (:,:) ]
+
col_plant_ndemand_vr => nitrogenflux_vars%plant_ndemand_vr_col , & ! Input: [real(r8) (:) ] col N uptake (gN/m2/s)
plant_ndemand_col => nitrogenflux_vars%plant_ndemand_col , & ! Output: [real(r8) (:,:) ]
@@ -718,97 +675,121 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so
decomp_k => carbonflux_vars%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
hr_vr => carbonflux_vars%hr_vr_col , & ! Output: [real(r8) (:,:) ] potential HR (gC/m3/s)
phr_vr => carbonflux_vars%phr_vr_col , & ! Output: [real(r8) (:,:) ] potential HR (gC/m3/s)
- fphr => carbonflux_vars%fphr_col & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
+ fphr => carbonflux_vars%fphr_col , & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
+
+ smin_no3_vr => nitrogenstate_vars%smin_no3_vr_col , &
+ smin_nh4_vr => nitrogenstate_vars%smin_nh4_vr_col &
)
! set time steps
dt = real( get_step_size(), r8 )
+ !------------------------------------------------------------------
+ ! 'call decomp_vertprofiles()' moved to EcosystemDynNoLeaching1
+ !------------------------------------------------------------------
+ smin_nh4_to_plant_vr_loc(:,:) = 0._r8
+ smin_no3_to_plant_vr_loc(:,:) = 0._r8
+
! MUST have already updated needed bgc variables from PFLOTRAN by this point
-!!------------------------------------------------------------------
-! moved to EcosystemDynNoLeaching1
-! call decomp_vertprofiles(bounds, &
-! num_soilc, filter_soilc, num_soilp, filter_soilp, &
-! soilstate_vars, canopystate_vars, cnstate_vars)
-
-!!------------------------------------------------------------------
- if(use_bgc_interface.and.use_pflotran.and.pf_cmode) then
- ! fpg calculation
- do fc=1,num_soilc
- c = filter_soilc(fc)
- sminn_to_plant(c) = 0._r8
- !! local var 'col_plant_ndemand' is replaced by fluxtype%plant_ndemand_col
-! col_plant_ndemand(c) = 0._r8
- do j = 1, nlevdecomp ! sum up actual and potential column-level N fluxes to plant
- sminn_to_plant(c) = sminn_to_plant(c) + sminn_to_plant_vr(c,j) * dzsoi_decomp(j)
-! col_plant_ndemand(c) = col_plant_ndemand(c) + col_plant_ndemand_vr(c,j) * dzsoi_decomp(j)
+ if(use_clm_interface.and.use_pflotran.and.pf_cmode) then
+ ! fpg calculation
+ do fc=1,num_soilc
+ c = filter_soilc(fc)
+ sminn_to_plant(c) = 0._r8
+ do j = 1, nlevdecomp ! sum up actual and potential column-level N fluxes to plant
+ sminn_to_plant(c) = sminn_to_plant(c) + sminn_to_plant_vr(c,j) * dzsoi_decomp(j)
+ end do
+ end do
+ do fc=1,num_soilc
+ c = filter_soilc(fc)
+ ! calculate the fraction of potential growth that can be
+ ! acheived with the N available to plants
+ if (plant_ndemand_col(c) > 0.0_r8) then
+ fpg(c) = max(0._r8,sminn_to_plant(c)) / plant_ndemand_col(c)
+ fpg(c) = min(1._r8, fpg(c))
+ else
+ fpg(c) = 1.0_r8
+ end if
end do
- end do
- do fc=1,num_soilc
- c = filter_soilc(fc)
- ! calculate the fraction of potential growth that can be
- ! acheived with the N available to plants
- if (plant_ndemand_col(c) > 0.0_r8) then
- fpg(c) = max(0._r8,sminn_to_plant(c)) / plant_ndemand_col(c)
- fpg(c) = min(1._r8, fpg(c))
- else
- fpg(c) = 1.0_r8
- end if
- end do
- ! fpi calculation
- do fc=1,num_soilc
- c = filter_soilc(fc)
- do j = 1, nlevdecomp
- if (potential_immob_vr(c,j) > 0.0_r8) then
- fpi_vr(c,j) = actual_immob_vr(c,j) / potential_immob_vr(c,j)
+ ! fpi calculation
+ do fc=1,num_soilc
+ c = filter_soilc(fc)
+ potential_immob(c) = 0._r8
+ actual_immob(c) = 0._r8
+ do j = 1, nlevdecomp
+ if (potential_immob_vr(c,j) > 0.0_r8) then
+ fpi_vr(c,j) = actual_immob_vr(c,j) / potential_immob_vr(c,j)
+ potential_immob(c) = potential_immob(c) + potential_immob_vr(c,j)*dzsoi_decomp(j)
+ actual_immob(c) = actual_immob(c) + actual_immob_vr(c,j)*dzsoi_decomp(j)
+ else
+ fpi_vr(c,j) = 0.0_r8
+ end if
+ end do
+ end do
+ do fc=1,num_soilc
+ c = filter_soilc(fc)
+ if (potential_immob(c) > 0.0_r8) then
+ fpi(c) = max(0._r8,actual_immob(c)) / potential_immob(c)
+ fpi(c) = min(1._r8, fpi(c))
else
- fpi_vr(c,j) = 0.0_r8
+ fpi(c) = 1.0_r8
end if
end do
- end do
- if (use_lch4) then
- ! Add up potential hr for methane calculations
- ! potential hr is not available from PFLOTRAN, so here temporarily as actual hr
- ! in the end, this methane module will be moving into PFLOTRAN as well
+ if (use_lch4) then
+ ! Add up potential hr for methane calculations
+ ! potential hr is not available from PFLOTRAN, so here temporarily as actual hr
+ ! in the end, this methane module will be moving into PFLOTRAN as well
- do j = 1,nlevdecomp
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- phr_vr(c,j) = hr_vr(c,j)
+ do j = 1,nlevdecomp
+ do fc = 1, num_soilc
+ c = filter_soilc(fc)
+ phr_vr(c,j) = hr_vr(c,j)
+ end do
end do
- end do
- ! Calculate total fraction of potential HR, for methane code
- do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- hrsum(c,j) = hr_vr(c,j)
+ ! Calculate total fraction of potential HR, for methane code
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ hrsum(c,j) = hr_vr(c,j)
+ end do
end do
- end do
- ! Nitrogen limitation / (low)-moisture limitation
- do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if (phr_vr(c,j) > 0._r8) then
- fphr(c,j) = hrsum(c,j) / phr_vr(c,j) * w_scalar(c,j)
- fphr(c,j) = max(fphr(c,j), 0.01_r8) ! Prevent overflow errors for 0 respiration
- else
- fphr(c,j) = 1._r8
- end if
+ ! Nitrogen limitation / (low)-moisture limitation
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (phr_vr(c,j) > 0._r8) then
+ fphr(c,j) = hrsum(c,j) / phr_vr(c,j) * w_scalar(c,j)
+ fphr(c,j) = max(fphr(c,j), 0.01_r8) ! Prevent overflow errors for 0 respiration
+ else
+ fphr(c,j) = 1._r8
+ end if
+ end do
+ end do
+ end if
+
+ ! needs to zero CLM-CNP variables NOT available from pflotran bgc coupling
+ call CNvariables_nan4pf(bounds, num_soilc, filter_soilc, &
+ num_soilp, filter_soilp, &
+ carbonflux_vars, nitrogenflux_vars, &
+ phosphorusstate_vars, phosphorusflux_vars)
+
+ ! save variables before updating
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ do j = 1,nlevdecomp
+ smin_no3_to_plant_vr_loc(c,j) = smin_no3_to_plant_vr(c,j)
+ smin_nh4_to_plant_vr_loc(c,j) = smin_nh4_to_plant_vr(c,j)
end do
end do
- end if
- ! needs to zero CLM-CN variables NOT available from pflotran bgc coupling
- call CNvariables_nan4pf(bounds, num_soilc, filter_soilc, &
- carbonflux_vars, nitrogenflux_vars)
- end if !!if(use_bgc_interface.and.use_pflotran.and.pf_cmode)
+ end if !if(use_clm_interface.and.use_pflotran.and.pf_cmode)
-!!------------------------------------------------------------------
+ !------------------------------------------------------------------
! phase-3 Allocation for plants
call t_startf('CNAllocation - phase-3')
call CNAllocation3_PlantCNPAlloc (bounds , &
@@ -819,9 +800,31 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so
nitrogenstate_vars, nitrogenflux_vars , &
phosphorusstate_vars, phosphorusflux_vars)
call t_stopf('CNAllocation - phase-3')
-!!------------------------------------------------------------------
+ !------------------------------------------------------------------
+ if(use_pflotran.and.pf_cmode) then
+ ! in CNAllocation3_PlantCNPAlloc():
+ ! smin_nh4_to_plant_vr(c,j), smin_no3_to_plant_vr(c,j), sminn_to_plant_vr(c,j) may be adjusted
+ ! therefore, we need to update smin_no3_vr(c,j) & smin_nh4_vr(c,j)
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ do j = 1,nlevdecomp
+ smin_no3_vr(c,j) = smin_no3_vr(c,j) - (smin_no3_to_plant_vr(c,j) - smin_no3_to_plant_vr_loc(c,j))*dt
+ smin_nh4_vr(c,j) = smin_nh4_vr(c,j) - (smin_nh4_to_plant_vr(c,j) - smin_nh4_to_plant_vr_loc(c,j))*dt
+ smin_no3_vr(c,j) = max(0._r8, smin_no3_vr(c,j))
+ smin_nh4_vr(c,j) = max(0._r8, smin_nh4_vr(c,j))
+ end do
+ end do
+ end if !(use_pflotran.and.pf_cmode)
+ !------------------------------------------------------------------
! vertically integrate net and gross mineralization fluxes for diagnostic output
+ do fc=1,num_soilc
+ c = filter_soilc(fc)
+ net_nmin(c) = 0._r8
+ gross_nmin(c) = 0._r8
+ net_pmin(c) = 0._r8
+ gross_pmin(c) = 0._r8
+ end do
do j = 1,nlevdecomp
do fc = 1,num_soilc
c = filter_soilc(fc)
@@ -835,10 +838,10 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so
end associate
end subroutine CNDecompAlloc2
-!!-------------------------------------------------------------------------------------------------
+ !-------------------------------------------------------------------------------------------------
!
- subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, &
- carbonflux_vars, nitrogenflux_vars)
+ subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
+ carbonflux_vars, nitrogenflux_vars, phosphorusstate_vars,phosphorusflux_vars)
!
!DESCRIPTION:
! CN variables not available from PFLOTRAN, some of which may be output and may cause issues,
@@ -846,14 +849,20 @@ subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, &
!
!USES:
+ use clm_varctl , only: cnallocate_carbon_only, cnallocate_carbonnitrogen_only
use clm_varpar , only: nlevdecomp, ndecomp_cascade_transitions
!
!ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilc ! number of soil columns in filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
+ integer , intent(in) :: num_soilp ! number of soil patches in filter
+ integer , intent(in) :: filter_soilp(:) ! filter for soil patches
type(carbonflux_type) , intent(inout) :: carbonflux_vars
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
+ !! add phosphorus --
+ type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
+ type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
!
!CALLED FROM:
!
@@ -881,9 +890,21 @@ subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, &
end do
- end associate
- end subroutine CNvariables_nan4pf
+ ! pflotran not yet support phosphous cycle
+ if (cnallocate_carbon_only() .or. &
+ cnallocate_carbonnitrogen_only() ) then
+ call phosphorusstate_vars%SetValues ( &
+ num_patch=num_soilp, filter_patch=filter_soilp, value_patch=0._r8, &
+ num_column=num_soilc, filter_column=filter_soilc, value_column=0._r8 )
+
+ call phosphorusflux_vars%SetValues ( &
+ num_patch=num_soilp, filter_patch=filter_soilp, value_patch=0._r8, &
+ num_column=num_soilc, filter_column=filter_soilc, value_column=0._r8 )
+ end if
+
+ end associate
+ end subroutine CNvariables_nan4pf
-!!-------------------------------------------------------------------------------------------------
+ !-------------------------------------------------------------------------------------------------
end module CNDecompMod
diff --git a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 b/components/clm/src/biogeochem/CNEcosystemDynMod.F90
index 048768f2c72a..a5bd39446028 100755
--- a/components/clm/src/biogeochem/CNEcosystemDynMod.F90
+++ b/components/clm/src/biogeochem/CNEcosystemDynMod.F90
@@ -34,7 +34,7 @@ module CNEcosystemDynMod
use PhosphorusFluxType , only : phosphorusflux_type
use PhosphorusStateType , only : phosphorusstate_type
! bgc interface & pflotran
- use clm_varctl , only : use_bgc_interface, use_clm_bgc, use_pflotran, pf_cmode, pf_hmode
+ use clm_varctl , only : use_clm_interface, use_clm_bgc, use_pflotran, pf_cmode, pf_hmode
use CNVerticalProfileMod , only : decomp_vertprofiles
use CNAllocationMod , only : nu_com_nfix, nu_com_phosphatase
use clm_varctl , only : nu_com
@@ -45,11 +45,10 @@ module CNEcosystemDynMod
!
! !PUBLIC MEMBER FUNCTIONS:
public :: CNEcosystemDynInit ! Ecosystem dynamics initialization
-! public :: CNEcosystemDynNoLeaching ! Ecosystem dynamics: phenology, vegetation, before doing N leaching
public :: CNEcosystemDynLeaching ! Ecosystem dynamics: phenology, vegetation, doing N leaching
- !!----------------------------------------------------------------------
- !! bgc interface & pflotran:
- !! CNEcosystemDynNoLeaching is divided into 2 subroutines:
+ !----------------------------------------------------------------------
+ ! bgc&th interface & pflotran:
+ ! CNEcosystemDynNoLeaching is divided into 2 subroutines:
public :: CNEcosystemDynNoLeaching1 ! Ecosystem dynamics: phenology, vegetation, before doing soil_bgc
public :: CNEcosystemDynNoLeaching2 ! Ecosystem dynamics: phenology, vegetation, after doing soil_bgc & before doing N leaching
!-----------------------------------------------------------------------
@@ -103,8 +102,8 @@ subroutine CNEcosystemDynLeaching(bounds, num_soilc, filter_soilc, &
!
! !USES:
use spmdMod , only: masterproc
- use PDynamicsMod , only: PWeathering,PAdsorption,PDesorption,POcclusion
- use PDynamicsMod , only: PBiochemMin,PLeaching
+ use PDynamicsMod , only: PWeathering,PAdsorption,PDesorption,POcclusion
+ use PDynamicsMod , only: PBiochemMin,PLeaching
use CNNDynamicsMod , only: CNNLeaching
use CNNStateUpdate3Mod , only: NStateUpdate3
use PStateUpdate3Mod , only: PStateUpdate3
@@ -145,7 +144,7 @@ subroutine CNEcosystemDynLeaching(bounds, num_soilc, filter_soilc, &
! only do if ed is off
if( .not. use_ed) then
- if(.not.(use_pflotran.and.pf_cmode)) then
+ !if(.not.(use_pflotran.and.pf_cmode)) then
call t_startf('PWeathering')
call PWeathering(num_soilc, filter_soilc, &
cnstate_vars,phosphorusstate_vars,phosphorusflux_vars)
@@ -178,18 +177,18 @@ subroutine CNEcosystemDynLeaching(bounds, num_soilc, filter_soilc, &
cnstate_vars,nitrogenstate_vars,phosphorusstate_vars,phosphorusflux_vars)
call t_stopf('PBiochemMin')
end if
- end if
+ !end if
- !-----------------------------------------------------------------------
- ! pflotran: when both 'pf-bgc' and 'pf-h' on, no need to call CLM-CN's N leaching module
- if (.not. (pf_cmode .and. pf_hmode)) then
- call CNNLeaching(bounds, num_soilc, filter_soilc, &
+ !-----------------------------------------------------------------------
+ ! pflotran: when both 'pf-bgc' and 'pf-h' on, no need to call CLM-CN's N leaching module
+ if (.not. (pf_cmode .and. pf_hmode)) then
+ call CNNLeaching(bounds, num_soilc, filter_soilc, &
waterstate_vars, waterflux_vars, nitrogenstate_vars, nitrogenflux_vars)
- call PLeaching(bounds, num_soilc, filter_soilc, &
+ call PLeaching(bounds, num_soilc, filter_soilc, &
waterstate_vars, waterflux_vars, phosphorusstate_vars, phosphorusflux_vars)
- end if !(.not. (pf_cmode .and. pf_hmode))
- !-----------------------------------------------------------------------
+ end if !(.not. (pf_cmode .and. pf_hmode))
+ !-----------------------------------------------------------------------
call t_startf('CNUpdate3')
@@ -231,7 +230,7 @@ subroutine CNEcosystemDynLeaching(bounds, num_soilc, filter_soilc, &
end subroutine CNEcosystemDynLeaching
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNEcosystemDynNoLeaching1(bounds, &
num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
@@ -243,11 +242,11 @@ subroutine CNEcosystemDynNoLeaching1(bounds, &
canopystate_vars, soilstate_vars, temperature_vars, crop_vars, &
ch4_vars, photosyns_vars, &
phosphorusflux_vars,phosphorusstate_vars)
- !!-------------------------------------------------------------------
- !! bgc interface
- !! Phase-1 of CNEcosystemDynNoLeaching
- !! call CNAllocation1_PlantNPDemand before soil_bgc
- !!-------------------------------------------------------------------
+ !-------------------------------------------------------------------
+ ! bgc interface
+ ! Phase-1 of CNEcosystemDynNoLeaching
+ ! call CNAllocation1_PlantNPDemand before soil_bgc
+ !-------------------------------------------------------------------
! !DESCRIPTION:
! The core CN code is executed here. Calculates fluxes for maintenance
@@ -280,7 +279,7 @@ subroutine CNEcosystemDynNoLeaching1(bounds, &
use CropType , only: crop_type
! use dynHarvestMod , only: CNHarvest
use clm_varpar , only: crop_prog
- use CNAllocationMod , only: CNAllocation1_PlantNPDemand !! Phase-1 of CNAllocation
+ use CNAllocationMod , only: CNAllocation1_PlantNPDemand ! Phase-1 of CNAllocation
! use CNDecompMod , only: CNDecompAlloc2
use CNNDynamicsMod , only: CNNLeaching
use PDynamicsMod , only: PLeaching
@@ -429,25 +428,25 @@ subroutine CNEcosystemDynNoLeaching1(bounds, &
atm2lnd_vars, phosphorusflux_vars)
call t_stopf('PDeposition')
-!!-------------------------------------------------------------------------------------------------
-!! 'decomp_rate_constants' is moved to CNDecompAlloc
-! if (use_century_decomp) then
-! call decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, &
-! canopystate_vars, soilstate_vars, temperature_vars, ch4_vars, carbonflux_vars)
-! else
-! call decomp_rate_constants_cn(bounds, num_soilc, filter_soilc, &
-! canopystate_vars, soilstate_vars, temperature_vars, ch4_vars, carbonflux_vars)
-! end if
-
-!!-------------------------------------------------------------------------------------------------
-!! 'decomp_vertprofiles' (calc nfixation_prof) is moved from CNDecompAlloc:
-!! 'nfixation_prof' is used to 'calc_nuptake_prof' & 'calc_puptake_prof', which are called in CNAllocation1,2,3
+ !-------------------------------------------------------------------------------------------------
+ ! plfotran: 'decomp_rate_constants' must be calculated before entering "clm_interface"
+ if (use_century_decomp) then
+ call decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, &
+ canopystate_vars, soilstate_vars, temperature_vars, ch4_vars, carbonflux_vars)
+ else
+ call decomp_rate_constants_cn(bounds, num_soilc, filter_soilc, &
+ canopystate_vars, soilstate_vars, temperature_vars, ch4_vars, carbonflux_vars, cnstate_vars)
+ end if
+
+ !-------------------------------------------------------------------------------------------------
+ ! 'decomp_vertprofiles' (calc nfixation_prof) is moved from CNDecompAlloc:
+ ! 'nfixation_prof' is used to 'calc_nuptake_prof' & 'calc_puptake_prof', which are called in CNAllocation1,2,3
call decomp_vertprofiles(bounds, &
num_soilc, filter_soilc, num_soilp, filter_soilp, &
soilstate_vars, canopystate_vars, cnstate_vars)
-!!-------------------------------------------------------------------------------------------------
- !! CNAllocation1 is always called (w/ or w/o use_bgc_interface)
- !! pflotran: call 'CNAllocation1' to obtain potential N demand for support initial GPP
+ !-------------------------------------------------------------------------------------------------
+ ! CNAllocation1 is always called (w/ or w/o use_clm_interface)
+ ! pflotran: call 'CNAllocation1' to obtain potential N demand for support initial GPP
call t_startf('CNAllocation - phase-1')
call CNAllocation1_PlantNPDemand (bounds , &
num_soilc, filter_soilc, num_soilp, filter_soilp , &
@@ -462,7 +461,7 @@ subroutine CNEcosystemDynNoLeaching1(bounds, &
end subroutine CNEcosystemDynNoLeaching1
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine CNEcosystemDynNoLeaching2(bounds, &
num_soilc, filter_soilc, &
num_soilp, filter_soilp, num_pcropp, filter_pcropp, doalb, &
@@ -474,11 +473,11 @@ subroutine CNEcosystemDynNoLeaching2(bounds, &
canopystate_vars, soilstate_vars, temperature_vars, crop_vars, ch4_vars, &
dgvs_vars, photosyns_vars, soilhydrology_vars, energyflux_vars, &
phosphorusflux_vars,phosphorusstate_vars)
- !!-------------------------------------------------------------------
- !! bgc interface
- !! Phase-2 of CNEcosystemDynNoLeaching
- !! call CNDecompAlloc (w/o bgc_interface) & CNDecompAlloc2
- !!-------------------------------------------------------------------
+ !-------------------------------------------------------------------
+ ! bgc interface
+ ! Phase-2 of CNEcosystemDynNoLeaching
+ ! call CNDecompAlloc (w/o bgc_interface) & CNDecompAlloc2
+ !-------------------------------------------------------------------
! !DESCRIPTION:
! The core CN code is executed here. Calculates fluxes for maintenance
@@ -515,7 +514,7 @@ subroutine CNEcosystemDynNoLeaching2(bounds, &
! use CNAllocationMod , only: cnallocation
use CNDecompMod , only: CNDecompAlloc
- use CNDecompMod , only: CNDecompAlloc2 !!after CNDecompAlloc
+ use CNDecompMod , only: CNDecompAlloc2 !after CNDecompAlloc
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
@@ -559,9 +558,9 @@ subroutine CNEcosystemDynNoLeaching2(bounds, &
call t_startf('CNDecompAlloc')
!----------------------------------------------------------------
- if(.not.use_bgc_interface) then
- !! directly run clm-bgc
- !! if (use_bgc_interface & use_clm_bgc), then CNDecomAlloc is called in clm_driver
+ if(.not.use_clm_interface) then
+ ! directly run clm-bgc
+ ! if (use_clm_interface & use_clm_bgc), then CNDecomAlloc is called in clm_driver
call CNDecompAlloc (bounds, num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
canopystate_vars, soilstate_vars, &
@@ -570,11 +569,11 @@ subroutine CNEcosystemDynNoLeaching2(bounds, &
carbonstate_vars, carbonflux_vars, &
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- end if !!if(.not.use_bgc_interface)
+ end if !if(.not.use_clm_interface)
!----------------------------------------------------------------
- !! CNDecompAlloc2 is called by both clm-bgc & pflotran
- !! pflotran: call 'CNDecompAlloc2' to calculate some diagnostic variables and 'fpg' for plant N uptake
- !! pflotran & clm-bgc : 'CNAllocation3_AG' and vertically integrate net and gross mineralization fluxes
+ ! CNDecompAlloc2 is called by both clm-bgc & pflotran
+ ! pflotran: call 'CNDecompAlloc2' to calculate some diagnostic variables and 'fpg' for plant N uptake
+ ! pflotran & clm-bgc : 'CNAllocation3_AG' and vertically integrate net and gross mineralization fluxes
call CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
photosyns_vars, canopystate_vars, soilstate_vars, temperature_vars, &
waterstate_vars, cnstate_vars, ch4_vars, &
diff --git a/components/clm/src/biogeochem/CNNStateUpdate1Mod.F90 b/components/clm/src/biogeochem/CNNStateUpdate1Mod.F90
index b9257b82eaee..0d78d3ea02cc 100644
--- a/components/clm/src/biogeochem/CNNStateUpdate1Mod.F90
+++ b/components/clm/src/biogeochem/CNNStateUpdate1Mod.F90
@@ -18,7 +18,7 @@ module CNNStateUpdate1Mod
use CNNitrogenStateType , only : nitrogenstate_type
use VegetationType , only : veg_pp
use tracer_varcon , only : is_active_betr_bgc
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
!
implicit none
diff --git a/components/clm/src/biogeochem/CNNStateUpdate2Mod.F90 b/components/clm/src/biogeochem/CNNStateUpdate2Mod.F90
index 51f7e1feccc9..92a2d377d05d 100644
--- a/components/clm/src/biogeochem/CNNStateUpdate2Mod.F90
+++ b/components/clm/src/biogeochem/CNNStateUpdate2Mod.F90
@@ -14,7 +14,7 @@ module CNNStateUpdate2Mod
use CNNitrogenFLuxType , only : nitrogenflux_type
use VegetationType , only : veg_pp
use pftvarcon , only : npcropmin
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
!
implicit none
diff --git a/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 b/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90
index db4450e38f26..5619dd286cc1 100644
--- a/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90
+++ b/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90
@@ -13,7 +13,7 @@ module CNNStateUpdate3Mod
use clm_varpar , only : i_cwd, i_met_lit, i_cel_lit, i_lig_lit
use CNNitrogenStateType , only : nitrogenstate_type
use CNNitrogenFLuxType , only : nitrogenflux_type
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
!
implicit none
@@ -74,16 +74,21 @@ subroutine NStateUpdate3(num_soilc, filter_soilc, num_soilp, filter_soilp, &
( nf%smin_no3_leached_vr_col(c,j) + nf%smin_no3_runoff_vr_col(c,j) ) * dt, 0._r8)
ns%sminn_vr_col(c,j) = ns%smin_no3_vr_col(c,j) + ns%smin_nh4_vr_col(c,j)
+ if (use_pflotran .and. pf_cmode) then
+ ns%sminn_vr_col(c,j) = ns%sminn_vr_col(c,j) + ns%smin_nh4sorb_vr_col(c,j)
+ end if
end if
- ! column level nitrogen fluxes from fire
- ! pft-level wood to column-level CWD (uncombusted wood)
- ns%decomp_npools_vr_col(c,j,i_cwd) = ns%decomp_npools_vr_col(c,j,i_cwd) + nf%fire_mortality_n_to_cwdn_col(c,j) * dt
-
- ! pft-level wood to column-level litter (uncombusted wood)
- ns%decomp_npools_vr_col(c,j,i_met_lit) = ns%decomp_npools_vr_col(c,j,i_met_lit) + nf%m_n_to_litr_met_fire_col(c,j)* dt
- ns%decomp_npools_vr_col(c,j,i_cel_lit) = ns%decomp_npools_vr_col(c,j,i_cel_lit) + nf%m_n_to_litr_cel_fire_col(c,j)* dt
- ns%decomp_npools_vr_col(c,j,i_lig_lit) = ns%decomp_npools_vr_col(c,j,i_lig_lit) + nf%m_n_to_litr_lig_fire_col(c,j)* dt
+ if (.not.(use_pflotran .and. pf_cmode)) then
+ ! column level nitrogen fluxes from fire
+ ! pft-level wood to column-level CWD (uncombusted wood)
+ ns%decomp_npools_vr_col(c,j,i_cwd) = ns%decomp_npools_vr_col(c,j,i_cwd) + nf%fire_mortality_n_to_cwdn_col(c,j) * dt
+
+ ! pft-level wood to column-level litter (uncombusted wood)
+ ns%decomp_npools_vr_col(c,j,i_met_lit) = ns%decomp_npools_vr_col(c,j,i_met_lit) + nf%m_n_to_litr_met_fire_col(c,j)* dt
+ ns%decomp_npools_vr_col(c,j,i_cel_lit) = ns%decomp_npools_vr_col(c,j,i_cel_lit) + nf%m_n_to_litr_cel_fire_col(c,j)* dt
+ ns%decomp_npools_vr_col(c,j,i_lig_lit) = ns%decomp_npools_vr_col(c,j,i_lig_lit) + nf%m_n_to_litr_lig_fire_col(c,j)* dt
+ end if !(.not.(use_pflotran .and. pf_cmode))
end do ! end of column loop
end do
diff --git a/components/clm/src/biogeochem/CNNitrogenFluxType.F90 b/components/clm/src/biogeochem/CNNitrogenFluxType.F90
index ea7dadecdfca..c954cdb16efb 100644
--- a/components/clm/src/biogeochem/CNNitrogenFluxType.F90
+++ b/components/clm/src/biogeochem/CNNitrogenFluxType.F90
@@ -13,8 +13,8 @@ module CNNitrogenFluxType
use LandunitType , only : lun_pp
use ColumnType , only : col_pp
use VegetationType , only : veg_pp
- !! bgc interface & pflotran:
- use clm_varctl , only : use_bgc_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc
+ ! bgc interface & pflotran:
+ use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc
!
! !PUBLIC TYPES:
implicit none
@@ -339,10 +339,10 @@ module CNNitrogenFluxType
real(r8), pointer :: avail_retransn_patch (:) ! N flux available from retranslocation pool (gN/m2/s)
real(r8), pointer :: plant_nalloc_patch (:) ! total allocated N flux (gN/m2/s)
- ! bgc interfacepflotran
+ ! bgc interface/pflotran
!------------------------------------------------------------------------
real(r8), pointer :: plant_ndemand_col (:) ! col N flux required to support initial GPP (gN/m2/s)
- !! pflotran
+ ! pflotran
real(r8), pointer :: plant_ndemand_vr_col (:,:) ! col vertically-resolved N flux required to support initial GPP (gN/m3/s)
real(r8), pointer :: f_ngas_decomp_vr_col (:,:) ! col vertically-resolved N emission from excess mineral N pool due to mineralization (gN/m3/s)
@@ -361,8 +361,8 @@ module CNNitrogenFluxType
real(r8), pointer :: externaln_to_decomp_npools_col (:,:,:) ! col net N fluxes associated with litter/som-adding/removal to decomp pools (gN/m3/s)
! (sum of all external N additions and removals, excluding decomposition/hr).
real(r8), pointer :: externaln_to_decomp_delta_col (:) ! col summarized net N i/o changes associated with litter/som-adding/removal to decomp pools btw time-step (gN/m2)
- real(r8), pointer :: no3_net_transport_vr_col (:,:) ! col net NO3 transport associated with runoff/leaching (gN/m3/s)
- real(r8), pointer :: no3_net_transport_delta_col (:) ! col summarized net change of column-level N leaching to NO3 bwtn time-step (for balance checking) (gN/m2)
+ real(r8), pointer :: no3_net_transport_vr_col (:,:) ! col net NO3 transport associated with runoff/leaching/diffusion (gN/m3/s)
+ real(r8), pointer :: nh4_net_transport_vr_col (:,:) ! col net NH4 transport associated with runoff/leaching/diffusion (gN/m3/s)
!------------------------------------------------------------------------
real(r8), pointer :: smin_no3_to_plant_patch (:) ! pft level plant uptake of soil NO3 (gN/m2/s) BGC mode
@@ -757,7 +757,7 @@ subroutine InitAllocate(this, bounds)
allocate(this%externaln_to_decomp_npools_col (begc:endc, 1:nlevdecomp_full, 1:ndecomp_pools)); this%externaln_to_decomp_npools_col (:,:,:) = spval
allocate(this%externaln_to_decomp_delta_col (begc:endc)) ; this%externaln_to_decomp_delta_col (:) = spval
allocate(this%no3_net_transport_vr_col (begc:endc, 1:nlevdecomp_full)) ; this%no3_net_transport_vr_col (:,:) = spval
- allocate(this%no3_net_transport_delta_col (begc:endc)) ; this%no3_net_transport_delta_col (:) = spval
+ allocate(this%nh4_net_transport_vr_col (begc:endc, 1:nlevdecomp_full)) ; this%nh4_net_transport_vr_col (:,:) = spval
!------------------------------------------------------------------------
allocate(this%smin_no3_to_plant_patch (begp:endp)) ; this%smin_no3_to_plant_patch (:) = nan
@@ -1464,14 +1464,14 @@ subroutine InitHistory(this, bounds)
endif
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%f_nit_col(begc:endc) = spval
call hist_addfld1d (fname='F_NIT', units='gN/m^2/s', &
avgflag='A', long_name='nitrification flux', &
ptr_col=this%f_nit_col)
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%f_denit_col(begc:endc) = spval
call hist_addfld1d (fname='F_DENIT', units='gN/m^2/s', &
avgflag='A', long_name='denitrification flux', &
@@ -1492,28 +1492,30 @@ subroutine InitHistory(this, bounds)
ptr_col=this%pot_f_denit_col)
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_leached_col(begc:endc) = spval
call hist_addfld1d (fname='SMIN_NO3_LEACHED', units='gN/m^2/s', &
avgflag='A', long_name='soil NO3 pool loss to leaching', &
ptr_col=this%smin_no3_leached_col)
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_runoff_col(begc:endc) = spval
call hist_addfld1d (fname='SMIN_NO3_RUNOFF', units='gN/m^2/s', &
avgflag='A', long_name='soil NO3 pool loss to runoff', &
ptr_col=this%smin_no3_runoff_col)
end if
- if (use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%f_nit_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='F_NIT'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='nitrification flux', &
ptr_col=this%f_nit_vr_col)
end if
- if (use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%f_denit_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='F_DENIT'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='denitrification flux', &
@@ -1534,14 +1536,16 @@ subroutine InitHistory(this, bounds)
ptr_col=this%pot_f_denit_vr_col, default='inactive')
end if
- if (use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_leached_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMIN_NO3_LEACHED'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='soil NO3 pool loss to leaching', &
ptr_col=this%smin_no3_leached_vr_col, default='inactive')
end if
- if (use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_runoff_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMIN_NO3_RUNOFF'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='soil NO3 pool loss to runoff', &
@@ -1555,28 +1559,32 @@ subroutine InitHistory(this, bounds)
ptr_col=this%n2_n2o_ratio_denit_vr_col, default='inactive')
end if
- if (use_nitrif_denitrif) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%actual_immob_no3_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='ACTUAL_IMMOB_NO3', units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='immobilization of NO3', &
ptr_col=this%actual_immob_no3_vr_col, default='inactive')
end if
- if (use_nitrif_denitrif) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%actual_immob_nh4_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='ACTUAL_IMMOB_NH4', units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='immobilization of NH4', &
ptr_col=this%actual_immob_nh4_vr_col, default='inactive')
end if
- if (use_nitrif_denitrif) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_to_plant_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMIN_NO3_TO_PLANT', units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='plant uptake of NO3', &
ptr_col=this%smin_no3_to_plant_vr_col, default='inactive')
end if
- if (use_nitrif_denitrif) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%smin_nh4_to_plant_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMIN_NH4_TO_PLANT', units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='plant uptake of NH4', &
@@ -1703,21 +1711,24 @@ subroutine InitHistory(this, bounds)
end if
- if ( use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%potential_immob_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='POTENTIAL_IMMOB'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='potential N immobilization', &
ptr_col=this%potential_immob_vr_col, default='inactive')
end if
- if ( use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%actual_immob_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='ACTUAL_IMMOB'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='actual N immobilization', &
ptr_col=this%actual_immob_vr_col, default='inactive')
end if
- if ( use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%sminn_to_plant_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMINN_TO_PLANT'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='plant uptake of soil mineral N', &
@@ -1725,21 +1736,24 @@ subroutine InitHistory(this, bounds)
end if
- if ( use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%supplement_to_sminn_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SUPPLEMENT_TO_SMINN'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='supplemental N supply', &
ptr_col=this%supplement_to_sminn_vr_col, default='inactive')
end if
- if ( use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%gross_nmin_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='GROSS_NMIN'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='gross rate of N mineralization', &
ptr_col=this%gross_nmin_vr_col, default='inactive')
end if
- if ( use_nitrif_denitrif .and. nlevdecomp_full > 1 ) then
+ if ((use_nitrif_denitrif .and. nlevdecomp_full > 1) &
+ .or. (use_pflotran .and. pf_cmode)) then
this%net_nmin_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='NET_NMIN'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='net rate of N mineralization', &
@@ -1902,8 +1916,8 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='total allocated N flux', &
ptr_patch=this%plant_nalloc_patch, default='inactive')
- !!-----------------------------------------------------------
- !! bgc interface & pflotran
+ !-----------------------------------------------------------
+ ! bgc interface & pflotran
this%plant_ndemand_col(begc:endc) = spval
call hist_addfld1d (fname='PLANT_NDEMAND_COL', units='gN/m^2/s', &
avgflag='A', long_name='N flux required to support initial GPP', &
@@ -1944,7 +1958,7 @@ subroutine InitHistory(this, bounds)
call hist_addfld1d (fname='SMIN_NO3_TO_PLANT', units='gN/m^2/s', &
avgflag='A', long_name='plant uptake of NO3', &
ptr_col=this%smin_no3_to_plant_col, default='inactive')
- !!---------------------------------------------------------------
+ !---------------------------------------------------------------
this%f_ngas_decomp_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='F_NGAS_DECOMP'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='n gas emission from excess mineral N pool due to mineralization', &
@@ -1974,8 +1988,8 @@ subroutine InitHistory(this, bounds)
call hist_addfld_decomp (fname='PLANT_NDEMAND'//trim(vr_suffix), units='gN/m^3/s', type2d='levdcmp', &
avgflag='A', long_name='plant N demand distribution via roots', &
ptr_col=this%plant_ndemand_vr_col, default='inactive')
- end if !! if (use_pflotran.and.pf_cmode)
- !!-----------------------------------------------------------
+ end if ! if (use_pflotran.and.pf_cmode)
+ !-----------------------------------------------------------
end subroutine InitHistory
!-----------------------------------------------------------------------
@@ -2147,7 +2161,7 @@ subroutine Restart (this, bounds, ncid, flag )
interpinic_flag='interp', readvar=readvar, data=this%grainn_storage_to_xfer_patch)
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
! pot_f_nit_vr
if (use_vertsoilc) then
ptr2d => this%pot_f_nit_vr_col(:,:)
@@ -2167,7 +2181,7 @@ subroutine Restart (this, bounds, ncid, flag )
end if
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
! f_nit_vr
if (use_vertsoilc) then
ptr2d => this%f_nit_vr_col(:,:)
@@ -2251,7 +2265,7 @@ subroutine Restart (this, bounds, ncid, flag )
end if
end if
- end if !! if (use_pflotran .and. pf_cmode)
+ end if ! if (use_pflotran .and. pf_cmode)
!------------------------------------------------------------------------
end subroutine Restart
@@ -2560,7 +2574,7 @@ subroutine SetValues ( this, &
this%fire_nloss_col(i) = value_column
this%wood_harvestn_col(i) = value_column
- !! bgc-interface
+ ! bgc-interface
this%plant_ndemand_col(i) = value_column
end do
@@ -2639,6 +2653,9 @@ subroutine SetValues ( this, &
if ( this%no3_net_transport_vr_col(i,j) == spval ) then
this%no3_net_transport_vr_col(i,j) = value_column
end if
+ if ( this%nh4_net_transport_vr_col(i,j) == spval ) then
+ this%nh4_net_transport_vr_col(i,j) = value_column
+ end if
end do
end do
@@ -2648,9 +2665,6 @@ subroutine SetValues ( this, &
if ( this%externaln_to_decomp_delta_col(i) == spval ) then
this%externaln_to_decomp_delta_col(i) = value_column
end if
- if ( this%no3_net_transport_delta_col(i) == spval ) then
- this%no3_net_transport_delta_col(i) = value_column
- end if
end do
!------------------------------------------------------------------------
@@ -2699,6 +2713,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
use subgridAveMod , only: p2c
use pftvarcon , only : npcropmin
use tracer_varcon , only: is_active_betr_bgc
+ use clm_varpar , only: nlevdecomp_full
!
! !ARGUMENTS:
class (nitrogenflux_type) :: this
@@ -2712,6 +2727,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
integer :: c,p,j,k,l ! indices
integer :: fp,fc ! lake filter indices
real(r8) :: maxdepth ! depth to integrate soil variables
+ integer :: nlev
!-----------------------------------------------------------------------
do fp = 1,num_soilp
@@ -2764,6 +2780,9 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
this%wood_harvestn_patch(bounds%begp:bounds%endp), &
this%wood_harvestn_col(bounds%begc:bounds%endc))
+ nlev = nlevdecomp
+ if (use_pflotran .and. pf_cmode) nlev = nlevdecomp_full
+
do fc = 1,num_soilc
c = filter_soilc(fc)
this%denit_col(c) = 0._r8
@@ -2780,7 +2799,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
!soil mineral N fluxes associated with decomposition cascade
do k = 1, ndecomp_cascade_transitions
- do j = 1,nlevdecomp
+ do j = 1,nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
@@ -2798,7 +2817,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
if (.not. use_nitrif_denitrif) then
! vertically integrate each denitrification flux
do l = 1, ndecomp_cascade_transitions
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%sminn_to_denit_decomp_cascade_col(c,l) = &
@@ -2809,7 +2828,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end do
! vertically integrate bulk denitrification and leaching flux
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%sminn_to_denit_excess_col(c) = &
@@ -2842,7 +2861,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
else
! vertically integrate NO3 NH4 N2O fluxes and pools
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
@@ -2893,7 +2912,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
! vertically integrate column-level fire N losses
do k = 1, ndecomp_pools
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%m_decomp_npools_to_fire_col(c,k) = &
@@ -2918,7 +2937,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end do
! supplementary N supplement_to_sminn
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%supplement_to_sminn_col(c) = &
@@ -2960,7 +2979,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
this%decomp_npools_leached_col(c,l) = 0._r8
end do
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%decomp_npools_leached_col(c,l) = &
@@ -2986,7 +3005,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
this%smin_nh4_to_plant_col(c) = 0._r8
this%plant_to_litter_nflux(c) = 0._r8
this%plant_to_cwd_nflux(c) = 0._r8
- do j = 1, nlevdecomp
+ do j = 1, nlev
this%plant_to_litter_nflux(c) = &
this%plant_to_litter_nflux(c) + &
this%phenology_n_to_litr_met_n_col(c,j)* dzsoi_decomp(j) + &
@@ -3008,7 +3027,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
if (use_nitrif_denitrif) then
do fc = 1,num_soilc
c = filter_soilc(fc)
- do j = 1, nlevdecomp
+ do j = 1, nlev
this%smin_no3_to_plant_col(c)= this%smin_no3_to_plant_col(c) + &
this%smin_no3_to_plant_vr_col(c,j) * dzsoi_decomp(j)
this%smin_nh4_to_plant_col(c)= this%smin_nh4_to_plant_col(c) + &
@@ -3019,23 +3038,23 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
! bgc interface & pflotran
!----------------------------------------------------------------
- if (use_bgc_interface) then
+ if (use_clm_interface .and. pf_cmode) then
call NSummary_interface(this, bounds, num_soilc, filter_soilc)
end if
!----------------------------------------------------------------
end subroutine Summary
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
! !INTERFACE:
subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
!
! !DESCRIPTION:
-!! bgc interface & pflotran:
-! On the radiation time step, perform olumn-level nitrogen
+! bgc interface & pflotran:
+! On the radiation time step, perform column-level nitrogen
! summary calculations, which mainly from PFLOTRAN bgc coupling
!
! !USES:
- use clm_varpar , only: nlevdecomp, ndecomp_pools
+ use clm_varpar , only: nlevdecomp_full, ndecomp_pools
use clm_varpar , only: i_met_lit, i_cel_lit, i_lig_lit, i_cwd
use clm_time_manager , only : get_step_size
@@ -3049,10 +3068,8 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
integer, intent(in) :: filter_soilc(:) ! filter for soil columns
!
! !CALLED FROM:
-! subroutine NSummary (if pflotran coupled)
+! subroutine NSummary (if pflotran coupled) vertically from 1 to 'nlevdecomp_full' (not 'nlevdecomp')
!
-! !REVISION HISTORY:
-!!06/17/2015: modified by Gangsheng Wang
!
! !LOCAL VARIABLES:
integer :: c,j, l ! indices
@@ -3063,12 +3080,14 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
dtime = real( get_step_size(), r8 )
if (use_pflotran .and. pf_cmode) then
-! nitrification-denitrification rates (not yet passing out from PF, but will)
+ ! nitrification-denitrification rates (not yet passing out from PF, but will)
+ !------------------------------------------------
+ ! NOT used currently
do fc = 1,num_soilc
c = filter_soilc(fc)
this%f_nit_col(c) = 0._r8
this%f_denit_col(c) = 0._r8
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
this%f_nit_vr_col(c,j) = 0._r8
this%f_nit_col(c) = this%f_nit_col(c) + &
this%f_nit_vr_col(c,j)*dzsoi_decomp(j)
@@ -3081,8 +3100,9 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
this%denit_col(c) = this%f_denit_col(c)
end do
+ !end------------------------------------------------
- ! the following are from pflotran bgc
+ ! the following are from pflotran bgc, and vertically down to 'nlevdecomp_full'
do fc = 1,num_soilc
c = filter_soilc(fc)
this%f_n2_soil_col(c) = 0._r8
@@ -3092,8 +3112,9 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
this%f_ngas_denit_col(c) = 0._r8
this%smin_no3_leached_col(c) = 0._r8
this%smin_no3_runoff_col(c) = 0._r8
+ this%sminn_leached_col(c) = 0._r8
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
! all N2/N2O gas exchange between atm. and soil (i.e., dissolving - degassing)
this%f_n2_soil_col(c) = this%f_n2_soil_col(c) + &
@@ -3110,27 +3131,34 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
this%f_ngas_denit_col(c) = this%f_ngas_denit_col(c) + &
this%f_ngas_denit_vr_col(c,j)*dzsoi_decomp(j)
- ! leaching/runoff flux (if not hydroloy-coupled, from CLM-CN; otherwise from PF)
+ ! leaching/runoff fluxes summed vertically
+ ! (1) if not hydroloy-coupled, advection from CLM-CN, plus diffusion from PF
+ ! (2) if hydrology-coupled, all from PF (i.e. 'no3_net_transport_vr_col');
this%smin_no3_leached_col(c) = this%smin_no3_leached_col(c) + &
+ this%no3_net_transport_vr_col(c,j) * dzsoi_decomp(j)
+
+ if(.not. pf_hmode) then ! this is from CLM-CN's leaching subroutine
+ this%smin_no3_leached_col(c) = this%smin_no3_leached_col(c) + &
this%smin_no3_leached_vr_col(c,j) * dzsoi_decomp(j)
- this%smin_no3_runoff_col(c) = this%smin_no3_runoff_col(c) + &
+ this%smin_no3_runoff_col(c) = this%smin_no3_runoff_col(c) + &
this%smin_no3_runoff_vr_col(c,j) * dzsoi_decomp(j)
+ endif
- ! assign all no3-N leaching/runoff to all mineral-N
+ ! assign all no3-N leaching/runof,including diffusion from PF, to all mineral-N
this%sminn_leached_vr_col(c,j) = this%smin_no3_leached_vr_col(c,j) + &
- this%smin_no3_runoff_vr_col(c,j)
+ this%smin_no3_runoff_vr_col(c,j) + &
+ this%nh4_net_transport_vr_col(c,j) * dzsoi_decomp(j)
- end do
+ this%sminn_leached_col(c) = this%sminn_leached_col(c) + &
+ this%sminn_leached_vr_col(c,j)*dzsoi_decomp(j)
+
+ end do !j = 1, nlevdecomp_full
! for balance-checking
this%denit_col(c) = this%f_ngas_denit_col(c)
this%f_n2o_nit_col(c) = this%f_ngas_decomp_col(c) + this%f_ngas_nitri_col(c)
- ! assign all no3-N leaching/runoff to all mineral-N
- this%sminn_leached_col(c) = this%smin_no3_leached_col(c) + this%smin_no3_runoff_col(c)
-
- end do
- end if !! if (use_pflotran .and. pf_cmode)
+ end do !fc = 1,num_soilc
! summarize at column-level vertically-resolved littering/removal for PFLOTRAN bgc input needs
@@ -3140,32 +3168,25 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
do fc = 1,num_soilc
c = filter_soilc(fc)
this%externaln_to_decomp_delta_col(c) = 0._r8
- this%no3_net_transport_delta_col(c) = 0._r8
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
do l = 1, ndecomp_pools
this%externaln_to_decomp_delta_col(c) = &
this%externaln_to_decomp_delta_col(c) + &
this%externaln_to_decomp_npools_col(c,j,l)*dzsoi_decomp(j)
end do
- ! NO3 leaching/runoff at previous time-step, which may be as source by PFLOTRAN
- this%no3_net_transport_delta_col(c) = &
- this%no3_net_transport_delta_col(c) + &
- this%no3_net_transport_vr_col(c,j)*dzsoi_decomp(j)
-
end do
end do
- ! do the initialization for the following 2 variables here.
+ ! do the initialization for the following variable here.
! DON'T do so in the beginning of CLM-CN time-step (otherwise the above saved will not work)
this%externaln_to_decomp_npools_col(:,:,:) = 0._r8
- this%no3_net_transport_vr_col(:,:) = 0._r8
! add up all vertically-resolved addition/removal rates (gC/m3/s) of decomp_pools
- do l = 1, ndecomp_pools
- do j = 1, nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ do j = 1, nlevdecomp_full
+ do l = 1, ndecomp_pools
! for litter C pools
if (l==i_met_lit) then
@@ -3174,9 +3195,8 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%phenology_n_to_litr_met_n_col(c,j) &
+ this%dwt_frootn_to_litr_met_n_col(c,j) &
+ this%gap_mortality_n_to_litr_met_n_col(c,j) &
- + this%harvest_n_to_litr_met_n_col(c,j) !!&
-! + this%m_n_to_litr_met_fire_col(c,j) &
-! - this%m_decomp_npools_to_fire_vr_col(c,j,l)
+ + this%harvest_n_to_litr_met_n_col(c,j) &
+ + this%m_n_to_litr_met_fire_col(c,j)
elseif (l==i_cel_lit) then
this%externaln_to_decomp_npools_col(c,j,l) = &
@@ -3184,9 +3204,8 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%phenology_n_to_litr_cel_n_col(c,j) &
+ this%dwt_frootn_to_litr_cel_n_col(c,j) &
+ this%gap_mortality_n_to_litr_cel_n_col(c,j) &
- + this%harvest_n_to_litr_cel_n_col(c,j) !!&
-! + this%m_n_to_litr_cel_fire_col(c,j) &
-! - this%m_decomp_npools_to_fire_vr_col(c,j,l)
+ + this%harvest_n_to_litr_cel_n_col(c,j) &
+ + this%m_n_to_litr_cel_fire_col(c,j)
elseif (l==i_lig_lit) then
this%externaln_to_decomp_npools_col(c,j,l) = &
@@ -3194,9 +3213,8 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%phenology_n_to_litr_lig_n_col(c,j) &
+ this%dwt_frootn_to_litr_lig_n_col(c,j) &
+ this%gap_mortality_n_to_litr_lig_n_col(c,j) &
- + this%harvest_n_to_litr_lig_n_col(c,j) !!&
-! + this%m_n_to_litr_lig_fire_col(c,j) &
-! - this%m_decomp_npools_to_fire_vr_col(c,j,l)
+ + this%harvest_n_to_litr_lig_n_col(c,j) &
+ + this%m_n_to_litr_lig_fire_col(c,j)
! for cwd
elseif (l==i_cwd) then
@@ -3205,14 +3223,8 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%dwt_livecrootn_to_cwdn_col(c,j) &
+ this%dwt_deadcrootn_to_cwdn_col(c,j) &
+ this%gap_mortality_n_to_cwdn_col(c,j) &
- + this%harvest_n_to_cwdn_col(c,j) !!&
-! + this%fire_mortality_n_to_cwdn_col(c,j)
-
- ! for som n
-! else
-! this%externaln_to_decomp_npools_col(c,j,l) = &
-! this%externaln_to_decomp_npools_col(c,j,l) &
-! - this%m_decomp_npools_to_fire_vr_col(c,j,l)
+ + this%harvest_n_to_cwdn_col(c,j) &
+ + this%fire_mortality_n_to_cwdn_col(c,j)
end if
@@ -3228,34 +3240,36 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc)
this%externaln_to_decomp_npools_col(c,j,l) = 0._r8
end if
- end do
- end do
- end do
+ end do !l = 1, ndecomp_pools
+ end do !j = 1, nlevdecomp_full
+ end do !fc = 1,num_soilc
+
- ! if pflotran hydrology NOT coupled, need to do adjusting for NO3 leaching for balance error checking
+ ! if pflotran hydrology NOT coupled, need to do:
+ ! saving for (next time-step) possible including of RT mass-transfer in PFLOTRAN bgc coupling.
+ ! (NOT USED anymore - 04/26/2017)
if (.not. pf_hmode) then
- do j = 1, nlevdecomp
+ do j = 1, nlevdecomp_full
do fc = 1,num_soilc
c = filter_soilc(fc)
- !! wgs: EXCLUDE leaching from external input
- this%no3_net_transport_vr_col(c,j) = 0._r8
-! this%no3_net_transport_vr_col(c,j) = this%smin_no3_runoff_vr_col(c,j) + &
-! this%smin_no3_leached_vr_col(c,j)
- this%no3_net_transport_delta_col(c) = &
- this%no3_net_transport_delta_col(c) - &
- this%no3_net_transport_vr_col(c,j)*dzsoi_decomp(j)
+ this%no3_net_transport_vr_col(c,j) = this%smin_no3_runoff_vr_col(c,j) + &
+ this%smin_no3_leached_vr_col(c,j)
end do
end do
+ else
+ this%no3_net_transport_vr_col(:,:) = 0._r8
end if
! change the sign so that it is the increments from the previous time-step (unit: g/m2/s)
do fc = 1, num_soilc
c = filter_soilc(fc)
this%externaln_to_decomp_delta_col(c) = -this%externaln_to_decomp_delta_col(c)
- this%no3_net_transport_delta_col(c) = -this%no3_net_transport_delta_col(c)
end do
+
+ end if ! if (use_pflotran .and. pf_cmode)
+
end subroutine NSummary_interface
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
end module CNNitrogenFluxType
diff --git a/components/clm/src/biogeochem/CNNitrogenStateType.F90 b/components/clm/src/biogeochem/CNNitrogenStateType.F90
index b1ef450047b2..dd4ff3aa1a00 100644
--- a/components/clm/src/biogeochem/CNNitrogenStateType.F90
+++ b/components/clm/src/biogeochem/CNNitrogenStateType.F90
@@ -618,7 +618,7 @@ subroutine InitHistory(this, bounds)
vr_suffix = ""
endif
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMIN_NO3'//trim(vr_suffix), units='gN/m^3', type2d='levdcmp', &
avgflag='A', long_name='soil mineral NO3 (vert. res.)', &
@@ -630,10 +630,12 @@ subroutine InitHistory(this, bounds)
ptr_col=this%smin_nh4_vr_col)
! pflotran
- this%smin_nh4sorb_vr_col(begc:endc,:) = spval
- call hist_addfld_decomp (fname='SMIN_NH4SORB'//trim(vr_suffix), units='gN/m^3', type2d='levdcmp', &
+ if(use_pflotran .and. pf_cmode) then
+ this%smin_nh4sorb_vr_col(begc:endc,:) = spval
+ call hist_addfld_decomp (fname='SMIN_NH4SORB'//trim(vr_suffix), units='gN/m^3', type2d='levdcmp', &
avgflag='A', long_name='soil mineral NH4 absorbed (vert. res.)', &
ptr_col=this%smin_nh4sorb_vr_col)
+ end if
if ( nlevdecomp_full > 1 ) then
this%smin_no3_col(begc:endc) = spval
@@ -647,11 +649,13 @@ subroutine InitHistory(this, bounds)
ptr_col=this%smin_nh4_col)
! pflotran
- this%smin_nh4sorb_col(begc:endc) = spval
- call hist_addfld1d (fname='SMIN_NH4SORB', units='gN/m^2', &
+ if(use_pflotran .and. pf_cmode) then
+ this%smin_nh4sorb_col(begc:endc) = spval
+ call hist_addfld1d (fname='SMIN_NH4SORB', units='gN/m^2', &
avgflag='A', long_name='soil mineral NH4 absorbed', &
ptr_col=this%smin_nh4sorb_col)
- endif
+ end if
+ end if
this%sminn_vr_col(begc:endc,:) = spval
call hist_addfld_decomp (fname='SMINN'//trim(vr_suffix), units='gN/m^3', type2d='levdcmp', &
@@ -876,15 +880,19 @@ subroutine InitCold(this, bounds, &
this%decomp_npools_col(c,k) = decomp_cpools_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
this%decomp_npools_1m_col(c,k) = decomp_cpools_1m_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
end do
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
do j = 1, nlevdecomp_full
this%smin_nh4_vr_col(c,j) = 0._r8
this%smin_no3_vr_col(c,j) = 0._r8
- this%smin_nh4sorb_vr_col(c,j) = 0._r8
+ if(use_pflotran .and. pf_cmode) then
+ this%smin_nh4sorb_vr_col(c,j) = 0._r8
+ end if
end do
this%smin_nh4_col(c) = 0._r8
this%smin_no3_col(c) = 0._r8
- this%smin_nh4sorb_col(c) = 0._r8
+ if(use_pflotran .and. pf_cmode) then
+ this%smin_nh4sorb_col(c) = 0._r8
+ end if
end if
this%totlitn_col(c) = 0._r8
this%totsomn_col(c) = 0._r8
@@ -1135,7 +1143,7 @@ subroutine Restart ( this, bounds, ncid, flag, cnstate_vars )
interpinic_flag='interp' , readvar=readvar, data=ptr1d)
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
! smin_no3_vr
if (use_vertsoilc) then
ptr2d => this%smin_no3_vr_col(:,:)
@@ -1155,7 +1163,7 @@ subroutine Restart ( this, bounds, ncid, flag, cnstate_vars )
end if
end if
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
! smin_nh4
if (use_vertsoilc) then
ptr2d => this%smin_nh4_vr_col(:,:)
@@ -1237,7 +1245,7 @@ subroutine Restart ( this, bounds, ncid, flag, cnstate_vars )
decomp_cascade_state = 0
end if
! add info about the nitrification / denitrification state
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
decomp_cascade_state = decomp_cascade_state + 10
end if
if (flag == 'write') itemp = decomp_cascade_state
@@ -1419,7 +1427,7 @@ subroutine SetValues ( this, &
this%sminn_col(i) = value_column
this%ntrunc_col(i) = value_column
this%cwdn_col(i) = value_column
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_col(i) = value_column
this%smin_nh4_col(i) = value_column
if(use_pflotran .and. pf_cmode) then
@@ -1439,7 +1447,7 @@ subroutine SetValues ( this, &
i = filter_column(fi)
this%sminn_vr_col(i,j) = value_column
this%ntrunc_vr_col(i,j) = value_column
- if (use_nitrif_denitrif) then
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
this%smin_no3_vr_col(i,j) = value_column
this%smin_nh4_vr_col(i,j) = value_column
if(use_pflotran .and. pf_cmode) then
@@ -1500,6 +1508,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
use clm_varpar , only: nlevdecomp,ndecomp_cascade_transitions,ndecomp_pools
use clm_varctl , only: use_nitrif_denitrif
use subgridAveMod , only: p2c
+ use clm_varpar , only: nlevdecomp_full
!
! !ARGUMENTS:
class (nitrogenstate_type) :: this
@@ -1513,6 +1522,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
integer :: c,p,j,k,l ! indices
integer :: fp,fc ! lake filter indices
real(r8) :: maxdepth ! depth to integrate soil variables
+ integer :: nlev
!-----------------------------------------------------------------------
do fp = 1,num_soilp
@@ -1580,7 +1590,10 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
this%totpftn_col(bounds%begc:bounds%endc))
! vertically integrate NO3 NH4 N2O pools
- if (use_nitrif_denitrif) then
+ nlev = nlevdecomp
+ if (use_pflotran .and. pf_cmode) nlev = nlevdecomp_full
+
+ if (use_nitrif_denitrif .or. (use_pflotran .and. pf_cmode)) then
do fc = 1,num_soilc
c = filter_soilc(fc)
this%smin_no3_col(c) = 0._r8
@@ -1589,7 +1602,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
this%smin_nh4sorb_col(c) = 0._r8
end if
end do
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%smin_no3_col(c) = &
@@ -1615,7 +1628,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
c = filter_soilc(fc)
this%decomp_npools_col(c,l) = 0._r8
end do
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%decomp_npools_col(c,l) = &
@@ -1744,7 +1757,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
c = filter_soilc(fc)
this%sminn_col(c) = 0._r8
end do
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%sminn_col(c) = &
@@ -1758,7 +1771,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
c = filter_soilc(fc)
this%ntrunc_col(c) = 0._r8
end do
- do j = 1, nlevdecomp
+ do j = 1, nlev
do fc = 1,num_soilc
c = filter_soilc(fc)
this%ntrunc_col(c) = &
diff --git a/components/clm/src/biogeochem/CNPrecisionControlMod.F90 b/components/clm/src/biogeochem/CNPrecisionControlMod.F90
index 66cf3287d2f9..0969652f7b95 100644
--- a/components/clm/src/biogeochem/CNPrecisionControlMod.F90
+++ b/components/clm/src/biogeochem/CNPrecisionControlMod.F90
@@ -34,7 +34,7 @@ subroutine CNPrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp,
!
! !USES:
use clm_varctl , only : iulog, use_c13, use_c14, use_nitrif_denitrif, use_ed
- use clm_varpar , only : nlevdecomp, crop_prog
+ use clm_varpar , only : nlevdecomp_full, crop_prog
use pftvarcon , only : nc3crop
use tracer_varcon , only : is_active_betr_bgc
!
@@ -672,7 +672,7 @@ subroutine CNPrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp,
do fc = 1,num_soilc
c = filter_soilc(fc)
- do j = 1,nlevdecomp
+ do j = 1,nlevdecomp_full
! initialize the column-level C and N truncation terms
cc = 0._r8
if ( use_c13 ) cc13 = 0._r8
@@ -728,7 +728,7 @@ subroutine CNPrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp,
do fc = 1,num_soilc
c = filter_soilc(fc)
- do j = 1,nlevdecomp
+ do j = 1,nlevdecomp_full
if (abs(ns%smin_no3_vr_col(c,j)) < ncrit/1e4_r8) then
if ( ns%smin_no3_vr_col(c,j) < 0._r8 ) then
write(iulog, *) '-10^-12 < smin_no3 < 0. resetting to zero.'
diff --git a/components/clm/src/biogeochem/PStateUpdate1Mod.F90 b/components/clm/src/biogeochem/PStateUpdate1Mod.F90
index df256c52e58f..f60ee26f8bf4 100644
--- a/components/clm/src/biogeochem/PStateUpdate1Mod.F90
+++ b/components/clm/src/biogeochem/PStateUpdate1Mod.F90
@@ -19,7 +19,7 @@ module PStateUpdate1Mod
use PhosphorusStateType , only : phosphorusstate_type
use VegetationType , only : veg_pp
use tracer_varcon , only : is_active_betr_bgc
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
use clm_varctl , only : nu_com
!
diff --git a/components/clm/src/biogeochem/PStateUpdate2Mod.F90 b/components/clm/src/biogeochem/PStateUpdate2Mod.F90
index 927c5b3caddf..fbdcd64eb840 100644
--- a/components/clm/src/biogeochem/PStateUpdate2Mod.F90
+++ b/components/clm/src/biogeochem/PStateUpdate2Mod.F90
@@ -15,7 +15,7 @@ module PStateUpdate2Mod
use VegetationType , only : veg_pp
use pftvarcon , only : npcropmin
use tracer_varcon , only : is_active_betr_bgc
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
!
implicit none
diff --git a/components/clm/src/biogeochem/PStateUpdate3Mod.F90 b/components/clm/src/biogeochem/PStateUpdate3Mod.F90
index accd872dda4f..85f715bf06b7 100644
--- a/components/clm/src/biogeochem/PStateUpdate3Mod.F90
+++ b/components/clm/src/biogeochem/PStateUpdate3Mod.F90
@@ -18,7 +18,7 @@ module PStateUpdate3Mod
use PhosphorusFLuxType , only : phosphorusflux_type
use soilorder_varcon , only : smax,ks_sorption
use tracer_varcon , only : is_active_betr_bgc
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
use clm_varctl , only : use_pflotran, pf_cmode
use clm_varctl , only : nu_com
use VegetationPropertiesType , only : veg_vp
diff --git a/components/clm/src/biogeochem/PhosphorusFluxType.F90 b/components/clm/src/biogeochem/PhosphorusFluxType.F90
index 4c21c2ddcc23..df762ced93de 100755
--- a/components/clm/src/biogeochem/PhosphorusFluxType.F90
+++ b/components/clm/src/biogeochem/PhosphorusFluxType.F90
@@ -13,8 +13,8 @@ module PhosphorusFluxType
use LandunitType , only : lun_pp
use ColumnType , only : col_pp
use VegetationType , only : veg_pp
- !! bgc interface & pflotran:
- use clm_varctl , only : use_bgc_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc
+ ! bgc interface & pflotran:
+ use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc
!
! !PUBLIC TYPES:
implicit none
@@ -282,7 +282,7 @@ module PhosphorusFluxType
real(r8), pointer :: avail_retransp_patch (:) ! P flux available from retranslocation pool (gP/m2/s)
real(r8), pointer :: plant_palloc_patch (:) ! total allocated P flux (gP/m2/s)
- ! clm_bgc_interface & pflotran
+ ! clm_interface & pflotran
!------------------------------------------------------------------------
real(r8), pointer :: plant_pdemand_col (:) ! col P flux required to support initial GPP (gN/m2/s)
real(r8), pointer :: plant_pdemand_vr_col (:,:) ! col vertically-resolved P flux required to support initial GPP (gP/m3/s)
@@ -322,7 +322,7 @@ module PhosphorusFluxType
procedure , private :: InitAllocate
procedure , private :: InitHistory
procedure , private :: InitCold
- !! bgc & pflotran interface
+ ! bgc & pflotran interface
procedure , private :: PSummary_interface
end type phosphorusflux_type
@@ -645,7 +645,7 @@ subroutine InitAllocate(this, bounds)
allocate(this%plant_to_litter_pflux (begc:endc )) ; this%plant_to_litter_pflux (:) = nan
allocate(this%plant_to_cwd_pflux (begc:endc )) ; this%plant_to_cwd_pflux (:) = nan
- ! clm_bgc_interface & pflotran
+ ! clm_interface & pflotran
!------------------------------------------------------------------------
allocate(this%plant_pdemand_col (begc:endc)) ; this%plant_pdemand_col (:) = nan
allocate(this%plant_pdemand_vr_col (begc:endc,1:nlevdecomp_full)) ; this%plant_pdemand_vr_col (:,:) = nan
@@ -1496,7 +1496,7 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='total allocated P flux', &
ptr_patch=this%plant_palloc_patch, default='active')
- !! bgc interface
+ ! bgc interface
this%plant_pdemand_col(begc:endc) = spval
call hist_addfld1d (fname='PLANT_PDEMAND_COL', units='gN/m^2/s', &
avgflag='A', long_name='P flux required to support initial GPP', &
@@ -1694,7 +1694,7 @@ subroutine Restart (this, bounds, ncid, flag )
long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%plant_palloc_patch)
- ! clm_bgc_interface & pflotran
+ ! clm_interface & pflotran
!------------------------------------------------------------------------
if (use_pflotran .and. pf_cmode) then
! externalp_to_decomp_ppools_col
@@ -1742,7 +1742,7 @@ subroutine Restart (this, bounds, ncid, flag )
end if
end if
- end if !! if (use_pflotran .and. pf_cmode)
+ end if ! if (use_pflotran .and. pf_cmode)
!------------------------------------------------------------------------
end subroutine Restart
@@ -1995,7 +1995,7 @@ subroutine SetValues ( this, &
this%fire_ploss_col(i) = value_column
this%wood_harvestp_col(i) = value_column
- !! bgc-interface
+ ! bgc-interface
this%plant_pdemand_col(i) = value_column
this%fire_ploss_col(i) = value_column
@@ -2047,6 +2047,7 @@ subroutine SetValues ( this, &
do fi = 1,num_column
i = filter_column(fi)
this%decomp_ppools_sourcesink_col(i,j,k) = value_column
+ this%biochem_pmin_ppools_vr_col(i,j,k) = value_column ! this is needed, if no P cycle
end do
end do
end do
@@ -2221,7 +2222,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end do
end do
end do
- end if !!if (.not.(use_pflotran .and. pf_cmode))
+ end if !if (.not.(use_pflotran .and. pf_cmode))
!-----------------------------------------------------------------
! vertically integrate inorganic P flux
@@ -2405,21 +2406,21 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil
end do
end do
- !! bgc interface & pflotran:
+ ! bgc interface & pflotran:
!----------------------------------------------------------------
- if (use_bgc_interface) then
+ if (use_clm_interface) then
call PSummary_interface(this, bounds, num_soilc, filter_soilc)
end if
!----------------------------------------------------------------
end subroutine Summary
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
! !INTERFACE:
subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
!
! !DESCRIPTION:
-!! bgc interface & pflotran:
+! bgc interface & pflotran:
! On the radiation time step, perform olumn-level nitrogen
! summary calculations, which mainly from PFLOTRAN bgc coupling
!
@@ -2436,10 +2437,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
type(bounds_type) , intent(in) :: bounds
integer, intent(in) :: num_soilc ! number of soil columns in filter
integer, intent(in) :: filter_soilc(:) ! filter for soil columns
-!
-! !REVISION HISTORY:
-!!08/26/2015: created by Gangsheng Wang
-!
+
! !LOCAL VARIABLES:
integer :: c,j, l ! indices
integer :: fc ! column filter indices
@@ -2448,7 +2446,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
! set time steps
dtime = real( get_step_size(), r8 )
if (use_pflotran .and. pf_cmode) then
- !! TODO
+ ! TODO
end if
! summarize at column-level vertically-resolved littering/removal for PFLOTRAN bgc input needs
@@ -2492,9 +2490,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%phenology_p_to_litr_met_p_col(c,j) &
+ this%dwt_frootp_to_litr_met_p_col(c,j) &
+ this%gap_mortality_p_to_litr_met_p_col(c,j) &
- + this%harvest_p_to_litr_met_p_col(c,j) !!&
-! + this%m_p_to_litr_met_fire_col(c,j) &
-! - this%m_decomp_ppools_to_fire_vr_col(c,j,l)
+ + this%harvest_p_to_litr_met_p_col(c,j)
elseif (l==i_cel_lit) then
this%externalp_to_decomp_ppools_col(c,j,l) = &
@@ -2502,9 +2498,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%phenology_p_to_litr_cel_p_col(c,j) &
+ this%dwt_frootp_to_litr_cel_p_col(c,j) &
+ this%gap_mortality_p_to_litr_cel_p_col(c,j) &
- + this%harvest_p_to_litr_cel_p_col(c,j) !!&
-! + this%m_p_to_litr_cel_fire_col(c,j) &
-! - this%m_decomp_ppools_to_fire_vr_col(c,j,l)
+ + this%harvest_p_to_litr_cel_p_col(c,j)
elseif (l==i_lig_lit) then
this%externalp_to_decomp_ppools_col(c,j,l) = &
@@ -2512,9 +2506,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%phenology_p_to_litr_lig_p_col(c,j) &
+ this%dwt_frootp_to_litr_lig_p_col(c,j) &
+ this%gap_mortality_p_to_litr_lig_p_col(c,j) &
- + this%harvest_p_to_litr_lig_p_col(c,j) !!&
-! + this%m_p_to_litr_lig_fire_col(c,j) &
-! - this%m_decomp_ppools_to_fire_vr_col(c,j,l)
+ + this%harvest_p_to_litr_lig_p_col(c,j)
! for cwd
elseif (l==i_cwd) then
@@ -2523,14 +2515,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
+ this%dwt_livecrootp_to_cwdp_col(c,j) &
+ this%dwt_deadcrootp_to_cwdp_col(c,j) &
+ this%gap_mortality_p_to_cwdp_col(c,j) &
- + this%harvest_p_to_cwdp_col(c,j) !!&
-! + this%fire_mortality_p_to_cwdp_col(c,j)
-!
- ! for som n
-! else
-! this%externalp_to_decomp_ppools_col(c,j,l) = &
-! this%externalp_to_decomp_ppools_col(c,j,l) &
-! - this%m_decomp_ppools_to_fire_vr_col(c,j,l)
+ + this%harvest_p_to_cwdp_col(c,j)
end if
@@ -2556,7 +2541,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
do fc = 1,num_soilc
c = filter_soilc(fc)
this%sminp_net_transport_vr_col(c,j) = 0._r8
-! this%sminp_net_transport_vr_col(c,j) = this%sminp_leached_vr_col(c,j)
+
this%sminp_net_transport_delta_col(c) = &
this%sminp_net_transport_delta_col(c) - &
this%sminp_net_transport_vr_col(c,j)*dzsoi_decomp(j)
@@ -2571,7 +2556,7 @@ subroutine PSummary_interface(this,bounds,num_soilc, filter_soilc)
this%sminp_net_transport_delta_col(c) = -this%sminp_net_transport_delta_col(c)
end do
end subroutine PSummary_interface
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
end module PhosphorusFluxType
diff --git a/components/clm/src/biogeophys/EnergyFluxType.F90 b/components/clm/src/biogeophys/EnergyFluxType.F90
index 1a8ab01e6787..8105549aaf81 100644
--- a/components/clm/src/biogeophys/EnergyFluxType.F90
+++ b/components/clm/src/biogeophys/EnergyFluxType.F90
@@ -94,6 +94,13 @@ module EnergyFluxType
! Latent heat
real(r8), pointer :: htvp_col (:) ! latent heat of vapor of water (or sublimation) [j/kg]
+ ! for couplig with pflotran
+ real(r8), pointer :: eflx_soil_grnd_col (:) ! col integrated soil ground heat flux (W/m2) [+ = into ground]
+ real(r8), pointer :: eflx_rnet_soil_col (:) ! col soil net (sw+lw) radiation flux (W/m2) [+ = into soil]
+ real(r8), pointer :: eflx_fgr0_soil_col (:) ! col soil-air heat flux (W/m2) [+ = into soil]
+ real(r8), pointer :: eflx_fgr0_snow_col (:) ! col soil-snow heat flux (W/m2) [+ = into soil]
+ real(r8), pointer :: eflx_fgr0_h2osfc_col (:) ! col soil-surfacewater heat flux (W/m2) [+ = into soil]
+
! Balance Checks
real(r8), pointer :: errsoi_patch (:) ! soil/lake energy conservation error (W/m**2)
real(r8), pointer :: errsoi_col (:) ! soil/lake energy conservation error (W/m**2)
@@ -222,6 +229,13 @@ subroutine InitAllocate(this, bounds)
allocate( this%htvp_col (begc:endc)) ; this%htvp_col (:) = nan
+ ! for coupling with pflotran
+ allocate( this%eflx_soil_grnd_col (begc:endc)) ; this%eflx_soil_grnd_col (:) = nan
+ allocate( this%eflx_rnet_soil_col (begc:endc)) ; this%eflx_rnet_soil_col (:) = nan
+ allocate( this%eflx_fgr0_soil_col (begc:endc)) ; this%eflx_fgr0_soil_col (:) = nan
+ allocate( this%eflx_fgr0_snow_col (begc:endc)) ; this%eflx_fgr0_snow_col (:) = nan
+ allocate( this%eflx_fgr0_h2osfc_col (begc:endc)) ; this%eflx_fgr0_h2osfc_col (:) = nan
+
allocate(this%rresis_patch (begp:endp,1:nlevgrnd)) ; this%rresis_patch (:,:) = nan
allocate(this%btran_patch (begp:endp)) ; this%btran_patch (:) = nan
allocate(this%btran2_patch (begp:endp)) ; this%btran2_patch (:) = nan
diff --git a/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90 b/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90
index 85244a692403..9cb4f458943e 100644
--- a/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90
+++ b/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90
@@ -35,6 +35,7 @@ Module HydrologyNoDrainageMod
subroutine HydrologyNoDrainage(bounds, &
num_nolakec, filter_nolakec, &
num_hydrologyc, filter_hydrologyc, &
+ num_hydrononsoic, filter_hydrononsoic, &
num_urbanc, filter_urbanc, &
num_snowc, filter_snowc, &
num_nosnowc, filter_nosnowc, &
@@ -63,7 +64,7 @@ subroutine HydrologyNoDrainage(bounds, &
use landunit_varcon , only : istice, istwet, istsoil, istice_mec, istcrop, istdlak
use column_varcon , only : icol_roof, icol_road_imperv, icol_road_perv, icol_sunwall
use column_varcon , only : icol_shadewall
- use clm_varctl , only : use_cn, use_betr, use_ed
+ use clm_varctl , only : use_cn, use_betr, use_ed, use_pflotran, pf_hmode
use clm_varpar , only : nlevgrnd, nlevsno, nlevsoi, nlevurb
use clm_time_manager , only : get_step_size, get_nstep
use SnowHydrologyMod , only : SnowCompaction, CombineSnowLayers, DivideSnowLayers
@@ -83,6 +84,8 @@ subroutine HydrologyNoDrainage(bounds, &
integer , intent(in) :: filter_nolakec(:) ! column filter for non-lake points
integer , intent(in) :: num_hydrologyc ! number of column soil points in column filter
integer , intent(in) :: filter_hydrologyc(:) ! column filter for soil points
+ integer , intent(in) :: num_hydrononsoic ! number of non-soil landunit points in hydrology filter
+ integer , intent(in) :: filter_hydrononsoic(:) ! column filter for non-soil hydrology points
integer , intent(in) :: num_urbanc ! number of column urban points in column filter
integer , intent(in) :: filter_urbanc(:) ! column filter for urban points
integer , intent(inout) :: num_snowc ! number of column snow points
@@ -183,8 +186,6 @@ subroutine HydrologyNoDrainage(bounds, &
call SnowWater(bounds, num_snowc, filter_snowc, num_nosnowc, filter_nosnowc, &
atm2lnd_vars, waterflux_vars, waterstate_vars, aerosol_vars)
-
-
! mapping soilmoist from CLM to VIC layers for runoff calculations
if (use_vichydro) then
call CLMVICMap(bounds, num_hydrologyc, filter_hydrologyc, &
@@ -194,9 +195,24 @@ subroutine HydrologyNoDrainage(bounds, &
call SurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, &
soilhydrology_vars, soilstate_vars, waterflux_vars, waterstate_vars)
- call Infiltration(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc,&
- energyflux_vars, soilhydrology_vars, soilstate_vars, temperature_vars, &
- waterflux_vars, waterstate_vars)
+ !------------------------------------------------------------------------------------
+ if (use_pflotran .and. pf_hmode) then
+
+ call Infiltration(bounds, num_hydrononsoic, filter_hydrononsoic, &
+ num_urbanc, filter_urbanc, &
+ energyflux_vars, soilhydrology_vars, soilstate_vars, temperature_vars, &
+ waterflux_vars, waterstate_vars)
+
+ else
+ !------------------------------------------------------------------------------------
+
+ call Infiltration(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, &
+ energyflux_vars, soilhydrology_vars, soilstate_vars, temperature_vars, &
+ waterflux_vars, waterstate_vars)
+
+ !------------------------------------------------------------------------------------
+ end if
+ !------------------------------------------------------------------------------------
if (use_betr) then
call ep_betr%BeTRSetBiophysForcing(bounds, col_pp, veg_pp, 1, nlevsoi, waterstate_vars=waterstate_vars)
@@ -218,9 +234,25 @@ subroutine HydrologyNoDrainage(bounds, &
if( use_ed ) call alm_fates%ComputeRootSoilFlux(bounds, num_hydrologyc, filter_hydrologyc, &
soilstate_vars, waterflux_vars)
- call SoilWater(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, &
+ !------------------------------------------------------------------------------------
+ if (use_pflotran .and. pf_hmode) then
+
+ call SoilWater(bounds, num_hydrononsoic, filter_hydrononsoic, &
+ num_urbanc, filter_urbanc, &
+ soilhydrology_vars, soilstate_vars, waterflux_vars, waterstate_vars, temperature_vars, &
+ soil_water_retention_curve)
+
+ else
+ !------------------------------------------------------------------------------------
+
+ call SoilWater(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, &
soilhydrology_vars, soilstate_vars, waterflux_vars, waterstate_vars, temperature_vars, &
soil_water_retention_curve)
+
+ !------------------------------------------------------------------------------------
+ end if
+ !------------------------------------------------------------------------------------
+
if (use_betr) then
call ep_betr%BeTRSetBiophysForcing(bounds, col_pp, veg_pp, 1, nlevsoi, waterstate_vars=waterstate_vars, &
@@ -237,9 +269,24 @@ subroutine HydrologyNoDrainage(bounds, &
soilhydrology_vars, waterstate_vars)
end if
- call WaterTable(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, &
+ !------------------------------------------------------------------------------------
+ if (use_pflotran .and. pf_hmode) then
+
+ call WaterTable(bounds, num_hydrononsoic, filter_hydrononsoic, &
+ num_urbanc, filter_urbanc, &
+ soilhydrology_vars, soilstate_vars, temperature_vars, waterstate_vars, waterflux_vars)
+
+ else
+ !------------------------------------------------------------------------------------
+
+ call WaterTable(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, &
soilhydrology_vars, soilstate_vars, temperature_vars, waterstate_vars, waterflux_vars)
+ !------------------------------------------------------------------------------------
+ end if
+ !------------------------------------------------------------------------------------
+
+
if (use_betr) then
!apply dew and sublimation fluxes, this is a temporary work aroud for tracking water isotope
!Jinyun Tang, Feb 4, 2015
@@ -406,7 +453,8 @@ subroutine HydrologyNoDrainage(bounds, &
end do
end do
- if (use_cn .or. use_ed) then
+ if ( (use_cn .or. use_ed) .and. &
+ .not.(use_pflotran .and. pf_hmode) ) then
! Update soilpsi.
! ZMS: Note this could be merged with the following loop updating smp_l in the future.
do j = 1, nlevgrnd
diff --git a/components/clm/src/biogeophys/SoilHydrologyMod.F90 b/components/clm/src/biogeophys/SoilHydrologyMod.F90
index 6cf30c3410f1..28dcc56e0178 100644
--- a/components/clm/src/biogeophys/SoilHydrologyMod.F90
+++ b/components/clm/src/biogeophys/SoilHydrologyMod.F90
@@ -981,9 +981,9 @@ subroutine Drainage(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filte
qflx_snwcp_liq => waterflux_vars%qflx_snwcp_liq_col , & ! Output: [real(r8) (:) ] excess rainfall due to snow capping (mm H2O /s) [+]
qflx_snwcp_ice => waterflux_vars%qflx_snwcp_ice_col , & ! Output: [real(r8) (:) ] excess snowfall due to snow capping (mm H2O /s) [+]
- qflx_dew_grnd => waterflux_vars%qflx_dew_grnd_col , & ! Output: [real(r8) (:) ] ground surface dew formation (mm H2O /s) [+]
- qflx_dew_snow => waterflux_vars%qflx_dew_snow_col , & ! Output: [real(r8) (:) ] surface dew added to snow pack (mm H2O /s) [+]
- qflx_sub_snow => waterflux_vars%qflx_sub_snow_col , & ! Output: [real(r8) (:) ] sublimation rate from snow pack (mm H2O /s) [+]
+ !qflx_dew_grnd => waterflux_vars%qflx_dew_grnd_col , & ! Output: [real(r8) (:) ] ground surface dew formation (mm H2O /s) [+]
+ !qflx_dew_snow => waterflux_vars%qflx_dew_snow_col , & ! Output: [real(r8) (:) ] surface dew added to snow pack (mm H2O /s) [+]
+ !qflx_sub_snow => waterflux_vars%qflx_sub_snow_col , & ! Output: [real(r8) (:) ] sublimation rate from snow pack (mm H2O /s) [+]
qflx_drain => waterflux_vars%qflx_drain_col , & ! Output: [real(r8) (:) ] sub-surface runoff (mm H2O /s)
qflx_qrgwl => waterflux_vars%qflx_qrgwl_col , & ! Output: [real(r8) (:) ] qflx_surf at glaciers, wetlands, lakes (mm H2O /s)
qflx_rsub_sat => waterflux_vars%qflx_rsub_sat_col , & ! Output: [real(r8) (:) ] soil saturation excess [mm h2o/s]
diff --git a/components/clm/src/biogeophys/TemperatureType.F90 b/components/clm/src/biogeophys/TemperatureType.F90
index 0232cab3f240..103ab8b8407e 100755
--- a/components/clm/src/biogeophys/TemperatureType.F90
+++ b/components/clm/src/biogeophys/TemperatureType.F90
@@ -103,6 +103,9 @@ module TemperatureType
! For VSFM model
real(r8), pointer :: t_soil_col_1d (:) ! 1D temperature of soil layers (Kelvin)
+ ! For coupling with pflotran
+ real(r8), pointer :: t_nearsurf_col (:) ! near-surface air temperature averaged over bare-veg as BC (Kelvin)
+
contains
procedure, public :: Init
@@ -237,7 +240,10 @@ subroutine InitAllocate(this, bounds)
allocate(this%c_h2osfc_col (begc:endc)) ; this%c_h2osfc_col (:) = nan
! For VSFM model
- allocate(this%t_soil_col_1d ((endc-begc+1)*nlevgrnd)) ; this%t_soil_col_1d (:) = nan
+ allocate(this%t_soil_col_1d ((endc-begc+1)*nlevgrnd)) ; this%t_soil_col_1d (:) = nan
+
+ ! for coupling with pflotran
+ allocate(this%t_nearsurf_col (begc:endc)) ; this%t_nearsurf_col (:) = nan
end subroutine InitAllocate
diff --git a/components/clm/src/biogeophys/WaterfluxType.F90 b/components/clm/src/biogeophys/WaterfluxType.F90
index ae35adc69678..ce49a8415c37 100644
--- a/components/clm/src/biogeophys/WaterfluxType.F90
+++ b/components/clm/src/biogeophys/WaterfluxType.F90
@@ -52,12 +52,12 @@ module WaterfluxType
real(r8), pointer :: qflx_prec_intr_patch (:) ! patch interception of precipitation [mm/s]
real(r8), pointer :: qflx_prec_intr_col (:) ! col interception of precipitation [mm/s]
- real(r8), pointer :: qflx_ev_snow_patch (:) ! patch evaporation heat flux from snow (W/m**2) [+ to atm]
- real(r8), pointer :: qflx_ev_snow_col (:) ! col evaporation heat flux from snow (W/m**2) [+ to atm]
- real(r8), pointer :: qflx_ev_soil_patch (:) ! patch evaporation heat flux from soil (W/m**2) [+ to atm]
- real(r8), pointer :: qflx_ev_soil_col (:) ! col evaporation heat flux from soil (W/m**2) [+ to atm]
- real(r8), pointer :: qflx_ev_h2osfc_patch (:) ! patch evaporation heat flux from soil (W/m**2) [+ to atm]
- real(r8), pointer :: qflx_ev_h2osfc_col (:) ! col evaporation heat flux from soil (W/m**2) [+ to atm]
+ real(r8), pointer :: qflx_ev_snow_patch (:) ! patch evaporation heat flux from snow (W/m**2) [+ to atm] ! NOTE: unit shall be mm H2O/s for water NOT heat
+ real(r8), pointer :: qflx_ev_snow_col (:) ! col evaporation heat flux from snow (W/m**2) [+ to atm] ! NOTE: unit shall be mm H2O/s for water NOT heat
+ real(r8), pointer :: qflx_ev_soil_patch (:) ! patch evaporation heat flux from soil (W/m**2) [+ to atm] ! NOTE: unit shall be mm H2O/s for water NOT heat
+ real(r8), pointer :: qflx_ev_soil_col (:) ! col evaporation heat flux from soil (W/m**2) [+ to atm] ! NOTE: unit shall be mm H2O/s for water NOT heat
+ real(r8), pointer :: qflx_ev_h2osfc_patch (:) ! patch evaporation heat flux from soil (W/m**2) [+ to atm] ! NOTE: unit shall be mm H2O/s for water NOT heat
+ real(r8), pointer :: qflx_ev_h2osfc_col (:) ! col evaporation heat flux from soil (W/m**2) [+ to atm] ! NOTE: unit shall be mm H2O/s for water NOT heat
real(r8), pointer :: qflx_gross_evap_soil_col (:) ! col gross infiltration from soil, this satisfies the relationship qflx_infl_col = qflx_gross_infl_soil_col-qflx_gross_evap_soil_col
real(r8), pointer :: qflx_gross_infl_soil_col (:) ! col gross infiltration, before considering the evaporation
diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90
index 45e3912c7af9..f47b3f5b4f3d 100644
--- a/components/clm/src/main/clm_driver.F90
+++ b/components/clm/src/main/clm_driver.F90
@@ -47,10 +47,10 @@ module clm_driver
!
use SurfaceRadiationMod , only : SurfaceRadiation, CanopySunShadeFractions
use UrbanRadiationMod , only : UrbanRadiation
- !clm_bgc_interface
+ !clm_interface
use CNEcosystemDynMod , only : CNEcosystemDynNoLeaching1, CNEcosystemDynNoLeaching2
- use CNEcosystemDynMod , only : CNEcosystemDynLeaching !!CNEcosystemDynNoLeaching,
+ use CNEcosystemDynMod , only : CNEcosystemDynLeaching
use CNVegStructUpdateMod , only : CNVegStructUpdate
use CNAnnualUpdateMod , only : CNAnnualUpdate
use CNBalanceCheckMod , only : BeginCBalance, BeginNBalance, CBalanceCheck, NBalanceCheck
@@ -125,20 +125,21 @@ module clm_driver
use shr_sys_mod , only : shr_sys_flush
use shr_log_mod , only : errMsg => shr_log_errMsg
- !!----------------------------------------------------------------------------
- !! bgc interface & pflotran:
- use clm_varctl , only : use_bgc_interface
- use clm_instMod , only : clm_bgc_data
- use clm_bgc_interfaceMod , only : get_clm_bgc_data
- !! (1) clm_bgc through interface
+ !----------------------------------------------------------------------------
+ ! bgc interface & pflotran:
+ use clm_varctl , only : use_clm_interface
+ use clm_instMod , only : clm_interface_data
+ use clm_interface_funcsMod , only : get_clm_data
+ ! (1) clm_bgc through interface
use clm_varctl , only : use_clm_bgc
- use clm_bgc_interfaceMod , only : clm_bgc_run, update_bgc_data_clm2clm
- !! (2) pflotran
- use clm_varctl , only : use_pflotran, pf_cmode, pf_hmode, pf_tmode
- use clm_bgc_interfaceMod , only : update_bgc_data_pf2clm
- use clm_pflotran_interfaceMod , only : clm_pf_run, clm_pf_write_restart
-! use clm_pflotran_interfaceMod , only : clm_pf_finalize
- !!----------------------------------------------------------------------------
+ use clm_interface_funcsMod , only : clm_bgc_run, update_bgc_data_clm2clm
+ ! (2) pflotran
+ use clm_time_manager , only : nsstep, nestep
+ use clm_varctl , only : use_pflotran, pf_cmode, pf_hmode, pf_tmode
+ use clm_interface_funcsMod , only : update_bgc_data_pf2clm, update_th_data_pf2clm
+ use clm_interface_pflotranMod , only : clm_pf_run, clm_pf_write_restart
+ use clm_interface_pflotranMod , only : clm_pf_finalize
+ !----------------------------------------------------------------------------
!
! !PUBLIC TYPES:
@@ -645,6 +646,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
call HydrologyNoDrainage(bounds_clump, &
filter(nc)%num_nolakec, filter(nc)%nolakec, &
filter(nc)%num_hydrologyc, filter(nc)%hydrologyc, &
+ filter(nc)%num_hydrononsoic, filter(nc)%hydrononsoic, &
filter(nc)%num_urbanc, filter(nc)%urbanc, &
filter(nc)%num_snowc, filter(nc)%snowc, &
filter(nc)%num_nosnowc, filter(nc)%nosnowc, &
@@ -773,11 +775,11 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
! - CNDV defined: prognostic biogeography; else prescribed
! - crop model: crop algorithms called from within CNEcosystemDyn
- !!===========================================================================================
- !! clm_bgc_interface: 'CNEcosystemDynNoLeaching' is divided into 2 subroutines (1 & 2): BEGIN
- !! CNEcosystemDynNoLeaching1 is called before clm_bgc_interface
- !! CNEcosystemDynNoLeaching2 is called after clm_bgc_interface
- !!===========================================================================================
+ !===========================================================================================
+ ! clm_interface: 'CNEcosystemDynNoLeaching' is divided into 2 subroutines (1 & 2): BEGIN
+ ! CNEcosystemDynNoLeaching1 is called before clm_interface
+ ! CNEcosystemDynNoLeaching2 is called after clm_interface
+ !===========================================================================================
call CNEcosystemDynNoLeaching1(bounds_clump, &
filter(nc)%num_soilc, filter(nc)%soilc, &
filter(nc)%num_soilp, filter(nc)%soilp, &
@@ -790,40 +792,36 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
ch4_vars, photosyns_vars, &
phosphorusflux_vars,phosphorusstate_vars)
- !!--------------------------------------------------------------------------------
- if (use_bgc_interface) then
- !! STEP-1: pass data from CLM to clm_bgc_data (INTERFACE DATA TYPE)
- call get_clm_bgc_data(clm_bgc_data,bounds_clump, &
+ !--------------------------------------------------------------------------------
+ if (use_clm_interface) then
+ ! STEP-1: pass data from CLM to clm_interface_data (INTERFACE DATA TYPE)
+ call get_clm_data(clm_interface_data,bounds_clump, &
filter(nc)%num_soilc, filter(nc)%soilc, &
filter(nc)%num_soilp, filter(nc)%soilp, &
- atm2lnd_vars, waterstate_vars, waterflux_vars, &
- soilstate_vars, temperature_vars, energyflux_vars, &
- soilhydrology_vars, soil_water_retention_curve, &
+ atm2lnd_vars, soilstate_vars, &
+ waterstate_vars, waterflux_vars, &
+ temperature_vars, energyflux_vars, &
cnstate_vars, carbonflux_vars, carbonstate_vars, &
nitrogenflux_vars, nitrogenstate_vars, &
phosphorusflux_vars, phosphorusstate_vars, &
- canopystate_vars, ch4_vars)
+ ch4_vars)
+
if (use_pflotran .and. pf_cmode) then
call t_startf('pflotran')
! -------------------------------------------------------------------------
! PFLOTRAN calling for solving below-ground and ground-surface processes,
! including thermal, hydrological and biogeochemical processes
- !! STEP-2: (1) pass data from clm_bgc_data to pflotran
- !! STEP-2: (2) run pflotran
- !! STEP-2: (3) update clm_bgc_data from pflotran
+ ! STEP-2: (1) pass data from clm_interface_data to pflotran
+ ! STEP-2: (2) run pflotran
+ ! STEP-2: (3) update clm_interface_data from pflotran
! -------------------------------------------------------------------------
- call clm_pf_run(clm_bgc_data,bounds_clump, &
- filter(nc)%num_soilc, filter(nc)%soilc)
+ call clm_pf_run(clm_interface_data, bounds_clump, filter, nc)
- !! STEP-3: update CLM from clm_bgc_data
- call update_bgc_data_pf2clm(clm_bgc_data,bounds_clump, &
- filter(nc)%num_soilc, filter(nc)%soilc, &
+ ! STEP-3: update CLM from clm_interface_data
+ call update_bgc_data_pf2clm(clm_interface_data%bgc, &
+ bounds_clump,filter(nc)%num_soilc, filter(nc)%soilc, &
filter(nc)%num_soilp, filter(nc)%soilp, &
- atm2lnd_vars, &
- waterstate_vars, waterflux_vars, &
- soilstate_vars, temperature_vars, energyflux_vars, &
- soilhydrology_vars, soil_water_retention_curve, &
cnstate_vars, carbonflux_vars, carbonstate_vars, &
nitrogenflux_vars, nitrogenstate_vars, &
phosphorusflux_vars, phosphorusstate_vars, &
@@ -834,12 +832,12 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
elseif (use_clm_bgc) then
call t_startf('clm-bgc via interface')
! -------------------------------------------------------------------------
- !! run clm-bgc (CNDecompAlloc) through interface
- !! STEP-2: (1) pass data from clm_bgc_data to CNDecompAlloc
- !! STEP-2: (2) run CNDecompAlloc
- !! STEP-2: (3) update clm_bgc_data from CNDecompAlloc
+ ! run clm-bgc (CNDecompAlloc) through interface
+ ! STEP-2: (1) pass data from clm_interface_data to CNDecompAlloc
+ ! STEP-2: (2) run CNDecompAlloc
+ ! STEP-2: (3) update clm_interface_data from CNDecompAlloc
! -------------------------------------------------------------------------
- call clm_bgc_run(clm_bgc_data, bounds_clump, &
+ call clm_bgc_run(clm_interface_data, bounds_clump, &
filter(nc)%num_soilc, filter(nc)%soilc, &
filter(nc)%num_soilp, filter(nc)%soilp, &
canopystate_vars, soilstate_vars, &
@@ -849,22 +847,18 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !! STEP-3: update CLM from clm_bgc_data
- call update_bgc_data_clm2clm(clm_bgc_data, bounds_clump, &
- filter(nc)%num_soilc, filter(nc)%soilc, &
+ ! STEP-3: update CLM from clm_interface_data
+ call update_bgc_data_clm2clm(clm_interface_data%bgc, &
+ bounds_clump, filter(nc)%num_soilc, filter(nc)%soilc,&
filter(nc)%num_soilp, filter(nc)%soilp, &
- atm2lnd_vars, &
- waterstate_vars, waterflux_vars, &
- soilstate_vars, temperature_vars, energyflux_vars, &
- soilhydrology_vars, soil_water_retention_curve, &
cnstate_vars, carbonflux_vars, carbonstate_vars, &
nitrogenflux_vars, nitrogenstate_vars, &
phosphorusflux_vars, phosphorusstate_vars, &
ch4_vars)
call t_stopf('clm-bgc via interface')
- end if !!if (use_pflotran .and. pf_cmode)
- end if !!if (use_bgc_interface)
- !!--------------------------------------------------------------------------------
+ end if !if (use_pflotran .and. pf_cmode)
+ end if !if (use_clm_interface)
+ !--------------------------------------------------------------------------------
call CNEcosystemDynNoLeaching2(bounds_clump, &
filter(nc)%num_soilc, filter(nc)%soilc, &
@@ -879,9 +873,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
dgvs_vars, photosyns_vars, soilhydrology_vars, energyflux_vars, &
phosphorusflux_vars,phosphorusstate_vars)
- !!===========================================================================================
- !! clm_bgc_interface: 'CNEcosystemDynNoLeaching' is divided into 2 subroutines (1 & 2): END
- !!===========================================================================================
+ !===========================================================================================
+ ! clm_interface: 'CNEcosystemDynNoLeaching' is divided into 2 subroutines (1 & 2): END
+ !===========================================================================================
call CNAnnualUpdate(bounds_clump, &
filter(nc)%num_soilc, filter(nc)%soilc, &
@@ -959,7 +953,20 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
call t_startf('hydro2 drainage')
- call HydrologyDrainage(bounds_clump, &
+ if (use_clm_interface .and. (use_pflotran .and. pf_hmode)) then
+ ! pflotran only works on 'soilc' (already done above).
+ ! here for non-soil hydrology columns
+ call HydrologyDrainage(bounds_clump, &
+ filter(nc)%num_nolakec, filter(nc)%nolakec, &
+ filter(nc)%num_hydrononsoic, filter(nc)%hydrononsoic, &
+ filter(nc)%num_urbanc, filter(nc)%urbanc, &
+ filter(nc)%num_do_smb_c, filter(nc)%do_smb_c, &
+ atm2lnd_vars, glc2lnd_vars, temperature_vars, &
+ soilhydrology_vars, soilstate_vars, waterstate_vars, waterflux_vars,ep_betr)
+
+ else
+
+ call HydrologyDrainage(bounds_clump, &
filter(nc)%num_nolakec, filter(nc)%nolakec, &
filter(nc)%num_hydrologyc, filter(nc)%hydrologyc, &
filter(nc)%num_urbanc, filter(nc)%urbanc, &
@@ -967,6 +974,8 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
atm2lnd_vars, glc2lnd_vars, temperature_vars, &
soilhydrology_vars, soilstate_vars, waterstate_vars, waterflux_vars,ep_betr)
+ end if
+
call t_stopf('hydro2 drainage')
if (use_betr) then
@@ -1279,13 +1288,6 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
soilstate_vars%bsw_col(bounds_proc%begc:bounds_proc%endc, 1:), &
soilstate_vars%hksat_col(bounds_proc%begc:bounds_proc%endc, 1:))
- !----------------------------------------------
- ! pflotran
- if (use_pflotran) then
- call clm_pf_write_restart(rdate)
- end if
- !----------------------------------------------
-
call t_stopf('clm_drv_io_htapes')
! Write to CNDV history buffer if appropriate
@@ -1313,12 +1315,24 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate)
phosphorusstate_vars,phosphorusflux_vars, &
ep_betr, alm_fates, rdate=rdate )
+ !----------------------------------------------
+ ! pflotran (off now)
+ ! if (use_pflotran) then
+ ! call clm_pf_write_restart(rdate)
+ ! end if
+ !----------------------------------------------
+
+
call t_stopf('clm_drv_io_wrest')
end if
call t_stopf('clm_drv_io')
end if
+ if (use_pflotran .and. nstep>=nestep) then
+ call clm_pf_finalize()
+ end if
+
end subroutine clm_drv
!-----------------------------------------------------------------------
diff --git a/components/clm/src/main/clm_initializeMod.F90 b/components/clm/src/main/clm_initializeMod.F90
index b52438bcae62..f4330c43347c 100644
--- a/components/clm/src/main/clm_initializeMod.F90
+++ b/components/clm/src/main/clm_initializeMod.F90
@@ -397,8 +397,8 @@ subroutine initialize2( )
use glc2lndMod , only : glc2lnd_type
use lnd2glcMod , only : lnd2glc_type
use SoilWaterRetentionCurveFactoryMod , only : create_soil_water_retention_curve
- use clm_varctl , only : use_bgc_interface, use_pflotran
- use clm_pflotran_interfaceMod , only : clm_pf_interface_init !!, clm_pf_set_restart_stamp
+ use clm_varctl , only : use_clm_interface, use_pflotran
+ use clm_interface_pflotranMod , only : clm_pf_interface_init !, clm_pf_set_restart_stamp
use tracer_varcon , only : is_active_betr_bgc
use clm_time_manager , only : is_restart
use ALMbetrNLMod , only : betr_namelist_buffer
@@ -531,9 +531,9 @@ subroutine initialize2( )
call clm_inst_biogeophys(bounds_proc)
- !allocate memory for betr simulator
- allocate(ep_betr, source=create_betr_simulation_alm())
if(use_betr)then
+ !allocate memory for betr simulator
+ allocate(ep_betr, source=create_betr_simulation_alm())
!set internal filters for betr
call ep_betr%BeTRSetFilter(maxpft_per_col=max_patch_per_col, boffline=.false.)
call ep_betr%InitOnline(bounds_proc, lun_pp, col_pp, veg_pp, waterstate_vars, betr_namelist_buffer, masterproc)
@@ -890,16 +890,16 @@ subroutine initialize2( )
deallocate(topo_glc_mec)
!------------------------------------------------------------
- !! initialize clm_bgc_interface_data_type
- call t_startf('init_clm_bgc_interface_data & pflotran')
- if (use_bgc_interface) then
- call clm_bgc_data%Init(bounds_proc)
+ ! initialize clm_bgc_interface_data_type
+ call t_startf('init_clm_interface_data & pflotran')
+ if (use_clm_interface) then
+ call clm_interface_data%Init(bounds_proc)
! PFLOTRAN initialization
if (use_pflotran) then
call clm_pf_interface_init(bounds_proc)
end if
end if
- call t_stopf('init_clm_bgc_interface_data & pflotran')
+ call t_stopf('init_clm_interface_data & pflotran')
!------------------------------------------------------------
!------------------------------------------------------------
diff --git a/components/clm/src/main/clm_instMod.F90 b/components/clm/src/main/clm_instMod.F90
index f7fb9efc07d3..0d2b8b3f6e0e 100644
--- a/components/clm/src/main/clm_instMod.F90
+++ b/components/clm/src/main/clm_instMod.F90
@@ -48,14 +48,13 @@ module clm_instMod
use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type
use UrbanParamsType , only : urbanparams_type ! Constants
use VegetationPropertiesType , only : veg_vp ! Ecophysical Constants
- ! use VegetationPropertiesType , only : veg_vp ! Constants
use SoilorderConType , only : soilordercon ! Constants
use LandunitType , only : lun_pp
use ColumnType , only : col_pp
use VegetationType , only : veg_pp
- use clm_bgc_interface_data , only : clm_bgc_interface_data_type
+ use clm_interface_dataType , only : clm_interface_data_type
use ChemStateType , only : chemstate_type ! structure for chemical indices of the soil, such as pH and Eh
use BeTRSimulationALM , only : betr_simulation_alm_type
use PlantMicKineticsMod , only : PlantMicKinetics_type
@@ -110,7 +109,7 @@ module clm_instMod
class(soil_water_retention_curve_type), allocatable :: soil_water_retention_curve
type(phosphorusstate_type) :: phosphorusstate_vars
type(phosphorusflux_type) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type) :: clm_bgc_data
+ type(clm_interface_data_type) :: clm_interface_data
type(chemstate_type) :: chemstate_vars
type(hlm_fates_interface_type) :: alm_fates
class(betr_simulation_alm_type), pointer :: ep_betr
diff --git a/components/clm/src/main/clm_bgc_interface_data.F90 b/components/clm/src/main/clm_interface_bgcType.F90
similarity index 74%
rename from components/clm/src/main/clm_bgc_interface_data.F90
rename to components/clm/src/main/clm_interface_bgcType.F90
index 64382b0bbda6..04c4998e5bae 100644
--- a/components/clm/src/main/clm_bgc_interface_data.F90
+++ b/components/clm/src/main/clm_interface_bgcType.F90
@@ -1,28 +1,22 @@
-module clm_bgc_interface_data
-!!=================================================================================================
+module clm_interface_bgcType
+!=================================================================================================
! CLM BioGeoChemistry (BGC) Interface: Data Type (Variables)
-!
-! Created by wgs @ ORNL
-!
-! date: 8/25/2015
-!!=================================================================================================
- !! USES:
+! created: 8/25/2015
+! update: 9/16/2016, 2/2/2017, May-2017, June-2017
+!=================================================================================================
+ ! USES:
use shr_log_mod , only : errMsg => shr_log_errMsg
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
- use clm_varpar , only : nlevsno, nlevgrnd
- use clm_varpar , only : nlevdecomp_full, ndecomp_pools, ndecomp_cascade_transitions
- use clm_varcon , only : spval
- use decompMod , only : bounds_type
implicit none
-! save
+!
private
- type, public :: clm_bgc_interface_data_type
+ type, public :: clm_interface_bgc_datatype
! clm_varpar
- integer :: nlevdecomp ! num of CLM soil layers that are mapped to/from PFLOTRAN
+ integer :: nlevdecomp_full ! num of CLM soil layers that are mapped to/from PFLOTRAN
integer :: ndecomp_pools ! num of decomposition pools
! decomp_cascade_con
@@ -30,38 +24,7 @@ module clm_bgc_interface_data
logical, pointer :: floating_cp_ratio (:) ! TRUE => pool has fixed C:P ratio
character(len=8), pointer :: decomp_pool_name (:) ! name of pool
real(r8), pointer :: initial_cn_ratio (:) ! c:n ratio for initialization of pools
- real(r8), pointer :: initial_cp_ratio (:) ! c:n ratio for initialization of pools
-
- ! col:
- real(r8), pointer :: z (:,:) ! layer depth (m) (-nlevsno+1:nlevgrnd)
- real(r8), pointer :: dz (:,:) ! layer thickness (m) (-nlevsno+1:nlevgrnd)
-
- ! soilstate_vars:
- real(r8), pointer :: bd_col (:,:) ! col bulk density of dry soil material [kg/m^3] (CN)
- real(r8), pointer :: hksat_col (:,:) ! col hydraulic conductivity at saturation (mm H2O /s)
- real(r8), pointer :: bsw_col (:,:) ! col Clapp and Hornberger "b" (nlevgrnd)
- real(r8), pointer :: watsat_col (:,:) ! col volumetric soil water at saturation (porosity)
- real(r8), pointer :: sucsat_col (:,:) ! col minimum soil suction (mm) (nlevgrnd)
- real(r8), pointer :: watfc_col (:,:) ! col volumetric soil water at field capacity (nlevsoi)
- real(r8), pointer :: porosity_col (:,:) ! col soil porisity (1-bulk_density/soil_density) (VIC)
- real(r8), pointer :: eff_porosity_col (:,:) ! col effective porosity = porosity - vol_ice (nlevgrnd)
- real(r8), pointer :: cellorg_col (:,:) ! col organic matter for gridcell containing column (1:nlevsoi)
- real(r8), pointer :: soilpsi_col (:,:) ! col soil water potential in each soil layer (MPa) (CN)
- real(r8), pointer :: rootfr_col (:,:) ! col fraction of roots in each soil layer (nlevgrnd)
-
- ! waterstate_vars:
- real(r8), pointer :: h2osoi_liq_col (:,:) ! col liquid water (kg/m2) (new) (-nlevsno+1:nlevgrnd)
- real(r8), pointer :: h2osoi_ice_col (:,:) ! col ice lens (kg/m2) (new) (-nlevsno+1:nlevgrnd)
- real(r8), pointer :: frac_sno_eff_col (:) ! col fraction of ground covered by snow (0 to 1)
- real(r8), pointer :: frac_h2osfc_col (:) ! col fractional area with surface water greater than zero
- real(r8), pointer :: h2osoi_vol_col (:,:) ! col volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3] (nlevgrnd)
-
- ! temperature_vars:
- real(r8), pointer :: t_soisno_col (:,:) ! col soil temperature (Kelvin) (-nlevsno+1:nlevgrnd)
- real(r8), pointer :: t_grnd_col (:) ! col ground temperature (Kelvin)
-
- ! canopystate_vars
- integer , pointer :: alt_indx_col (:) ! col current depth of thaw
+ real(r8), pointer :: initial_cp_ratio (:) ! c:p ratio for initialization of pools
! ch4
real(r8), pointer :: finundated_col (:) ! col fractional inundated area (excluding dedicated wetland cols)
@@ -72,6 +35,10 @@ module clm_bgc_interface_data
real(r8), pointer :: o2_decomp_depth_sat_col (:,:) ! col O2 consumption during decomposition in each soil layer (nlevsoi) (mol/m3/s)
real(r8), pointer :: o2_decomp_depth_unsat_col (:,:) ! col O2 consumption during decomposition in each soil layer (nlevsoi) (mol/m3/s)
+ ! cnstate_vars:
+ real(r8) , pointer :: rf_decomp_cascade_col (:,:,:) ! col respired fraction in decomposition step (frac)
+ real(r8) , pointer :: pathfrac_decomp_cascade_col (:,:,:) ! col what fraction of C leaving a given pool passes through a given
+
! carbonstate_vars:
real(r8), pointer :: decomp_cpools_vr_col (:,:,:) ! col (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
@@ -111,6 +78,10 @@ module clm_bgc_interface_data
real(r8), pointer :: sminn_to_denit_decomp_cascade_vr_col (:,:,:) ! col vertically-resolved denitrification along decomp cascade (gN/m3/s)
real(r8), pointer :: decomp_cascade_hr_vr_col (:,:,:) ! vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
+ real(r8), pointer :: o_scalar_col (:,:) ! fraction by which decomposition is limited by anoxia
+ real(r8), pointer :: w_scalar_col (:,:) ! fraction by which decomposition is limited by moisture availability
+ real(r8), pointer :: t_scalar_col (:,:) ! fraction by which decomposition is limited by temperature
+
! mineralization / immobilization / uptake flux
real(r8), pointer :: gross_nmin_vr_col (:,:) ! col vertically-resolved gross rate of N mineralization (gN/m3/s)
real(r8), pointer :: net_nmin_vr_col (:,:) ! col vertically-resolved net rate of N mineralization (gN/m3/s)
@@ -177,21 +148,23 @@ module clm_bgc_interface_data
real(r8) , pointer :: fpi_p_col (:) ! col fraction of potential immobilization (no units)
real(r8), pointer :: fpg_p_col (:) ! col fraction of potential gpp (no units)
- !!------------------------------------------------------------------------------------------
- !! pflotran variables: BEGIN
- !!------------------------------------------------------------------------------------------
+ !------------------------------------------------------------------------------------------
+ ! pflotran variables: BEGIN
+ !------------------------------------------------------------------------------------------
! bgc rates/fluxes (previous time-step) to decomposition pools
real(r8), pointer :: externalc_to_decomp_cpools_col (:,:,:) ! col (gC/m3/s) net C fluxes associated with litter/som-adding/removal to decomp pools
real(r8), pointer :: externaln_to_decomp_npools_col (:,:,:) ! col (gN/m3/s) net N fluxes associated with litter/som-adding/removal to decomp pools
real(r8), pointer :: externalp_to_decomp_ppools_col (:,:,:) ! col (gP/m3/s) net P fluxes associated with litter/som-adding/removal to decomp pools
-
+ real(r8), pointer :: decomp_k_pools (:) ! rate constant for each decomposition pool (1./sec)
+ real(r8), pointer :: sitefactor_kd_vr_col (:,:) ! a site factor for adjusting rate constant of all decomposition pools (-) (c,j)
+ real(r8), pointer :: adfactor_kd_pools (:) ! a speed-up factor for adjusting rate constant of individual decomposition pool (-) (k)
+
! bgc rates/fluxes (previous time-step) to nh4 / no3
real(r8), pointer :: externaln_to_nh4_col (:,:) ! col (gN/m3/s) net N fluxes to nh4 pool: deposition + fertilization + supplement + nfix + soyfixn
real(r8), pointer :: externaln_to_no3_col (:,:) ! col (gN/m3/s) net N fluxes to no3 pool: deposition + fertilization + supplement
real(r8), pointer :: externaln_to_sminn_col (:,:) ! col (gN/m3/s) net N fluxes to sminn pool: deposition + fertilization + supplement + nfix + soyfixn
real(r8), pointer :: smin_no3_leached_vr_col (:,:) ! col vertically-resolved soil mineral NO3 loss to leaching (gN/m3/s)
real(r8), pointer :: smin_no3_runoff_vr_col (:,:) ! col vertically-resolved rate of mineral NO3 loss with runoff (gN/m3/s)
- real(r8), pointer :: no3_net_transport_vr_col (:,:) ! col net NO3 transport associated with runoff/leaching (gN/m3/s)
! bgc rates/fluxes (previous time-step) to mineral P
real(r8), pointer :: externalp_to_primp_col (:,:) ! pdep_to_sminp_col (:) ! col atmospheric P deposition to soil mineral P (gP/m2/s)
@@ -205,62 +178,62 @@ module clm_bgc_interface_data
real(r8), pointer :: f_ngas_nitri_vr_col (:,:) ! col vertically-resolved N emission from nitrification (gN/m3/s)
real(r8), pointer :: f_ngas_denit_vr_col (:,:) ! col vertically-resolved N emission from denitrification (gN/m3/s)
- ! waterflux_vars:
- real(r8), pointer :: qflx_top_soil_col (:) ! col net water input into soil from top (mm/s)
- real(r8), pointer :: qflx_sub_snow_col (:) ! col sublimation rate from snow pack (mm H2O /s) [+]
- real(r8), pointer :: qflx_evap_soi_col (:) ! col soil evaporation (mm H2O/s) (+ = to atm)
- real(r8), pointer :: qflx_ev_h2osfc_col (:) ! col evaporation heat flux from soil (W/m**2) [+ to atm]
- real(r8), pointer :: qflx_tran_veg_col (:) ! col vegetation transpiration (mm H2O/s) (+ = to atm)
-
- ! energyflux_vars:
- real(r8), pointer :: htvp_col (:) ! latent heat of vapor of water (or sublimation) [j/kg]
- real(r8), pointer :: eflx_bot_col (:) ! col heat flux from beneath the soil or ice column (W/m**2)
- real(r8), pointer :: eflx_gnet_col (:) ! col net heat flux into ground (W/m**2)
- real(r8), pointer :: eflx_soil_grnd_col (:) ! col soil heat flux (W/m**2) [+ = into soil]
+ ! aq. phases:
+ real(r8), pointer :: no3_net_transport_vr_col (:,:) ! col net NO3 transport associated with runoff/leaching (gN/m3/s) - also store PF's N transport inc. diffusion at current time-step
+ real(r8), pointer :: nh4_net_transport_vr_col (:,:) ! col net NH4 transport associated with runoff/leaching (gN/m3/s) - also store PF's N transport inc. diffusion at current time-step
! atm2lnd:
- real(r8), pointer :: forc_pbot_not_downscaled_grc (:) ! not downscaled atm pressure (Pa)
real(r8), pointer :: forc_pco2_grc (:) ! CO2 partial pressure (Pa)
real(r8), pointer :: forc_pch4_grc (:) ! CH4 partial pressure (Pa)
- !!------------------------------------------------------------------------------------------
- !! pflotran variables: END
- !!------------------------------------------------------------------------------------------
+ ! mass balance check:
+ ! summary of layer 1:nlevdecomp_full
+ real(r8), pointer :: soil_begcb_col (:) ! soil organic carbon mass, beginning of time step (gC/m**2)
+ real(r8), pointer :: soil_begnb_col (:) ! soil nitrogen mass, beginning of time step (gN/m**2)
+ real(r8), pointer :: soil_begnb_org_col (:) ! soil organic nitrogen mass, beginning of time step (gN/m**2)
+ real(r8), pointer :: soil_begnb_min_col (:) ! soil mineral nitrogen mass, beginning of time step (gN/m**2) = no3 + nh4 + nh4sorb
+ !------------------------------------------------------------------------------------------
+ ! pflotran variables: END
+ !------------------------------------------------------------------------------------------
-!!-------------------------------------------------------------------------------------------------
+
+!-------------------------------------------------------------------------------------------------
contains
procedure , public :: Init
procedure , private :: InitAllocate
- end type clm_bgc_interface_data_type
-!!-------------------------------------------------------------------------------------------------
+ end type clm_interface_bgc_datatype
+!-------------------------------------------------------------------------------------------------
-!! type(clm_bgc_interface_data_type) , public, target , save :: clm_bgc_data
contains
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine Init(this, bounds)
- class(clm_bgc_interface_data_type) :: this
+ use decompMod , only : bounds_type
+ class(clm_interface_bgc_datatype) :: this
type(bounds_type), intent(in) :: bounds
call this%InitAllocate (bounds)
end subroutine Init
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
subroutine InitAllocate(this, bounds)
- !! USES
-
+ ! USES
+ use clm_varpar , only : nlevsno, nlevgrnd
+ use clm_varpar , only : nlevdecomp_full, ndecomp_pools, ndecomp_cascade_transitions
+ use clm_varcon , only : spval
+ use decompMod , only : bounds_type
- !! ARGUMENTS:
+ ! ARGUMENTS:
real(r8) :: ival = 0.0_r8 ! initial value
- class(clm_bgc_interface_data_type) :: this
- type(bounds_type), intent(in) :: bounds
+ class(clm_interface_bgc_datatype) :: this
+ type(bounds_type), intent(in) :: bounds
- !! LOCAL VARIABLES:
+ ! LOCAL VARIABLES:
integer :: begg, endg
integer :: begc, endc
integer :: begp, endp
@@ -276,36 +249,6 @@ subroutine InitAllocate(this, bounds)
allocate(this%initial_cn_ratio (0:ndecomp_pools)) ; this%initial_cn_ratio (:) = nan
allocate(this%initial_cp_ratio (0:ndecomp_pools)) ; this%initial_cp_ratio (:) = nan
- ! col:
- allocate(this%z (begc:endc,-nlevsno+1:nlevgrnd)) ; this%z (:,:) = nan
- allocate(this%dz (begc:endc,-nlevsno+1:nlevgrnd)) ; this%dz (:,:) = nan
- ! soilstate_vars:
- allocate(this%bd_col (begc:endc,nlevgrnd)) ; this%bd_col (:,:) = nan
- allocate(this%hksat_col (begc:endc,nlevgrnd)) ; this%hksat_col (:,:) = spval
- allocate(this%bsw_col (begc:endc,nlevgrnd)) ; this%bsw_col (:,:) = nan
- allocate(this%watsat_col (begc:endc,nlevgrnd)) ; this%watsat_col (:,:) = nan
- allocate(this%sucsat_col (begc:endc,nlevgrnd)) ; this%sucsat_col (:,:) = spval
- allocate(this%watfc_col (begc:endc,nlevgrnd)) ; this%watfc_col (:,:) = nan
- allocate(this%porosity_col (begc:endc,nlevgrnd)) ; this%porosity_col (:,:) = spval
- allocate(this%eff_porosity_col (begc:endc,nlevgrnd)) ; this%eff_porosity_col (:,:) = spval
- allocate(this%cellorg_col (begc:endc,nlevgrnd)) ; this%cellorg_col (:,:) = nan
- allocate(this%soilpsi_col (begc:endc,nlevgrnd)) ; this%soilpsi_col (:,:) = nan
- allocate(this%rootfr_col (begc:endc,1:nlevgrnd)) ; this%rootfr_col (:,:) = nan
-
- ! waterstate_vars:
- allocate(this%h2osoi_liq_col (begc:endc,-nlevsno+1:nlevgrnd)) ; this%h2osoi_liq_col (:,:) = nan
- allocate(this%h2osoi_ice_col (begc:endc,-nlevsno+1:nlevgrnd)) ; this%h2osoi_ice_col (:,:) = nan
- allocate(this%frac_sno_eff_col (begc:endc)) ; this%frac_sno_eff_col (:) = nan
- allocate(this%frac_h2osfc_col (begc:endc)) ; this%frac_h2osfc_col (:) = nan
- allocate(this%h2osoi_vol_col (begc:endc, 1:nlevgrnd)) ; this%h2osoi_vol_col (:,:) = nan
-
- ! temperature_vars:
- allocate(this%t_soisno_col (begc:endc,-nlevsno+1:nlevgrnd)) ; this%t_soisno_col (:,:) = nan
- allocate(this%t_grnd_col (begc:endc)) ; this%t_grnd_col (:) = nan
-
- ! canopystate_vars
- allocate(this%alt_indx_col (begc:endc)) ; this%alt_indx_col (:) = huge(1)
-
! ch4
allocate(this%finundated_col (begc:endc)) ; this%finundated_col (:) = nan
allocate(this%o2stress_unsat_col (begc:endc,1:nlevgrnd)) ; this%o2stress_unsat_col (:,:) = nan
@@ -315,6 +258,13 @@ subroutine InitAllocate(this, bounds)
allocate(this%o2_decomp_depth_sat_col (begc:endc,1:nlevgrnd)) ; this%o2_decomp_depth_sat_col (:,:) = nan
allocate(this%o2_decomp_depth_unsat_col (begc:endc,1:nlevgrnd)) ; this%o2_decomp_depth_unsat_col (:,:) = nan
+ ! cnstate_vars:
+ allocate(this%rf_decomp_cascade_col(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions));
+ this%rf_decomp_cascade_col(:,:,:) = nan
+
+ allocate(this%pathfrac_decomp_cascade_col(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions));
+ this%pathfrac_decomp_cascade_col(:,:,:) = nan
+
! carbonstate_vars:
allocate(this%decomp_cpools_vr_col (begc:endc,1:nlevdecomp_full,1:ndecomp_pools)); this%decomp_cpools_vr_col(:,:,:)= ival
allocate(this%decomp_npools_vr_col (begc:endc,1:nlevdecomp_full,1:ndecomp_pools)); this%decomp_npools_vr_col(:,:,:)= ival
@@ -355,6 +305,11 @@ subroutine InitAllocate(this, bounds)
allocate(this%decomp_cascade_hr_vr_col (begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions)); this%decomp_cascade_hr_vr_col (:,:,:) = ival
+ allocate(this%t_scalar_col (begc:endc,1:nlevdecomp_full)); this%t_scalar_col (:,:)=spval
+ allocate(this%w_scalar_col (begc:endc,1:nlevdecomp_full)); this%w_scalar_col (:,:)=spval
+ allocate(this%o_scalar_col (begc:endc,1:nlevdecomp_full)); this%o_scalar_col (:,:)=spval
+
+
! mineralization / immobilization / uptake fluxes
allocate(this%gross_nmin_vr_col (begc:endc,1:nlevdecomp_full)) ; this%gross_nmin_vr_col (:,:) = ival
allocate(this%net_nmin_vr_col (begc:endc,1:nlevdecomp_full)) ; this%net_nmin_vr_col (:,:) = ival
@@ -420,13 +375,17 @@ subroutine InitAllocate(this, bounds)
allocate(this%fpi_p_col (begc:endc)) ; this%fpi_p_col (:) = nan
allocate(this%fpg_p_col (begc:endc)) ; this%fpg_p_col (:) = nan
- !!------------------------------------------------------------------------------------------
- !! pflotran variables: BEGIN
- !!------------------------------------------------------------------------------------------
+ !------------------------------------------------------------------------------------------
+ ! pflotran variables: BEGIN
+ !------------------------------------------------------------------------------------------
! bgc rates/fluxes to decomposition pools
allocate(this%externalc_to_decomp_cpools_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)); this%externalc_to_decomp_cpools_col(:,:,:) = spval
allocate(this%externaln_to_decomp_npools_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)); this%externaln_to_decomp_npools_col(:,:,:) = spval
allocate(this%externalp_to_decomp_ppools_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)); this%externalp_to_decomp_ppools_col(:,:,:) = spval
+ allocate(this%decomp_k_pools (1:ndecomp_pools)) ; this%decomp_k_pools (:) = spval
+ allocate(this%adfactor_kd_pools (1:ndecomp_pools)) ; this%adfactor_kd_pools (:) = spval
+
+ allocate(this%sitefactor_kd_vr_col (begc:endc,1:nlevdecomp_full)) ; this%sitefactor_kd_vr_col (:,:) = spval
! bgc rates/fluxes to nh4 / no3
allocate(this%externaln_to_nh4_col (begc:endc,1:nlevdecomp_full)) ; this%externaln_to_nh4_col (:,:) = spval
@@ -435,6 +394,7 @@ subroutine InitAllocate(this, bounds)
allocate(this%smin_no3_leached_vr_col (begc:endc,1:nlevdecomp_full)) ; this%smin_no3_leached_vr_col (:,:) = ival
allocate(this%smin_no3_runoff_vr_col (begc:endc,1:nlevdecomp_full)) ; this%smin_no3_runoff_vr_col (:,:) = ival
allocate(this%no3_net_transport_vr_col (begc:endc,1:nlevdecomp_full)) ; this%no3_net_transport_vr_col (:,:) = spval
+ allocate(this%nh4_net_transport_vr_col (begc:endc,1:nlevdecomp_full)) ; this%nh4_net_transport_vr_col (:,:) = spval
! bgc rates/fluxes to mineral P
allocate(this%externalp_to_primp_col (begc:endc,1:nlevdecomp_full)) ; this%externalp_to_primp_col (:,:) = spval
@@ -448,28 +408,21 @@ subroutine InitAllocate(this, bounds)
allocate(this%f_ngas_nitri_vr_col (begc:endc,1:nlevdecomp_full)) ; this%f_ngas_nitri_vr_col (:,:) = ival
allocate(this%f_ngas_denit_vr_col (begc:endc,1:nlevdecomp_full)) ; this%f_ngas_denit_vr_col (:,:) = ival
- ! waterflux_vars:
- allocate(this%qflx_top_soil_col (begc:endc)) ; this%qflx_top_soil_col (:) = ival
- allocate(this%qflx_ev_h2osfc_col (begc:endc)) ; this%qflx_ev_h2osfc_col (:) = ival
- allocate(this%qflx_evap_soi_col (begc:endc)) ; this%qflx_evap_soi_col (:) = ival
- allocate(this%qflx_sub_snow_col (begc:endc)) ; this%qflx_sub_snow_col (:) = ival
- allocate(this%qflx_tran_veg_col (begc:endc)) ; this%qflx_tran_veg_col (:) = ival
-
- ! energyflux_vars:
- allocate( this%htvp_col (begc:endc)) ; this%htvp_col (:) = ival
- allocate( this%eflx_bot_col (begc:endc)) ; this%eflx_bot_col (:) = ival
- allocate( this%eflx_gnet_col (begc:endc)) ; this%eflx_bot_col (:) = ival
- allocate( this%eflx_soil_grnd_col (begc:endc)) ; this%eflx_soil_grnd_col (:) = ival
-
! atm2lnd:
- allocate(this%forc_pbot_not_downscaled_grc (begg:endg)) ; this%forc_pbot_not_downscaled_grc (:) = ival
allocate(this%forc_pco2_grc (begg:endg)) ; this%forc_pco2_grc (:) = ival
allocate(this%forc_pch4_grc (begg:endg)) ; this%forc_pch4_grc (:) = ival
- !!------------------------------------------------------------------------------------------
- !! pflotran variables: END
- !!------------------------------------------------------------------------------------------
+
+ ! mass balance check
+ allocate(this%soil_begcb_col (begc:endc)) ; this%soil_begcb_col (:) = ival
+ allocate(this%soil_begnb_col (begc:endc)) ; this%soil_begnb_col (:) = ival
+ allocate(this%soil_begnb_org_col (begc:endc)) ; this%soil_begnb_org_col (:) = ival
+ allocate(this%soil_begnb_min_col (begc:endc)) ; this%soil_begnb_min_col (:) = ival
+
+ !------------------------------------------------------------------------------------------
+ ! pflotran variables: END
+ !------------------------------------------------------------------------------------------
end subroutine InitAllocate
-!!-------------------------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------------------------
-end module clm_bgc_interface_data
+end module clm_interface_bgcType
diff --git a/components/clm/src/main/clm_interface_dataType.F90 b/components/clm/src/main/clm_interface_dataType.F90
new file mode 100644
index 000000000000..88df65bbcf7b
--- /dev/null
+++ b/components/clm/src/main/clm_interface_dataType.F90
@@ -0,0 +1,127 @@
+module clm_interface_dataType
+
+!=================================================================================================
+! ALM Thermal(T)-Hydrology (H) & BioGeoChemistry (BGC) Interface: Data Type (Variables)
+! created: 8/25/2015
+! update: 9/16/2016, 2/2/2017, May-2017, June-2017
+!=================================================================================================
+ ! USES:
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
+
+ use clm_interface_thType
+ use clm_interface_bgcType
+
+ implicit none
+
+ private
+
+!-------------------------------------------------------------------------------------------------
+ type, public :: clm_interface_data_type
+
+ ! col dimension
+ real(r8), pointer :: z (:,:) ! layer depth (m) (-nlevsno+1:nlevgrnd)
+ real(r8), pointer :: zi (:,:) ! layer depth (m) (-nlevsno+1:nlevgrnd)
+ real(r8), pointer :: dz (:,:) ! layer thickness (m) (-nlevsno+1:nlevgrnd)
+
+ ! soilstate_vars:
+ real(r8), pointer :: bd_col (:,:) ! col bulk density of dry soil material [kg/m^3] (CN)
+ real(r8), pointer :: hksat_col (:,:) ! col hydraulic conductivity at saturation (mm H2O /s)
+ real(r8), pointer :: bsw_col (:,:) ! col Clapp and Hornberger "b" (nlevgrnd)
+ real(r8), pointer :: watsat_col (:,:) ! col volumetric soil water at saturation (porosity)
+ real(r8), pointer :: watmin_col (:,:) ! col minimum volumetric soil water (nlevsoi)
+ real(r8), pointer :: sucsat_col (:,:) ! col minimum soil suction (mm) (nlevgrnd)
+ real(r8), pointer :: sucmin_col (:,:) ! col minimum allowable soil liquid suction pressure (mm) [Note: sucmin_col is a negative value, while sucsat_col is a positive quantity]
+ real(r8), pointer :: watfc_col (:,:) ! col volumetric soil water at field capacity (nlevsoi)
+ real(r8), pointer :: porosity_col (:,:) ! col soil porisity (1-bulk_density/soil_density) (VIC)
+ real(r8), pointer :: eff_porosity_col (:,:) ! col effective porosity = porosity - vol_ice (nlevgrnd)
+ real(r8), pointer :: cellorg_col (:,:) ! col organic matter for gridcell containing column (1:nlevsoi)
+ real(r8), pointer :: rootfr_col (:,:) ! col fraction of roots in each soil layer (nlevgrnd)
+
+ real(r8), pointer :: tkfrz_col (:,:) ! col thermal conductivity, frozen soil [W/m-K] (new) (nlevgrnd)
+ real(r8), pointer :: tkdry_col (:,:) ! col thermal conductivity, dry soil (W/m/Kelvin) (nlevgrnd)
+ real(r8), pointer :: tkwet_col (:,:) ! col thermal conductivity, saturated soil [W/m-K] (new) (nlevgrnd)
+ real(r8), pointer :: csol_col (:,:) ! col heat capacity, soil solids (J/m**3/Kelvin) (nlevgrnd)
+
+ ! thermal-hydrology:
+ type(clm_interface_th_datatype) :: th
+
+ ! biogeochemistry:
+ type(clm_interface_bgc_datatype):: bgc
+
+ !
+ contains
+ procedure , public :: Init
+ procedure , private :: InitAllocate
+ end type clm_interface_data_type
+!-------------------------------------------------------------------------------------------------
+
+
+contains
+
+!-------------------------------------------------------------------------------------------------
+ subroutine Init(this, bounds)
+ use decompMod , only : bounds_type
+ class(clm_interface_data_type) :: this
+ type(bounds_type), intent(in) :: bounds
+
+ call this%InitAllocate (bounds)
+
+ call this%th%Init(bounds)
+
+ call this%bgc%Init(bounds)
+
+ end subroutine Init
+!-------------------------------------------------------------------------------------------------
+
+!-------------------------------------------------------------------------------------------------
+
+ subroutine InitAllocate(this, bounds)
+ ! USES
+ use clm_varpar , only : nlevsno, nlevgrnd
+ use clm_varcon , only : spval
+ use decompMod , only : bounds_type
+
+ ! ARGUMENTS:
+ real(r8) :: ival = 0.0_r8 ! initial value
+ class(clm_interface_data_type) :: this
+ type(bounds_type), intent(in) :: bounds
+
+ ! LOCAL VARIABLES:
+ integer :: begg, endg
+ integer :: begc, endc
+ integer :: begp, endp
+ !------------------------------------------------------------------------
+ begg = bounds%begg; endg= bounds%endg
+ begc = bounds%begc; endc= bounds%endc
+ begp = bounds%begp; endp= bounds%endp
+
+ ! col:
+ allocate(this%z (begc:endc,-nlevsno+1:nlevgrnd)) ; this%z (:,:) = nan
+ allocate(this%zi (begc:endc,-nlevsno+0:nlevgrnd)) ; this%zi (:,:) = nan
+ allocate(this%dz (begc:endc,-nlevsno+1:nlevgrnd)) ; this%dz (:,:) = nan
+
+ ! soilstate_vars:
+ allocate(this%bd_col (begc:endc,1:nlevgrnd)) ; this%bd_col (:,:) = nan
+ allocate(this%hksat_col (begc:endc,1:nlevgrnd)) ; this%hksat_col (:,:) = spval
+ allocate(this%bsw_col (begc:endc,1:nlevgrnd)) ; this%bsw_col (:,:) = nan
+ allocate(this%watsat_col (begc:endc,1:nlevgrnd)) ; this%watsat_col (:,:) = nan
+ allocate(this%watmin_col (begc:endc,1:nlevgrnd)) ; this%watmin_col (:,:) = nan
+ allocate(this%sucsat_col (begc:endc,1:nlevgrnd)) ; this%sucsat_col (:,:) = spval
+ allocate(this%sucmin_col (begc:endc,1:nlevgrnd)) ; this%sucmin_col (:,:) = spval
+ allocate(this%watfc_col (begc:endc,1:nlevgrnd)) ; this%watfc_col (:,:) = nan
+ allocate(this%porosity_col (begc:endc,1:nlevgrnd)) ; this%porosity_col (:,:) = spval
+ allocate(this%eff_porosity_col (begc:endc,1:nlevgrnd)) ; this%eff_porosity_col (:,:) = spval
+ allocate(this%cellorg_col (begc:endc,1:nlevgrnd)) ; this%cellorg_col (:,:) = nan
+ allocate(this%rootfr_col (begc:endc,1:nlevgrnd)) ; this%rootfr_col (:,:) = nan
+
+ allocate(this%tkwet_col (begc:endc,1:nlevgrnd)) ; this%tkwet_col (:,:) = nan
+ allocate(this%tkdry_col (begc:endc,1:nlevgrnd)) ; this%tkdry_col (:,:) = nan
+ allocate(this%tkfrz_col (begc:endc,1:nlevgrnd)) ; this%tkfrz_col (:,:) = nan
+ allocate(this%csol_col (begc:endc,1:nlevgrnd)) ; this%csol_col (:,:) = nan
+
+ end subroutine InitAllocate
+!-------------------------------------------------------------------------------------------------
+
+end module clm_interface_dataType
diff --git a/components/clm/src/main/clm_bgc_interfaceMod.F90 b/components/clm/src/main/clm_interface_funcsMod.F90
similarity index 64%
rename from components/clm/src/main/clm_bgc_interfaceMod.F90
rename to components/clm/src/main/clm_interface_funcsMod.F90
index 3a7ba894214f..9244698bc0c1 100644
--- a/components/clm/src/main/clm_bgc_interfaceMod.F90
+++ b/components/clm/src/main/clm_interface_funcsMod.F90
@@ -1,29 +1,27 @@
-module clm_bgc_interfaceMod
-!!=================================================================================================
-! CLM BioGeoChemistry (BGC) Interface
-!
-! Created by wgs @ ORNL
-!
-! date: 8/25/2015
-!!=================================================================================================
+module clm_interface_funcsMod
+!=================================================================================================
+! CLM Theraml-Hydrology (TH) & BioGeoChemistry (BGC) Interface: Modules
+! created: 8/25/2015
+! updated: June-2017
+!=================================================================================================
#include "shr_assert.h"
- !! MODULE: clm_bgc_interfaceMod
- !!--------------------------------------------------------------------------------------
- !! DESCRIPTION:
- !! Coupling of CLM with any specific Soil BGC module Consists of 3 STEPS:
- !! STEP-1: clm vars -> clm_bgc_data (i.e. clm_bgc_interface_data_type) ; pass clm vars to clm_bgc_data
- !! STEP-2: clm_bgc_data -> soil bgc module -> clm_bgc_data
- !! 2.1: clm_bgc_data -> soil bgc module
- !! 2.2: run soil bgc module
- !! 2.3: soil bgc module -> clm_bgc_data
- !! STEP-3: clm_bgc_data -> clm vars
- !!--------------------------------------------------------------------------------------
+ ! MODULE: clm_interface_funcsMod
+ !--------------------------------------------------------------------------------------
+ ! DESCRIPTION:
+ ! Coupling of CLM with any specific Soil BGC module Consists of 3 STEPS:
+ ! STEP-1: clm vars -> clm_interface_data (i.e. clm_interface_dataType) ; pass clm vars to clm_interface_data
+ ! STEP-2: clm_interface_data -> soil bgc module -> clm_interface_data
+ ! 2.1: clm_interface_data -> soil bgc module
+ ! 2.2: run soil bgc module
+ ! 2.3: soil bgc module -> clm_interface_data
+ ! STEP-3: clm_interface_data -> clm vars
+ !--------------------------------------------------------------------------------------
- !!--------------------------------------------------------------------------------------
+ !--------------------------------------------------------------------------------------
! !USES:
! clm g/l/c/p constants
use shr_log_mod , only : errMsg => shr_log_errMsg
@@ -31,7 +29,7 @@ module clm_bgc_interfaceMod
use GridcellType , only : grc_pp
use LandunitType , only : lun_pp
use ColumnType , only : col_pp
- use VegetationType , only : veg_pp
+ use VegetationType , only : veg_pp
use decompMod , only : bounds_type
@@ -59,18 +57,21 @@ module clm_bgc_interfaceMod
use PhosphorusFluxType , only : phosphorusflux_type
use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type
- use clm_bgc_interface_data , only : clm_bgc_interface_data_type
+
+ use clm_interface_dataType , only : clm_interface_data_type
+ use clm_interface_thType , only : clm_interface_th_datatype
+ use clm_interface_bgcType , only : clm_interface_bgc_datatype
! most used constants in this module
- use clm_varpar , only : nlevsoi, nlevsno,nlevgrnd, nlevdecomp, nlevdecomp_full
- use clm_varpar , only : ndecomp_pools
+ use clm_varpar , only : nlevsoi, nlevsno, nlevgrnd, nlevdecomp_full
+ use clm_varpar , only : ndecomp_pools, ndecomp_cascade_transitions
use clm_varpar , only : max_patch_per_col
use clm_varcon , only : denh2o, denice, tfrz, dzsoi_decomp
use landunit_varcon , only : istsoil, istcrop
! misc.
use abortutils , only : endrun
- !!--------------------------------------------------------------------------------------
+ !--------------------------------------------------------------------------------------
implicit none
@@ -78,24 +79,24 @@ module clm_bgc_interfaceMod
private ! By default everything is private
- !! LOCAL VARIABLES:
+ ! LOCAL VARIABLES:
- !!--------------------------------------------------------------------------------------
- !! (1) GENERIC SUBROUTINES: used by any specific soil BGC module
- !! pass clm variables to clm_bgc_data
- public :: get_clm_bgc_data !! STEP-1: clm vars -> clm_bgc_data
+ !--------------------------------------------------------------------------------------
+ ! (1) GENERIC SUBROUTINES: used by any specific soil BGC module
+ ! pass clm variables to clm_bgc_data
+ public :: get_clm_data ! STEP-1: clm vars -> clm_interface_data
- !! pass clm variables to clm_bgc_data, called by get_clm_bgc_data
- private :: get_clm_soil_property !! STEP-1.1: soil properties
- private :: get_clm_soil_thermohydro !! STEP-1.2: thermohydrology vars
- private :: get_clm_bgc_state !! STEP-1.3: state vars
- private :: get_clm_bgc_flux !! STEP-1.4: flux vars
+ ! pass clm variables to clm_interface_data, called by get_clm_data
+ private :: get_clm_soil_property ! STEP-1.1: soil properties
+ private :: get_clm_soil_th_state ! STEP-1.2: thermohydrology (TH) state vars
+ private :: get_clm_bgc_state ! STEP-1.3: state vars
+ private :: get_clm_bgc_flux ! STEP-1.4: flux vars
- !! STEP-3.x: clm_bgc_data -> clm vars
- !! update clm variables from clm_bgc_data,
- !! e.g., called in 'update_bgc_data_clm2clm' and 'update_bgc_data_pf2clm'
- !! specific bgc-module (e.g., PFLOTRAN) requires certain combination of these subroutines
+ ! STEP-3.x: clm_interface_data -> clm vars
+ ! update clm variables from clm_interface_data,
+ ! e.g., called in 'update_bgc_data_clm2clm' and 'update_bgc_data_pf2clm'
+ ! specific bgc-module (e.g., PFLOTRAN) requires certain combination of these subroutines
private :: update_bgc_state_decomp
private :: update_bgc_state_smin
private :: update_bgc_flux_decomp_sourcesink
@@ -106,37 +107,38 @@ module clm_bgc_interfaceMod
private :: update_soil_moisture
private :: update_soil_temperature
- !!--------------------------------------------------------------------------------------
- !! (2) SPECIFIC SUBROUTINES: used by a specific soil BGC module
- !! (2.1) Specific Subroutines for running clm-bgc (CN or BGC) through interface
- !! if (use_bgc_interface .and. use_clm_bgc)
- public :: clm_bgc_run !! STEP-2: clm_bgc_data -> clm-bgc module -> clm_bgc_data ; called in clm_driver
- private :: clm_bgc_get_data !! STEP-2.1: clm_bgc_data -> clm-bgc module ; called in clm_bgc_run
- !! STEP-2.2: run clm-bgc module ; see CNDecompAlloc in CNDecompMod
- private :: clm_bgc_update_data !! STEP-2.3: clm-bgc module-> clm_bgc_data ; called in clm_bgc_run
- public :: update_bgc_data_clm2clm !! STEP-3: clm_bgc_data -> clm vars ; called in clm_driver
-
- !! (2.2) Specific Subroutines for CLM-PFLOTRAN Coupling: update clm variables from pflotran
- !! if (use_bgc_interface .and. use_pflotran)
- public :: update_bgc_data_pf2clm !! STEP-3: clm_bgc_data -> clm vars ; called in clm_driver
- !! STEP-2: see 'clm_pf_run' in clm_pflotran_interfaceMod
- !!--------------------------------------------------------------------------------------
+ !--------------------------------------------------------------------------------------
+ ! (2) SPECIFIC SUBROUTINES: used by a specific soil BGC module
+ ! (2.1) Specific Subroutines for running clm-bgc (CN or BGC) through interface
+ ! if (use_clm_interface .and. use_clm_bgc)
+ public :: clm_bgc_run ! STEP-2: clm_interface_data -> clm-bgc module -> clm_interface_data ; called in clm_driver
+ private :: clm_bgc_get_data ! STEP-2.1: clm_interface_data -> clm-bgc module ; called in clm_bgc_run
+ ! STEP-2.2: run clm-bgc module ; see CNDecompAlloc in CNDecompMod
+ private :: clm_bgc_update_data ! STEP-2.3: clm-bgc module-> clm_interface_data ; called in clm_bgc_run
+ public :: update_bgc_data_clm2clm ! STEP-3: clm_interface_data -> clm vars ; called in clm_driver
+
+ ! (2.2) Specific Subroutines for CLM-PFLOTRAN Coupling: update clm variables from pflotran
+ ! if (use_clm_interface .and. use_pflotran)
+ public :: update_bgc_data_pf2clm ! STEP-3: clm_interface_data -> clm vars ; called in clm_driver
+ ! STEP-2: see 'clm_pf_run' in clm_interface_pflotranMod
+
+ public :: update_th_data_pf2clm
+ !--------------------------------------------------------------------------------------
contains
-!!--------------------------------------------------------------------------------------
- subroutine get_clm_bgc_data(clm_bgc_data,bounds, &
- num_soilc, filter_soilc, &
+!--------------------------------------------------------------------------------------
+ subroutine get_clm_data(clm_idata, &
+ bounds, num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
- atm2lnd_vars, &
+ atm2lnd_vars, soilstate_vars, &
waterstate_vars, waterflux_vars, &
- soilstate_vars, temperature_vars, energyflux_vars, &
- soilhydrology_vars, soil_water_retention_curve, &
+ temperature_vars, energyflux_vars, &
cnstate_vars, carbonflux_vars, carbonstate_vars, &
nitrogenflux_vars, nitrogenstate_vars, &
phosphorusflux_vars, phosphorusstate_vars, &
- canopystate_vars, ch4_vars &
+ ch4_vars &
)
implicit none
@@ -148,12 +150,11 @@ subroutine get_clm_bgc_data(clm_bgc_data,bounds, &
integer , intent(in) :: num_soilp ! number of soil patches in filter
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
type(atm2lnd_type) , intent(in) :: atm2lnd_vars
- type(canopystate_type) , intent(in) :: canopystate_vars
+ type(soilstate_type) , intent(in) :: soilstate_vars
+
type(waterstate_type) , intent(in) :: waterstate_vars
type(waterflux_type) , intent(in) :: waterflux_vars
- type(soilstate_type) , intent(in) :: soilstate_vars
type(temperature_type) , intent(in) :: temperature_vars
- type(soilhydrology_type) , intent(in) :: soilhydrology_vars
type(energyflux_type) , intent(in) :: energyflux_vars
type(cnstate_type) , intent(in) :: cnstate_vars
@@ -165,45 +166,59 @@ subroutine get_clm_bgc_data(clm_bgc_data,bounds, &
type(phosphorusstate_type) , intent(in) :: phosphorusstate_vars
type(ch4_type) , intent(in) :: ch4_vars
- class(soil_water_retention_curve_type) , intent(in) :: soil_water_retention_curve
- type(clm_bgc_interface_data_type) , intent(inout) :: clm_bgc_data
+ type(clm_interface_data_type), intent(inout) :: clm_idata
+
+ ! LOCAL
+ !type(clm_interface_th_datatype) , pointer :: clm_idata_th
+ !type(clm_interface_bgc_datatype), pointer :: clm_idata_bgc
+
+ character(len=256) :: subname = "get_clm_data"
!-----------------------------------------------------------------------
- character(len=256) :: subname = "get_clm_bgc_data"
+ associate ( &
+ clm_idata_th => clm_idata%th, &
+ clm_idata_bgc => clm_idata%bgc &
+ )
- call get_clm_soil_property(clm_bgc_data, &
+ call get_clm_soil_property(clm_idata, &
bounds, num_soilc, filter_soilc, &
- soilstate_vars)
+ soilstate_vars, cnstate_vars)
- call get_clm_soil_thermohydro(clm_bgc_data, &
+ call get_clm_soil_th_state(clm_idata_th, &
bounds, num_soilc, filter_soilc, &
atm2lnd_vars, soilstate_vars, &
- waterstate_vars, waterflux_vars, &
- temperature_vars, energyflux_vars, &
- soil_water_retention_curve, &
- canopystate_vars, ch4_vars)
+ waterstate_vars, temperature_vars)
+
+ call get_clm_soil_th_flux(clm_idata_th, &
+ bounds, num_soilc, filter_soilc, &
+ waterflux_vars, energyflux_vars)
- call get_clm_bgc_state(clm_bgc_data, &
+ call get_clm_bgc_state(clm_idata_bgc, &
bounds, num_soilc, filter_soilc, &
+ atm2lnd_vars, soilstate_vars, &
carbonstate_vars, nitrogenstate_vars, &
- phosphorusstate_vars)
+ phosphorusstate_vars, &
+ ch4_vars)
- call get_clm_bgc_flux(clm_bgc_data, &
+ call get_clm_bgc_flux(clm_idata_bgc, &
bounds, num_soilc, filter_soilc, &
cnstate_vars, carbonflux_vars, &
- nitrogenflux_vars, phosphorusflux_vars)
+ nitrogenflux_vars, phosphorusflux_vars, &
+ ch4_vars)
- end subroutine get_clm_bgc_data
-!!--------------------------------------------------------------------------------------
+ end associate
+ end subroutine get_clm_data
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
- subroutine get_clm_soil_property(clm_bgc_data, &
+!--------------------------------------------------------------------------------------
+ subroutine get_clm_soil_property(clm_idata, &
bounds, num_soilc, filter_soilc, &
- soilstate_vars)
+ soilstate_vars, cnstate_vars)
+
!
! !DESCRIPTION:
- ! get soil column physical properties
+ ! get soil column physical and biogeochemical properties
!
! !USES:
use CNDecompCascadeConType, only : decomp_cascade_con
@@ -218,18 +233,20 @@ subroutine get_clm_soil_property(clm_bgc_data, &
integer , intent(in) :: num_soilc ! number of column soil points in column filter
integer , intent(in) :: filter_soilc(:) ! column filter for soil points
type(soilstate_type) , intent(in) :: soilstate_vars
+ type(cnstate_type) , intent(in) :: cnstate_vars
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
+ type(clm_interface_data_type), intent(inout) :: clm_idata
- integer :: fc, g, l, c, j ! indices
+ integer :: fc, g, l, c, j, k ! indices
integer :: gcount, cellcount
character(len= 32) :: subname = 'get_clm_soil_property' ! subroutine name
- associate( &
+ associate ( &
! Assign local pointer to derived subtypes components (column-level)
z => col_pp%z , & ! [real(r8) (:,:)] layer depth (m)
dz => col_pp%dz , & ! [real(r8) (:,:)] layer thickness depth (m)
+ zi => col_pp%zi , & !
bd => soilstate_vars%bd_col , & !
bsw => soilstate_vars%bsw_col , & ! [real(r8) (:,:)] Clapp and Hornberger "b" (nlevgrnd)
@@ -237,64 +254,80 @@ subroutine get_clm_soil_property(clm_bgc_data, &
sucsat => soilstate_vars%sucsat_col , & ! [real(r8) (:,:)] minimum soil suction (mm) (nlevgrnd)
watsat => soilstate_vars%watsat_col , & ! [real(r8) (:,:)] volumetric soil water at saturation (porosity) (nlevgrnd)
watfc => soilstate_vars%watfc_col , & ! [real(r8) (:,:)] volumetric soil water at saturation (porosity) (nlevgrnd)
-
- cellorg => soilstate_vars%cellorg_col , & ! Input: [real(r8) (:,:) ] column 3D org (kg/m3 organic matter) (nlevgrnd)
-
+ watmin => soilstate_vars%watmin_col , & ! col minimum volumetric soil water (nlevsoi)
+ sucmin => soilstate_vars%sucmin_col , & ! col minimum allowable soil liquid suction pressure (mm) [Note: sucmin_col is a negative value, while sucsat_col is a positive quantity]
+ !
+ cellorg => soilstate_vars%cellorg_col , & ! Input: [real(r8) (:,:) ] column 3D org (kg/m3 organic matter) (nlevgrnd)
+ !
porosity => soilstate_vars%porosity_col , &
eff_porosity => soilstate_vars%eff_porosity_col , &
-
+ !
+ rootfr => soilstate_vars%rootfr_col , & ! pft-level effective fraction of roots in each soil layer
+ !
initial_cn_ratio => decomp_cascade_con%initial_cn_ratio , &
initial_cp_ratio => decomp_cascade_con%initial_cp_ratio , &
-
+ !
decomp_pool_name => decomp_cascade_con%decomp_pool_name_history , &
floating_cn_ratio => decomp_cascade_con%floating_cn_ratio_decomp_pools , &
- floating_cp_ratio => decomp_cascade_con%floating_cp_ratio_decomp_pools &
+ floating_cp_ratio => decomp_cascade_con%floating_cp_ratio_decomp_pools , &
+ decomp_k_pools => decomp_cascade_con%decomp_k_pools , &
+ adfactor_kd_pools => decomp_cascade_con%spinup_factor , &
+ rf_decomp_cascade => cnstate_vars%rf_decomp_cascade_col , &
+ pathfrac_decomp_cascade => cnstate_vars%pathfrac_decomp_cascade_col &
)
!-------------------------------------------------------------------------------------
- !! constants:
- clm_bgc_data%ndecomp_pools = ndecomp_pools
- clm_bgc_data%decomp_pool_name(:) = decomp_pool_name(:)
- clm_bgc_data%floating_cn_ratio(:) = floating_cn_ratio(:)
- clm_bgc_data%floating_cp_ratio(:) = floating_cp_ratio(:)
-
- clm_bgc_data%initial_cn_ratio(:) = initial_cn_ratio(:)
- clm_bgc_data%initial_cp_ratio(:) = initial_cp_ratio(:)
-
+ ! constants:
+ clm_idata%bgc%ndecomp_pools = ndecomp_pools
+ clm_idata%bgc%decomp_pool_name(:) = decomp_pool_name(:)
+ clm_idata%bgc%floating_cn_ratio(:) = floating_cn_ratio(:)
+ clm_idata%bgc%floating_cp_ratio(:) = floating_cp_ratio(:)
+ clm_idata%bgc%initial_cn_ratio(:) = initial_cn_ratio(:)
+ clm_idata%bgc%initial_cp_ratio(:) = initial_cp_ratio(:)
+ clm_idata%bgc%decomp_k_pools(:) = decomp_k_pools(1:ndecomp_pools)
+ clm_idata%bgc%adfactor_kd_pools(:) = adfactor_kd_pools(1:ndecomp_pools)
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1,nlevsoi
- clm_bgc_data%z(c,:) = z(c,:)
- clm_bgc_data%dz(c,:) = dz(c,:)
- clm_bgc_data%bd_col(c,:) = bd(c,:)
- clm_bgc_data%bsw_col(c,:) = bsw(c,:)
- clm_bgc_data%hksat_col(c,:) = hksat(c,:)
- clm_bgc_data%sucsat_col(c,:) = sucsat(c,:)
- clm_bgc_data%watsat_col(c,:) = watsat(c,:)
- clm_bgc_data%watfc_col(c,:) = watfc(c,:)
-
- clm_bgc_data%porosity_col(c,:) = porosity(c,:)
- clm_bgc_data%eff_porosity_col(c,:) = eff_porosity(c,:)
-
- clm_bgc_data%cellorg_col(c,:) = cellorg(c,:)
-! end do
+
+ clm_idata%z(c,:) = z(c,:)
+ clm_idata%zi(c,:) = zi(c,:)
+ clm_idata%dz(c,:) = dz(c,:)
+ clm_idata%bd_col(c,:) = bd(c,:)
+ clm_idata%bsw_col(c,:) = bsw(c,:)
+ clm_idata%hksat_col(c,:) = hksat(c,:)
+ clm_idata%sucsat_col(c,:) = sucsat(c,:)
+ clm_idata%watsat_col(c,:) = watsat(c,:)
+ clm_idata%watfc_col(c,:) = watfc(c,:)
+ clm_idata%watmin_col(c,:) = watmin(c,:)
+ clm_idata%sucmin_col(c,:) = sucmin(c,:)
+
+ clm_idata%porosity_col(c,:) = porosity(c,:)
+ clm_idata%eff_porosity_col(c,:) = eff_porosity(c,:)
+
+ clm_idata%cellorg_col(c,:) = cellorg(c,:)
+
+ clm_idata%rootfr_col(c,:) = rootfr(c,:)
+
+ !
+ do k = 1, ndecomp_cascade_transitions
+ clm_idata%bgc%rf_decomp_cascade_col(c,:,k) = rf_decomp_cascade(c,:,k)
+ clm_idata%bgc%pathfrac_decomp_cascade_col(c,:,k) = pathfrac_decomp_cascade(c,:,k)
+ end do
+
end do
- end associate
+ end associate
end subroutine get_clm_soil_property
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
- subroutine get_clm_soil_thermohydro(clm_bgc_data, &
+!--------------------------------------------------------------------------------------
+ subroutine get_clm_soil_th_state(clm_idata_th, &
bounds, num_soilc, filter_soilc, &
atm2lnd_vars, soilstate_vars, &
- waterstate_vars, waterflux_vars, &
- temperature_vars, energyflux_vars, &
- soil_water_retention_curve, &
- canopystate_vars, ch4_vars)
+ waterstate_vars, temperature_vars)
!
! !DESCRIPTION:
! get soil temperature/saturation from CLM to soil BGC module
@@ -313,199 +346,216 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, &
type(atm2lnd_type) , intent(in) :: atm2lnd_vars
type(soilstate_type) , intent(in) :: soilstate_vars
type(waterstate_type) , intent(in) :: waterstate_vars
- type(waterflux_type) , intent(in) :: waterflux_vars
type(temperature_type) , intent(in) :: temperature_vars
- type(energyflux_type) , intent(in) :: energyflux_vars
- type(canopystate_type) , intent(in) :: canopystate_vars
- type(ch4_type) , intent(in) :: ch4_vars
- class(soil_water_retention_curve_type) , intent(in) :: soil_water_retention_curve
- type(clm_bgc_interface_data_type) , intent(inout) :: clm_bgc_data
+ type(clm_interface_th_datatype) , intent(inout) :: clm_idata_th
! !LOCAL VARIABLES:
- integer :: fc, c, j ! indices
- integer :: pftindex, p
-! real(r8) :: sattmp, psitmp, itheta
-! real(r8) :: watmin(num_soilc, nlevsoi)
-! real(r8) :: sucmin(num_soilc, nlevsoi)
+ integer :: fc, c, j ! indices
!EOP
!-----------------------------------------------------------------------
associate ( &
- gridcell => col_pp%gridcell , & ! column's gridcell
- wtgcell => col_pp%wtgcell , & ! column's weight relative to gridcell
- cactive => col_pp%active , & ! [logical (:)] column active or not
- dz => col_pp%dz , & ! layer thickness depth (m)
- zi => col_pp%zi , & ! interface depth (m)
-
- soilpsi => soilstate_vars%soilpsi_col , & ! soil water matric potential in each soil layer (MPa)
- rootfr => soilstate_vars%rootfr_col , & ! pft-level effective fraction of roots in each soil layer
-
- h2osoi_vol => waterstate_vars%h2osoi_vol_col , & ! Input: [real(r8) (:,:) ] volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3] (nlevgrnd)
- h2osoi_liq => waterstate_vars%h2osoi_liq_col , & ! liquid water (kg/m2)
- h2osoi_ice => waterstate_vars%h2osoi_ice_col , & ! ice lens (kg/m2)
- frac_sno => waterstate_vars%frac_sno_eff_col , & ! Input: fraction of ground covered by snow (0 to 1)
- frac_h2osfc => waterstate_vars%frac_h2osfc_col , & ! Input: fraction of ground covered by surface water (0 to 1)
-
- t_soisno => temperature_vars%t_soisno_col , & ! snow-soil temperature (Kelvin)
- t_grnd => temperature_vars%t_grnd_col , & ! Input: [real(r8) (:)] ground surface temperature [K]
-
- forc_pbot => atm2lnd_vars%forc_pbot_not_downscaled_grc, & ! atmospheric pressure (Pa)
- forc_pco2 => atm2lnd_vars%forc_pco2_grc , & ! partial pressure co2 (Pa)
- forc_pch4 => atm2lnd_vars%forc_pch4_grc , & ! partial pressure ch4 (Pa)
-
- alt_indx => canopystate_vars%alt_indx_col , & ! Input: [integer (:) ] current depth of thaw
- o2stress_sat => ch4_vars%o2stress_sat_col , & ! Input: [real(r8) (:,:) ] Ratio of oxygen available to that demanded by roots, aerobes, & methanotrophs (nlevsoi)
- o2stress_unsat => ch4_vars%o2stress_unsat_col , & ! Input: [real(r8) (:,:) ] Ratio of oxygen available to that demanded by roots, aerobes, & methanotrophs (nlevsoi)
- finundated => ch4_vars%finundated_col , & ! Input: [real(r8) (:) ] fractional inundated area (excluding dedicated wetland columns)
- o2_decomp_depth_unsat => ch4_vars%o2_decomp_depth_unsat_col , & ! Input: [real(r8) (:,:) ] O2 consumption during decomposition in each soil layer (nlevsoi) (mol/m3/s)
- conc_o2_unsat => ch4_vars%conc_o2_unsat_col , & ! Input: [real(r8) (:,:) ] O2 conc in each soil layer (mol/m3) (nlevsoi)
- o2_decomp_depth_sat => ch4_vars%o2_decomp_depth_sat_col , & ! Input: [real(r8) (:,:) ] O2 consumption during decomposition in each soil layer (nlevsoi) (mol/m3/s)
- conc_o2_sat => ch4_vars%conc_o2_sat_col , & ! Input: [real(r8) (:,:) ] O2 conc in each soil layer (mol/m3) (nlevsoi)
-
- htvp => energyflux_vars%htvp_col , & ! Input: [real(r8) (:)] latent heat of vapor of water (or sublimation) [j/kg]
- eflx_bot => energyflux_vars%eflx_bot_col , & ! heat flux from beneath column (W/m**2) [+ = upward]
- eflx_gnet_patch => energyflux_vars%eflx_gnet_patch , & ! net ground heat flux into the surface (W/m**2) per patch
- eflx_soil_grnd_patch => energyflux_vars%eflx_soil_grnd_patch , & ! soil heat flux (W/m**2) [+ = into soil]
-
- qflx_top_soil => waterflux_vars%qflx_top_soil_col , & ! Input: net water input into soil from top (mm/s)
- qflx_ev_h2osfc => waterflux_vars%qflx_ev_h2osfc_col , & ! Input: column-level evaporation flux from h2osfc (W/m2) [+ to atm] : checking unit
- qflx_evap_soi => waterflux_vars%qflx_evap_soi_col , & ! Input: column-level soil evaporation (mm H2O/s) (+ = to atm)
- qflx_sub_snow => waterflux_vars%qflx_sub_snow_col , & ! Input: column-level evaporation flux from snow (mm H2O/s) [+ to atm]
- qflx_tran_veg => waterflux_vars%qflx_tran_veg_col & ! Input: pft-level vegetation transpiration (mm H2O/s) (+ = to atm)
+ soilpsi => soilstate_vars%soilpsi_col , & !
+ !
+ frac_sno_eff => waterstate_vars%frac_sno_eff_col , & !
+ frac_h2osfc => waterstate_vars%frac_h2osfc_col , & !
+ h2osoi_vol => waterstate_vars%h2osoi_vol_col , & ! [real(r8) (:,:)] volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3] (nlevgrnd)
+ h2osoi_liq => waterstate_vars%h2osoi_liq_col , & ! [real(r8) (:,:)] liquid water (kg/m2) (-nlevsno+1:nlevgrnd)
+ h2osoi_ice => waterstate_vars%h2osoi_ice_col , & ! [real(r8) (:,:)] ice lens (kg/m2) (-nlevsno+1:nlevgrnd)
+ !
+ t_soisno => temperature_vars%t_soisno_col , & ! [real(r8) (:,:)] snow-soil temperature (Kelvin) (-nlevsno+1:nlevgrnd)
+ t_grnd => temperature_vars%t_grnd_col , & ! [real(r8) (:)] ground (snow/soil1/surfwater-mixed) temperature (Kelvin)
+ t_h2osfc => temperature_vars%t_h2osfc_col , & ! [real(r8) (:)] surface water temperature (Kelvin)
+ t_nearsurf => temperature_vars%t_nearsurf_col , & ! [real(r8) (:)] near surface air temperature (Kelvin)
+ !
+ forc_pbot => atm2lnd_vars%forc_pbot_not_downscaled_grc & ! atmospheric pressure (Pa)
+ )
- )
!--------------------------------------------------------------------------------------
-!
-! watmin(:,:) = 0.01_r8
-! sucmin(:,:) = 1.e8_r8
-
- !! grid:
- clm_bgc_data%forc_pbot_not_downscaled_grc(:) = forc_pbot(:)
- clm_bgc_data%forc_pco2_grc(:) = forc_pco2(:)
- clm_bgc_data%forc_pch4_grc(:) = forc_pch4(:)
-
+ ! grid:
+ clm_idata_th%forc_pbot_grc = forc_pbot
do fc = 1,num_soilc
c = filter_soilc(fc)
- clm_bgc_data%frac_sno_eff_col(c) = frac_sno(c)
- clm_bgc_data%frac_h2osfc_col(c) = frac_h2osfc(c)
+ clm_idata_th%frac_sno_eff_col(c) = frac_sno_eff(c)
+ clm_idata_th%frac_h2osfc_col(c) = frac_h2osfc(c)
- clm_bgc_data%t_grnd_col(c) = t_grnd(c)
+ clm_idata_th%t_grnd_col(c) = t_grnd(c)
+ clm_idata_th%t_h2osfc_col(c) = t_h2osfc(c)
+ clm_idata_th%t_nearsurf_col(c) = t_nearsurf(c)
- clm_bgc_data%alt_indx_col(c) = alt_indx(c)
- clm_bgc_data%finundated_col(c) = finundated(c)
+ do j = -nlevsno+1,nlevgrnd
+ if(j>=1) then
+ clm_idata_th%soilpsi_col(c,j) = soilpsi(c,j)
+ clm_idata_th%h2osoi_vol_col(c,j) = h2osoi_vol(c,j)
+ endif
- clm_bgc_data%qflx_top_soil_col(c) = qflx_top_soil(c)
- clm_bgc_data%qflx_ev_h2osfc_col(c) = qflx_ev_h2osfc(c)
- clm_bgc_data%qflx_evap_soi_col(c) = qflx_evap_soi(c)
- clm_bgc_data%qflx_sub_snow_col(c) = qflx_sub_snow(c)
- clm_bgc_data%qflx_tran_veg_col(c) = qflx_tran_veg(c)
+ clm_idata_th%h2osoi_liq_col(c,j) = h2osoi_liq(c,j)
+ clm_idata_th%h2osoi_ice_col(c,j) = h2osoi_ice(c,j)
+ clm_idata_th%t_soisno_col(c,j) = t_soisno(c,j)
+ end do
- clm_bgc_data%htvp_col(c) = htvp(c)
- clm_bgc_data%eflx_bot_col(c) = eflx_bot(c)
+ end do
-! do j = 1, nlevsoi
- clm_bgc_data%soilpsi_col(c,:) = soilpsi(c,:)
- clm_bgc_data%rootfr_col(c,:) = rootfr(c,:)
+ end associate
+ end subroutine get_clm_soil_th_state
+!--------------------------------------------------------------------------------------
- clm_bgc_data%h2osoi_vol_col(c,:) = h2osoi_vol(c,:)
- clm_bgc_data%h2osoi_liq_col(c,:) = h2osoi_liq(c,:)
- clm_bgc_data%h2osoi_ice_col(c,:) = h2osoi_ice(c,:)
+!--------------------------------------------------------------------------------------
+ subroutine get_clm_soil_th_flux(clm_idata_th, &
+ bounds, num_soilc, filter_soilc, &
+ waterflux_vars, energyflux_vars)
+ !
+ ! !DESCRIPTION:
+ ! get soil temperature/saturation from CLM to soil BGC module
+ !
+ ! !USES:
+ use clm_time_manager , only : get_nstep
+ use shr_const_mod , only : SHR_CONST_G
- clm_bgc_data%t_soisno_col(c,:) = t_soisno(c,:)
- clm_bgc_data%o2stress_unsat_col(c,:) = o2stress_unsat(c,:)
- clm_bgc_data%o2stress_sat_col(c,:) = o2stress_sat(c,:)
- clm_bgc_data%o2_decomp_depth_unsat_col(c,:) = o2_decomp_depth_unsat(c,:)
- clm_bgc_data%conc_o2_unsat_col(c,:) = conc_o2_unsat(c,:)
- clm_bgc_data%o2_decomp_depth_sat_col(c,:) = o2_decomp_depth_sat(c,:)
- clm_bgc_data%conc_o2_sat_col(c,:) = conc_o2_sat(c,:)
+ ! !ARGUMENTS:
+ implicit none
-! end do
- end do
+ type(bounds_type) , intent(in) :: bounds ! bounds
+ integer , intent(in) :: num_soilc ! number of column soil points in column filter
+ integer , intent(in) :: filter_soilc(:) ! column filter for soil points
+ type(waterflux_type) , intent(in) :: waterflux_vars
+ type(energyflux_type) , intent(in) :: energyflux_vars
- ! CLM appears NO column-level ground-heat-flux variable, instead by 'patch'
- do fc = 1, num_soilc
+ type(clm_interface_th_datatype) , intent(inout) :: clm_idata_th
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, j ! indices
+
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ qflx_top_soil => waterflux_vars%qflx_top_soil_col , & ! [real(:,:)] net liq. water input into top of soil column (mmH2O/s)
+ qflx_evap_soil => waterflux_vars%qflx_ev_soil_col , & ! [real(:)] ! col soil surface evaporation (mm H2O/s) (+ = to atm)
+ qflx_evap_h2osfc => waterflux_vars%qflx_ev_h2osfc_col , & ! [real(:)] ! col water surface evaporation (mm H2O/s) (+ = to atm)
+ qflx_evap_snow => waterflux_vars%qflx_ev_snow_col , & ! [real(:)] ! col snow surface evaporation (mm H2O/s) (+ = to atm)
+ qflx_subl_snow => waterflux_vars%qflx_sub_snow_col , & ! [real(:)] ! col snow sublimation (mm H2O/s) (+ = to atm)
+ qflx_tran_veg => waterflux_vars%qflx_tran_veg_col , & ! [real(:)] ! col plant transpiration (mm H2O/s) (+ = to atm)
+ qflx_rootsoil => waterflux_vars%qflx_rootsoi_col , & ! [real(:,:)] ! col vertically-resolved root and soil water exchange [mm H2O/s] [+ into root]
+ !
+ htvp => energyflux_vars%htvp_col , & ! [real(:) ! latent heat of vapor of water (or sublimation) [j/kg]
+ eflx_bot => energyflux_vars%eflx_bot_col , & ! [real(:) ! col heat flux from beneath the soil or ice column (W/m**2)
+ eflx_soil_grnd => energyflux_vars%eflx_soil_grnd_col , & ! [real(:) ! col soil (ground) heat flux (W/m**2) [+ = into ground]
+ eflx_fgr0_snow => energyflux_vars%eflx_fgr0_snow_col , & ! [real(:) ! col ground heat flux from snow bottom to first soil layer (W/m**2) [+ = into soil]
+ eflx_fgr0_h2osfc => energyflux_vars%eflx_fgr0_h2osfc_col , & ! [real(:) ! col ground heat flux from surface water bottom to first soil layer (W/m**2) [+ = into soil]
+ eflx_fgr0_soil => energyflux_vars%eflx_fgr0_soil_col , & ! [real(:) ! col ground heat flux from near-surface air to first soil layer (W/m**2) [+ = into soil]
+ eflx_rnet_soil => energyflux_vars%eflx_rnet_soil_col & ! [real(:) ! net radiation flux between soil layer 1 and above-air, excluding SH and LE (i.e. radiation form only ) (W/m2) [+ = into soil]
+
+ )
+
+ ! a few notes:
+ ! - 'qflx_evap_soil' appears for total soil surface, esp. bare soil; 'qflx_ev_soil/snow/h2osfc' are actually applied for in soil water modules
+ ! - 'qflx_ev_snow' vs. 'qflx_sub_snow': the former is for total evap from both solid/liq., the latter is from solid snow pack (normally shall be same)
+ ! there is another variable 'qlfx_evap_grnd', which are those from liq. water when snow
+ !--------------------------------------------------------------------------------------
+!
+ do fc = 1,num_soilc
c = filter_soilc(fc)
- clm_bgc_data%eflx_soil_grnd_col(c) = 0._r8
- clm_bgc_data%eflx_gnet_col(c) = 0._r8
- do pftindex = 1, max_patch_per_col
- if (pftindex <= col_pp%npfts(c)) then
- p = col_pp%pfti(c) + pftindex - 1
- clm_bgc_data%eflx_soil_grnd_col(c) = clm_bgc_data%eflx_soil_grnd_col(c) &
- + eflx_soil_grnd_patch(p) * veg_pp%wtcol(p) ! W/m2
- clm_bgc_data%eflx_gnet_col(c) = clm_bgc_data%eflx_gnet_col(c) &
- + eflx_gnet_patch(p) * veg_pp%wtcol(p)
- end if
- end do
+
+ clm_idata_th%qflx_top_soil_col(c) = qflx_top_soil(c)
+ clm_idata_th%qflx_evap_soil_col(c) = qflx_evap_soil(c)
+ clm_idata_th%qflx_evap_h2osfc_col(c) = qflx_evap_h2osfc(c)
+ clm_idata_th%qflx_evap_snow_col(c) = qflx_evap_snow(c)
+ clm_idata_th%qflx_subl_snow_col(c) = qflx_subl_snow(c)
+ clm_idata_th%qflx_tran_veg_col(c) = qflx_tran_veg(c)
+
+ do j = 1,nlevgrnd
+ clm_idata_th%qflx_rootsoil_col(c,j) = qflx_rootsoil(c,j)
+ end do
+
+ clm_idata_th%htvp_col(c) = htvp(c)
+ clm_idata_th%eflx_bot_col(c) = eflx_bot(c)
+ clm_idata_th%eflx_soil_grnd_col(c) = eflx_soil_grnd(c)
+ clm_idata_th%eflx_fgr0_snow_col(c) = eflx_fgr0_snow(c)
+ clm_idata_th%eflx_fgr0_h2osfc_col(c) = eflx_fgr0_h2osfc(c)
+ clm_idata_th%eflx_fgr0_soil_col(c) = eflx_fgr0_soil(c)
+ clm_idata_th%eflx_rnet_soil_col(c) = eflx_rnet_soil(c)
+
end do
-!
-!write(*,'(A30,12E14.6)')">>>DEBUG | soillsat=", soillsat_clmp_loc(1:10)
-!write(*,'(A30,12E14.6)')">>>DEBUG | gsoilpsi[Pa]=", soilpsi_clmp_loc(1:10)
-!write(*,'(A30,12E14.6)')">>>DEBUG | soilt[oC]=", soilt_clmp_loc(1:10)
+ end associate
+ end subroutine get_clm_soil_th_flux
+!--------------------------------------------------------------------------------------
- end associate
- end subroutine get_clm_soil_thermohydro
-!!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine get_clm_bgc_state(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
+ atm2lnd_vars, soilstate_vars, &
carbonstate_vars, nitrogenstate_vars, &
- phosphorusstate_vars)
+ phosphorusstate_vars, &
+ ch4_vars)
- !! get clm bgc state variables
+ ! get clm bgc state variables
implicit none
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilc ! number of soil columns in filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
+ type(atm2lnd_type) , intent(in) :: atm2lnd_vars
+ type(soilstate_type) , intent(in) :: soilstate_vars
type(carbonstate_type) , intent(in) :: carbonstate_vars
type(nitrogenstate_type) , intent(in) :: nitrogenstate_vars
type(phosphorusstate_type) , intent(in) :: phosphorusstate_vars
-! type(ch4_type) , intent(in) :: ch4_vars
+ type(ch4_type) , intent(in) :: ch4_vars ! not yet used, but will be.
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
+ type(clm_interface_bgc_datatype), intent(inout) :: clm_bgc_data
character(len=256) :: subname = "get_clm_bgc_state"
! Local variables
integer :: fc, c, j, k
-! integer :: gcount, cellcount
-! real(r8) :: wtgcell, realc_gcell, realn_gcell
-
!------------------------------------------------------------------------------------------
!
associate ( &
- decomp_cpools_vr=> carbonstate_vars%decomp_cpools_vr_col , & ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- decomp_npools_vr=> nitrogenstate_vars%decomp_npools_vr_col , & ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+ decomp_cpools_vr=> carbonstate_vars%decomp_cpools_vr_col , & ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ decomp_npools_vr=> nitrogenstate_vars%decomp_npools_vr_col , & ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
decomp_ppools_vr=> phosphorusstate_vars%decomp_ppools_vr_col , & ! [real(r8) (:,:,:) ! col (gP/m3) vertically-resolved decomposing (litter, cwd, soil) P pools
-
- smin_no3_vr => nitrogenstate_vars%smin_no3_vr_col , & ! (gN/m3) vertically-resolved soil mineral NO3
- smin_nh4_vr => nitrogenstate_vars%smin_nh4_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4
- smin_nh4sorb_vr => nitrogenstate_vars%smin_nh4sorb_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
-
+ smin_no3_vr => nitrogenstate_vars%smin_no3_vr_col , & ! (gN/m3) vertically-resolved soil mineral NO3
+ smin_nh4_vr => nitrogenstate_vars%smin_nh4_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4
+ smin_nh4sorb_vr => nitrogenstate_vars%smin_nh4sorb_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
+ !
solutionp_vr => phosphorusstate_vars%solutionp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil solution P
labilep_vr => phosphorusstate_vars%labilep_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil labile mineral P
secondp_vr => phosphorusstate_vars%secondp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil secondary mineralP
sminp_vr => phosphorusstate_vars%sminp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil mineral P = solutionp + labilep + secondp
occlp_vr => phosphorusstate_vars%occlp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil occluded mineral P
- primp_vr => phosphorusstate_vars%primp_vr_col & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil primary mineral P
+ primp_vr => phosphorusstate_vars%primp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil primary mineral P
+ !
+ forc_pco2 => atm2lnd_vars%forc_pco2_grc , & ! partial pressure co2 (Pa)
+ forc_pch4 => atm2lnd_vars%forc_pch4_grc , & ! partial pressure ch4 (Pa)
+ !
+ o2stress_sat => ch4_vars%o2stress_sat_col , & ! Input: [real(r8) (:,:) ] Ratio of oxygen available to that demanded by roots, aerobes, & methanotrophs (nlevsoi)
+ o2stress_unsat => ch4_vars%o2stress_unsat_col , & ! Input: [real(r8) (:,:) ] Ratio of oxygen available to that demanded by roots, aerobes, & methanotrophs (nlevsoi)
+ finundated => ch4_vars%finundated_col , & ! Input: [real(r8) (:) ] fractional inundated area (excluding dedicated wetland columns)
+ o2_decomp_depth_unsat => ch4_vars%o2_decomp_depth_unsat_col , & ! Input: [real(r8) (:,:) ] O2 consumption during decomposition in each soil layer (nlevsoi) (mol/m3/s)
+ conc_o2_unsat => ch4_vars%conc_o2_unsat_col , & ! Input: [real(r8) (:,:) ] O2 conc in each soil layer (mol/m3) (nlevsoi)
+ o2_decomp_depth_sat => ch4_vars%o2_decomp_depth_sat_col , & ! Input: [real(r8) (:,:) ] O2 consumption during decomposition in each soil layer (nlevsoi) (mol/m3/s)
+ conc_o2_sat => ch4_vars%conc_o2_sat_col & ! Input: [real(r8) (:,:) ] O2 conc in each soil layer (mol/m3) (nlevsoi)
)
!
+
+ clm_bgc_data%forc_pco2_grc(:) = forc_pco2(:)
+ clm_bgc_data%forc_pch4_grc(:) = forc_pch4(:)
+
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
do k = 1, ndecomp_pools
clm_bgc_data%decomp_cpools_vr_col(c,:,k) = decomp_cpools_vr(c,:,k)
clm_bgc_data%decomp_npools_vr_col(c,:,k) = decomp_npools_vr(c,:,k)
clm_bgc_data%decomp_ppools_vr_col(c,:,k) = decomp_ppools_vr(c,:,k)
+
end do
clm_bgc_data%smin_no3_vr_col(c,:) = smin_no3_vr(c,:)
@@ -518,30 +568,38 @@ subroutine get_clm_bgc_state(clm_bgc_data, &
clm_bgc_data%sminp_vr_col(c,:) = solutionp_vr(c,:) + labilep_vr(c,:) + secondp_vr(c,:)
clm_bgc_data%occlp_vr_col(c,:) = occlp_vr(c,:)
clm_bgc_data%primp_vr_col(c,:) = primp_vr(c,:)
-! end do
+
+ clm_bgc_data%finundated_col(c) = finundated(c)
+ clm_bgc_data%o2stress_unsat_col(c,:) = o2stress_unsat(c,:)
+ clm_bgc_data%o2stress_sat_col(c,:) = o2stress_sat(c,:)
+ clm_bgc_data%o2_decomp_depth_unsat_col(c,:) = o2_decomp_depth_unsat(c,:)
+ clm_bgc_data%conc_o2_unsat_col(c,:) = conc_o2_unsat(c,:)
+ clm_bgc_data%o2_decomp_depth_sat_col(c,:) = o2_decomp_depth_sat(c,:)
+ clm_bgc_data%conc_o2_sat_col(c,:) = conc_o2_sat(c,:)
+
end do
+!-----------------------------------------------------------------------------
end associate
end subroutine get_clm_bgc_state
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
- subroutine get_clm_bgc_flux(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
- cnstate_vars, carbonflux_vars, nitrogenflux_vars, &
- phosphorusflux_vars)
+!--------------------------------------------------------------------------------------
+ subroutine get_clm_bgc_flux(clm_bgc_data, &
+ bounds, num_soilc, filter_soilc, &
+ cnstate_vars, carbonflux_vars, &
+ nitrogenflux_vars, phosphorusflux_vars, &
+ ch4_vars)
!
! !DESCRIPTION:
- !! get clm bgc flux variables: external inputs to bgc state variables (pools)
+ ! get clm bgc flux variables: external inputs to bgc state variables (pools)
!
! !USES:
-
-! use clm_time_manager, only : get_step_size, get_nstep
-
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-
+ use clm_time_manager , only : get_curr_date
+ use clm_varctl , only : spinup_state
+ use CNDecompCascadeConType, only : decomp_cascade_con
! !ARGUMENTS:
implicit none
@@ -554,17 +612,18 @@ subroutine get_clm_bgc_flux(clm_bgc_data, &
type(carbonflux_type) , intent(in) :: carbonflux_vars
type(nitrogenflux_type) , intent(in) :: nitrogenflux_vars
type(phosphorusflux_type) , intent(in) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type) , intent(inout) :: clm_bgc_data
+ type(ch4_type) , intent(in) :: ch4_vars ! not yet used, but will be.
+
+ type(clm_interface_bgc_datatype) , intent(inout) :: clm_bgc_data
character(len=256) :: subname = "get_clm_bgc_flux"
! !LOCAL VARIABLES:
integer :: fc, c, g, j, k ! do loop indices
-! integer :: gcount, cellcount
-! real(r8) :: wtgcell, realc_gcell, realn_gcell
real(r8) :: dtime ! land model time step (sec)
+ integer :: year, mon, day, sec
! ratios of NH4:NO3 in N deposition and fertilization (temporarily set here, will be as inputs)
real(r8) :: r_nh4_no3_dep(bounds%begc:bounds%endc)
@@ -581,6 +640,9 @@ subroutine get_clm_bgc_flux(clm_bgc_data, &
externalc_to_decomp_cpools_vr => carbonflux_vars%externalc_to_decomp_cpools_col , &
externaln_to_decomp_npools_vr => nitrogenflux_vars%externaln_to_decomp_npools_col , &
externalp_to_decomp_ppools_vr => phosphorusflux_vars%externalp_to_decomp_ppools_col , &
+ t_scalar => carbonflux_vars%t_scalar_col , & ! Output: [real(r8) (:,:) ] soil temperature scalar for decomp
+ w_scalar => carbonflux_vars%w_scalar_col , & ! Output: [real(r8) (:,:) ] soil water scalar for decomp
+ o_scalar => carbonflux_vars%o_scalar_col , & ! Output: [real(r8) (:,:) ] fraction by which decomposition is limited by anoxia
! inorg. nitrogen source
ndep_to_sminn => nitrogenflux_vars%ndep_to_sminn_col , &
nfix_to_sminn => nitrogenflux_vars%nfix_to_sminn_col , &
@@ -591,7 +653,10 @@ subroutine get_clm_bgc_flux(clm_bgc_data, &
nfixation_prof => cnstate_vars%nfixation_prof_col , &
ndep_prof => cnstate_vars%ndep_prof_col , &
+ decomp_k_scalar => cnstate_vars%scalaravg_col , &
+
no3_net_transport_vr => nitrogenflux_vars%no3_net_transport_vr_col , &
+ nh4_net_transport_vr => nitrogenflux_vars%nh4_net_transport_vr_col , &
col_plant_ndemand_vr => nitrogenflux_vars%plant_ndemand_vr_col , &
plant_ndemand_col => nitrogenflux_vars%plant_ndemand_col , &
@@ -605,60 +670,78 @@ subroutine get_clm_bgc_flux(clm_bgc_data, &
sminp_net_transport_vr => phosphorusflux_vars%sminp_net_transport_vr_col &
)
-! dtime = get_step_size()
-
+ !
+ call get_curr_date(year, mon, day, sec)
!
r_nh4_no3_dep(:) = 1.0_r8 ! temporarily assuming half of N dep is in NH4 and another half in NO3
r_nh4_no3_fert(:) = 1.0_r8 ! temporarily assiming half of N fertilization is in NH4 and another half in NO3
+
!
do fc = 1,num_soilc
c = filter_soilc(fc)
+
+ clm_bgc_data%t_scalar_col(c,:) = t_scalar(c,:)
+ clm_bgc_data%w_scalar_col(c,:) = w_scalar(c,:)
+ clm_bgc_data%o_scalar_col(c,:) = o_scalar(c,:)
+
+
clm_bgc_data%plant_ndemand_col(c) = plant_ndemand_col(c)
clm_bgc_data%plant_pdemand_col(c) = plant_pdemand_col(c)
fnh4_dep = max(0._r8, min(1.0_r8, 1._r8/(r_nh4_no3_dep(c)+1._r8)))
fnh4_fert = max(0._r8, min(1.0_r8, 1._r8/(r_nh4_no3_fert(c)+1._r8)))
-! do j = 1, nlevdecomp
- do k = 1, ndecomp_pools
- clm_bgc_data%externalc_to_decomp_cpools_col(c,:,k) = externalc_to_decomp_cpools_vr(c,:,k)
- clm_bgc_data%externaln_to_decomp_npools_col(c,:,k) = externaln_to_decomp_npools_vr(c,:,k)
- clm_bgc_data%externalp_to_decomp_ppools_col(c,:,k) = externalp_to_decomp_ppools_vr(c,:,k)
- end do
+ do k = 1, ndecomp_pools
+ clm_bgc_data%externalc_to_decomp_cpools_col(c,:,k) = externalc_to_decomp_cpools_vr(c,:,k)
+ clm_bgc_data%externaln_to_decomp_npools_col(c,:,k) = externaln_to_decomp_npools_vr(c,:,k)
+ clm_bgc_data%externalp_to_decomp_ppools_col(c,:,k) = externalp_to_decomp_ppools_vr(c,:,k)
+ end do
- clm_bgc_data%externaln_to_nh4_col(c,:) = fnh4_dep*ndep_to_sminn(c) * ndep_prof(c,:) + &
- fnh4_fert*fert_to_sminn(c) * ndep_prof(c,:) + &
- fnh4_fert*supplement_to_sminn_vr(c,:) + &
- nfix_to_sminn(c) * nfixation_prof(c,:) + &
- soyfixn_to_sminn(c) * nfixation_prof(c,:)
+ ! the following is for CTC ad-spinup.
+ ! There is a 'time' control here, so MUST be called each time-step,
+ ! and then better put the code here rather than in 'get_clm_bgc_state'
+ if (spinup_state == 1 .and. year >= 40) then
+ clm_bgc_data%sitefactor_kd_vr_col(c,:) = decomp_k_scalar(c)
+ else
+ clm_bgc_data%sitefactor_kd_vr_col(c,:) = 1.0_r8
+ end if
- clm_bgc_data%externaln_to_no3_col(c,:) = (1._r8-fnh4_dep)*ndep_to_sminn(c) * ndep_prof(c, :) + &
- (1._r8-fnh4_fert)*fert_to_sminn(c) * ndep_prof(c, :) + &
- (1._r8-fnh4_fert)*supplement_to_sminn_vr(c,:)
- clm_bgc_data%externalp_to_primp_col(c,:) = pdep_to_sminp(c)*ndep_prof(c, :)
- clm_bgc_data%externalp_to_labilep_col(c,:) = fert_p_to_sminp(c)*ndep_prof(c, :)
- clm_bgc_data%externalp_to_solutionp_col(c,:) = supplement_to_sminp_vr(c,:)
- !! net flux to no3 = externaln_to_no3_col(c,j) - no3_net_transport_vr_col(c,j)
- clm_bgc_data%no3_net_transport_vr_col(c,:) = no3_net_transport_vr(c,:)
- clm_bgc_data%sminp_net_transport_vr_col(c,:) = sminp_net_transport_vr(c,:) !!from solutionp
+ clm_bgc_data%externaln_to_nh4_col(c,:) = fnh4_dep*ndep_to_sminn(c) * ndep_prof(c,:) + &
+ fnh4_fert*fert_to_sminn(c) * ndep_prof(c,:) + &
+ fnh4_fert*supplement_to_sminn_vr(c,:) + &
+ nfix_to_sminn(c) * nfixation_prof(c,:) + &
+ soyfixn_to_sminn(c) * nfixation_prof(c,:)
- clm_bgc_data%plant_ndemand_vr_col(c,:) = col_plant_ndemand_vr(c,:)
- clm_bgc_data%plant_pdemand_vr_col(c,:) = col_plant_pdemand_vr(c,:)
+ clm_bgc_data%externaln_to_no3_col(c,:) = (1._r8-fnh4_dep)*ndep_to_sminn(c) * ndep_prof(c, :) + &
+ (1._r8-fnh4_fert)*fert_to_sminn(c) * ndep_prof(c, :) + &
+ (1._r8-fnh4_fert)*supplement_to_sminn_vr(c,:)
-! end do
- end do
+
+
+ clm_bgc_data%externalp_to_primp_col(c,:) = pdep_to_sminp(c)*ndep_prof(c, :)
+ clm_bgc_data%externalp_to_labilep_col(c,:) = fert_p_to_sminp(c)*ndep_prof(c, :)
+ clm_bgc_data%externalp_to_solutionp_col(c,:) = supplement_to_sminp_vr(c,:)
+
+ clm_bgc_data%no3_net_transport_vr_col(c,:) = no3_net_transport_vr(c,:)
+ clm_bgc_data%nh4_net_transport_vr_col(c,:) = nh4_net_transport_vr(c,:)
+ clm_bgc_data%sminp_net_transport_vr_col(c,:) = sminp_net_transport_vr(c,:) !from solutionp
+
+ clm_bgc_data%plant_ndemand_vr_col(c,:) = col_plant_ndemand_vr(c,:)
+ clm_bgc_data%plant_pdemand_vr_col(c,:) = col_plant_pdemand_vr(c,:)
+
+ end do ! fc = 1,num_soilc
end associate
end subroutine get_clm_bgc_flux
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
- subroutine update_soil_moisture(clm_bgc_data, &
+!--------------------------------------------------------------------------------------
+ subroutine update_soil_moisture(clm_idata_th, &
bounds, num_soilc, filter_soilc, &
- waterstate_vars)
+ soilstate_vars, waterstate_vars)
!
! !DESCRIPTION:
@@ -672,9 +755,10 @@ subroutine update_soil_moisture(clm_bgc_data, &
type(bounds_type), intent(in) :: bounds
integer, intent(in) :: num_soilc ! number of column soil points in column filter
integer, intent(in) :: filter_soilc(:) ! column filter for soil points
-! type(soilstate_type) , intent(in) :: soilstate_vars
+ type(soilstate_type), intent(inout) :: soilstate_vars
type(waterstate_type), intent(inout) :: waterstate_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
+
+ type(clm_interface_th_datatype), intent(in) :: clm_idata_th
! !LOCAL VARIABLES:
integer :: fc, c, j, g, gcount ! indices
@@ -682,6 +766,8 @@ subroutine update_soil_moisture(clm_bgc_data, &
!EOP
!-----------------------------------------------------------------------
associate ( &
+ soilpsi_col => soilstate_vars%soilpsi_col , &
+ !
h2osoi_liq_col => waterstate_vars%h2osoi_liq_col , &
h2osoi_ice_col => waterstate_vars%h2osoi_ice_col , &
h2osoi_vol_col => waterstate_vars%h2osoi_vol_col &
@@ -689,20 +775,21 @@ subroutine update_soil_moisture(clm_bgc_data, &
do fc = 1,num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevsoi
- h2osoi_liq_col(c,:) = clm_bgc_data%h2osoi_liq_col(c,:)
- h2osoi_ice_col(c,:) = clm_bgc_data%h2osoi_ice_col(c,:)
- h2osoi_vol_col(c,:) = clm_bgc_data%h2osoi_vol_col(c,:)
-! end do
+
+ soilpsi_col(c,:) = clm_idata_th%soilpsi_col(c,:)
+
+ h2osoi_liq_col(c,:) = clm_idata_th%h2osoi_liq_col(c,:)
+ h2osoi_ice_col(c,:) = clm_idata_th%h2osoi_ice_col(c,:)
+ h2osoi_vol_col(c,:) = clm_idata_th%h2osoi_vol_col(c,:)
end do
end associate
end subroutine update_soil_moisture
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
- subroutine update_soil_temperature(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
+!--------------------------------------------------------------------------------------
+ subroutine update_soil_temperature(clm_idata_th, &
+ bounds, num_soilc, filter_soilc, &
temperature_vars)
!
@@ -718,7 +805,7 @@ subroutine update_soil_temperature(clm_bgc_data, &
integer , intent(in) :: num_soilc ! number of column soil points in column filter
integer , intent(in) :: filter_soilc(:) ! column filter for soil points
type(temperature_type) , intent(inout) :: temperature_vars
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_th_datatype) , intent(in) :: clm_idata_th
! !LOCAL VARIABLES:
integer :: fc, c, j, g, gcount ! indices
@@ -728,30 +815,67 @@ subroutine update_soil_temperature(clm_bgc_data, &
associate ( &
t_soisno => temperature_vars%t_soisno_col & ! snow-soil temperature (Kelvin)
)
+
do fc = 1,num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevsoi
- t_soisno(c,:) = clm_bgc_data%t_soisno_col(c,:)
-! end do
+ t_soisno(c,:) = clm_idata_th%t_soisno_col(c,:)
end do
end associate
end subroutine update_soil_temperature
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
+ subroutine update_th_data_pf2clm(clm_idata_th, &
+ bounds, num_soilc, filter_soilc, &
+ waterstate_vars, waterflux_vars, &
+ temperature_vars, energyflux_vars, &
+ soilstate_vars, soilhydrology_vars)
+
+ ! USES
+ use clm_varctl , only : use_pflotran, pf_tmode, pf_hmode
+
+ implicit none
+
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_soilc ! number of soil columns in filter
+ integer , intent(in) :: filter_soilc(:) ! filter for soil columns
+ type(waterstate_type) , intent(inout) :: waterstate_vars
+ type(waterflux_type) , intent(inout) :: waterflux_vars
+ type(temperature_type) , intent(inout) :: temperature_vars
+ type(soilstate_type) , intent(inout) :: soilstate_vars
+ type(soilhydrology_type) , intent(inout) :: soilhydrology_vars
+ type(energyflux_type) , intent(inout) :: energyflux_vars
+
+ type(clm_interface_th_datatype), intent(in) :: clm_idata_th
-!!--------------------------------------------------------------------------------------
- subroutine update_bgc_state_decomp(clm_bgc_data, &
+ !-----------------------------------------------------------------------
+
+ character(len=256) :: subname = "update_th_data_pf2clm"
+
+ if (pf_tmode) then
+ call update_soil_temperature(clm_idata_th, &
+ bounds, num_soilc, filter_soilc, &
+ temperature_vars)
+ end if
+
+ if (pf_hmode) then
+ call update_soil_moisture(clm_idata_th, &
+ bounds, num_soilc, filter_soilc, &
+ soilstate_vars, waterstate_vars)
+ end if
+
+ end subroutine update_th_data_pf2clm
+!--------------------------------------------------------------------------------------
+
+
+!--------------------------------------------------------------------------------------
+ subroutine update_bgc_state_decomp(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
carbonstate_vars, nitrogenstate_vars, &
phosphorusstate_vars &
)
-! use CNDecompCascadeConType, only : decomp_cascade_con
-! use clm_time_manager, only : get_step_size
-!#ifndef FLEXIBLE_POOLS
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-!#endif
-
implicit none
type(bounds_type) , intent(in) :: bounds
@@ -762,51 +886,41 @@ subroutine update_bgc_state_decomp(clm_bgc_data, &
type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype) , intent(in) :: clm_bgc_data
character(len=256) :: subname = "update_soil_bgc_state"
integer :: fc,c,j,k
-! integer :: gcount, cellcount
-! real(r8) :: wtgcell
-
-! real(r8) :: dtime ! land model time step (sec)
!------------------------------------------------------------------------------------
- !
- associate ( &
- decomp_cpools_vr => carbonstate_vars%decomp_cpools_vr_col , &
- decomp_npools_vr => nitrogenstate_vars%decomp_npools_vr_col , &
- decomp_ppools_vr => phosphorusstate_vars%decomp_ppools_vr_col &
- )
+ !
+ associate ( &
+ decomp_cpools_vr => carbonstate_vars%decomp_cpools_vr_col , &
+ decomp_npools_vr => nitrogenstate_vars%decomp_npools_vr_col , &
+ decomp_ppools_vr => phosphorusstate_vars%decomp_ppools_vr_col &
+ )
! ------------------------------------------------------------------------
-! dtime = get_step_size()
!
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
do k = 1, ndecomp_pools
decomp_cpools_vr(c,:,k) = clm_bgc_data%decomp_cpools_vr_col(c,:,k)
decomp_npools_vr(c,:,k) = clm_bgc_data%decomp_npools_vr_col(c,:,k)
decomp_ppools_vr(c,:,k) = clm_bgc_data%decomp_ppools_vr_col(c,:,k)
end do
-! end do
end do
end associate
end subroutine update_bgc_state_decomp
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_state_smin(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
nitrogenstate_vars, phosphorusstate_vars)
use CNDecompCascadeConType, only : decomp_cascade_con
use clm_time_manager, only : get_step_size
-!#ifndef FLEXIBLE_POOLS
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-!#endif
implicit none
@@ -817,15 +931,11 @@ subroutine update_bgc_state_smin(clm_bgc_data, &
type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype), intent(in) :: clm_bgc_data
character(len=256) :: subname = "update_bgc_state_smin"
integer :: fc,c,j
-! integer :: gcount, cellcount
-! real(r8) :: wtgcell
-!
-! real(r8) :: dtime ! land model time step (sec)
!------------------------------------------------------------------------------------
!
@@ -844,11 +954,9 @@ subroutine update_bgc_state_smin(clm_bgc_data, &
)
! ------------------------------------------------------------------------
-! dtime = get_step_size()
!
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
smin_no3_vr(c,:) = clm_bgc_data%smin_no3_vr_col(c,:)
smin_nh4_vr(c,:) = clm_bgc_data%smin_nh4_vr_col(c,:)
smin_nh4sorb_vr(c,:) = clm_bgc_data%smin_nh4sorb_vr_col(c,:)
@@ -860,25 +968,19 @@ subroutine update_bgc_state_smin(clm_bgc_data, &
sminp_vr(c,:) = clm_bgc_data%sminp_vr_col(c,:)
occlp_vr(c,:) = clm_bgc_data%occlp_vr_col(c,:)
primp_vr(c,:) = clm_bgc_data%primp_vr_col(c,:)
-! end do
end do
-!write(*,'(A30,12E14.6)')"DEBUG | clm UPDATE no3=",smin_no3_vr(1,1:nlevdecomp)
end associate
end subroutine update_bgc_state_smin
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_flux_decomp_sourcesink(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
- carbonflux_vars, nitrogenflux_vars, &
+ bounds, num_soilc, filter_soilc, &
+ carbonflux_vars, nitrogenflux_vars, &
phosphorusflux_vars)
use CNDecompCascadeConType, only : decomp_cascade_con
- use clm_time_manager, only : get_step_size
-!#ifndef FLEXIBLE_POOLS
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-!#endif
implicit none
@@ -890,7 +992,7 @@ subroutine update_bgc_flux_decomp_sourcesink(clm_bgc_data, &
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype), intent(in):: clm_bgc_data
integer :: fc, c, j, k
character(len=256) :: subname = "update_soil_bgc_pf2clm"
@@ -903,29 +1005,23 @@ subroutine update_bgc_flux_decomp_sourcesink(clm_bgc_data, &
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
do k = 1, ndecomp_pools
decomp_cpools_sourcesink_vr(c,:,k) = clm_bgc_data%decomp_cpools_sourcesink_col(c,:,k)
decomp_npools_sourcesink_vr(c,:,k) = clm_bgc_data%decomp_npools_sourcesink_col(c,:,k)
decomp_ppools_sourcesink_vr(c,:,k) = clm_bgc_data%decomp_ppools_sourcesink_col(c,:,k)
end do
-! end do
end do
end associate
end subroutine update_bgc_flux_decomp_sourcesink
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_flux_decomp_cascade(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
carbonflux_vars, nitrogenflux_vars, &
phosphorusflux_vars)
use CNDecompCascadeConType, only : decomp_cascade_con
- use clm_time_manager, only : get_step_size
-!#ifndef FLEXIBLE_POOLS
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-!#endif
implicit none
@@ -937,7 +1033,7 @@ subroutine update_bgc_flux_decomp_cascade(clm_bgc_data, &
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype), intent(in):: clm_bgc_data
integer :: fc, c, j, k
character(len=256) :: subname = "update_soil_bgc_pf2clm"
@@ -960,8 +1056,6 @@ subroutine update_bgc_flux_decomp_cascade(clm_bgc_data, &
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
-
phr_vr(c,:) = clm_bgc_data%phr_vr_col(c,:)
fphr(c,:) = clm_bgc_data%fphr_col(c,:)
@@ -975,24 +1069,17 @@ subroutine update_bgc_flux_decomp_cascade(clm_bgc_data, &
decomp_cascade_sminp_flux_vr_col(c,:,k) = clm_bgc_data%decomp_cascade_sminp_flux_vr_col(c,:,k)
sminn_to_denit_decomp_cascade_vr_col(c,:,k) = clm_bgc_data%sminn_to_denit_decomp_cascade_vr_col(c,:,k)
end do
-! end do
end do
end associate
end subroutine update_bgc_flux_decomp_cascade
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_flux_smin(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
cnstate_vars, &
nitrogenflux_vars, phosphorusflux_vars)
-! use CNDecompCascadeConType, only : decomp_cascade_con
-! use clm_time_manager, only : get_step_size
-!#ifndef FLEXIBLE_POOLS
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-!#endif
-
implicit none
type(bounds_type) , intent(in) :: bounds
@@ -1003,7 +1090,7 @@ subroutine update_bgc_flux_smin(clm_bgc_data, &
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype) , intent(in) :: clm_bgc_data
integer :: fc, c, j
character(len=256) :: subname = "update_bgc_flux_smin"
@@ -1033,6 +1120,9 @@ subroutine update_bgc_flux_smin(clm_bgc_data, &
sminn_to_denit_excess_vr => nitrogenflux_vars%sminn_to_denit_excess_vr_col , & ! Output: [real(r8) (:,:) ]
supplement_to_sminn_vr => nitrogenflux_vars%supplement_to_sminn_vr_col , & ! Output: [real(r8) (:,:) ]
+ no3_net_transport_vr => nitrogenflux_vars%no3_net_transport_vr_col , & ! Output: updated from PF, if coupled
+ nh4_net_transport_vr => nitrogenflux_vars%nh4_net_transport_vr_col , & ! Output: updated from PF, if coupled
+
potential_immob_p => phosphorusflux_vars%potential_immob_p_col , & ! Output: [real(r8) (:) ]
actual_immob_p => phosphorusflux_vars%actual_immob_p_col , & ! Output: [real(r8) (:) ]
sminp_to_plant => phosphorusflux_vars%sminp_to_plant_col , & ! Output: [real(r8) (:) ]
@@ -1046,7 +1136,7 @@ subroutine update_bgc_flux_smin(clm_bgc_data, &
net_pmin_vr => phosphorusflux_vars%net_pmin_vr_col & ! Output: [real(r8) (:,:) ]
)
- do fc = 1, num_soilc
+ do fc = 1, num_soilc
c = filter_soilc(fc)
fpg(c) = clm_bgc_data%fpg_col(c)
@@ -1062,49 +1152,44 @@ subroutine update_bgc_flux_smin(clm_bgc_data, &
actual_immob_p(c) = clm_bgc_data%actual_immob_p_col(c)
sminp_to_plant(c) = clm_bgc_data%sminp_to_plant_col(c)
-! do j = 1, nlevdecomp
- fpi_vr(c,:) = clm_bgc_data%fpi_vr_col(c,:)
- fpi_p_vr(c,:) = clm_bgc_data%fpi_p_vr_col(c,:)
+ fpi_vr(c,:) = clm_bgc_data%fpi_vr_col(c,:)
+ fpi_p_vr(c,:) = clm_bgc_data%fpi_p_vr_col(c,:)
- sminn_to_plant_vr(c,:) = clm_bgc_data%sminn_to_plant_vr_col(c,:)
- smin_no3_to_plant_vr(c,:) = clm_bgc_data%smin_no3_to_plant_vr_col(c,:)
- smin_nh4_to_plant_vr(c,:) = clm_bgc_data%smin_nh4_to_plant_vr_col(c,:)
+ sminn_to_plant_vr(c,:) = clm_bgc_data%sminn_to_plant_vr_col(c,:)
+ smin_no3_to_plant_vr(c,:) = clm_bgc_data%smin_no3_to_plant_vr_col(c,:)
+ smin_nh4_to_plant_vr(c,:) = clm_bgc_data%smin_nh4_to_plant_vr_col(c,:)
- potential_immob_vr(c,:) = clm_bgc_data%potential_immob_vr_col(c,:)
- actual_immob_vr(c,:) = clm_bgc_data%actual_immob_vr_col(c,:)
- actual_immob_no3_vr(c,:) = clm_bgc_data%actual_immob_no3_vr_col(c,:)
- actual_immob_nh4_vr(c,:) = clm_bgc_data%actual_immob_nh4_vr_col(c,:)
- gross_nmin_vr(c,:) = clm_bgc_data%gross_nmin_vr_col(c,:)
- net_nmin_vr(c,:) = clm_bgc_data%net_nmin_vr_col(c,:) !!NOT available in PF
+ potential_immob_vr(c,:) = clm_bgc_data%potential_immob_vr_col(c,:)
+ actual_immob_vr(c,:) = clm_bgc_data%actual_immob_vr_col(c,:)
+ actual_immob_no3_vr(c,:) = clm_bgc_data%actual_immob_no3_vr_col(c,:)
+ actual_immob_nh4_vr(c,:) = clm_bgc_data%actual_immob_nh4_vr_col(c,:)
+ gross_nmin_vr(c,:) = clm_bgc_data%gross_nmin_vr_col(c,:)
+ net_nmin_vr(c,:) = clm_bgc_data%net_nmin_vr_col(c,:)
- sminn_to_denit_excess_vr(c,:)=clm_bgc_data%sminn_to_denit_excess_vr_col(c,:)
- supplement_to_sminn_vr(c,:) = clm_bgc_data%supplement_to_sminn_vr_col(c,:)
+ sminn_to_denit_excess_vr(c,:)=clm_bgc_data%sminn_to_denit_excess_vr_col(c,:)
+ supplement_to_sminn_vr(c,:) = clm_bgc_data%supplement_to_sminn_vr_col(c,:)
- supplement_to_sminp_vr(c,:) = clm_bgc_data%supplement_to_sminp_vr_col(c,:)
+ no3_net_transport_vr(c,:) = clm_bgc_data%no3_net_transport_vr_col(c,:)
+ nh4_net_transport_vr(c,:) = clm_bgc_data%nh4_net_transport_vr_col(c,:)
- sminp_to_plant_vr(c,:) = clm_bgc_data%sminp_to_plant_vr_col(c,:)
- potential_immob_p_vr(c,:) = clm_bgc_data%potential_immob_p_vr_col(c,:)
- actual_immob_p_vr(c,:) = clm_bgc_data%actual_immob_p_vr_col(c,:)
- gross_pmin_vr(c,:) = clm_bgc_data%gross_pmin_vr_col(c,:)
- net_pmin_vr(c,:) = clm_bgc_data%net_pmin_vr_col(c,:) !!NOT available in PF
+ supplement_to_sminp_vr(c,:) = clm_bgc_data%supplement_to_sminp_vr_col(c,:)
-! end do
- end do
+ sminp_to_plant_vr(c,:) = clm_bgc_data%sminp_to_plant_vr_col(c,:)
+ potential_immob_p_vr(c,:) = clm_bgc_data%potential_immob_p_vr_col(c,:)
+ actual_immob_p_vr(c,:) = clm_bgc_data%actual_immob_p_vr_col(c,:)
+ gross_pmin_vr(c,:) = clm_bgc_data%gross_pmin_vr_col(c,:)
+ net_pmin_vr(c,:) = clm_bgc_data%net_pmin_vr_col(c,:) !NOT available in PF
+
+ end do
end associate
end subroutine update_bgc_flux_smin
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_flux_nitdenit(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
+ bounds, num_soilc, filter_soilc, &
nitrogenflux_vars, phosphorusflux_vars)
-! use CNDecompCascadeConType, only : decomp_cascade_con
-! use clm_time_manager, only : get_step_size
-!#ifndef FLEXIBLE_POOLS
-! use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-!#endif
-
implicit none
type(bounds_type) , intent(in) :: bounds
@@ -1113,7 +1198,7 @@ subroutine update_bgc_flux_nitdenit(clm_bgc_data, &
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype) , intent(in) :: clm_bgc_data
integer :: fc, c, j
character(len=256) :: subname = "update_bgc_flux_nitdenit"
@@ -1130,28 +1215,23 @@ subroutine update_bgc_flux_nitdenit(clm_bgc_data, &
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
-
- pot_f_nit_vr(c,:) = clm_bgc_data%pot_f_nit_vr_col(c,:)
- pot_f_denit_vr(c,:) = clm_bgc_data%pot_f_denit_vr_col(c,:)
- f_nit_vr(c,:) = clm_bgc_data%f_nit_vr_col(c,:)
- f_denit_vr(c,:) = clm_bgc_data%f_denit_vr_col(c,:)
- n2_n2o_ratio_denit_vr(c,:) = clm_bgc_data%n2_n2o_ratio_denit_vr_col(c,:)
- f_n2o_denit_vr(c,:) = clm_bgc_data%f_n2o_denit_vr_col(c,:)
- f_n2o_nit_vr(c,:) = clm_bgc_data%f_n2o_nit_vr_col(c,:)
-! end do
+ pot_f_nit_vr(c,:) = clm_bgc_data%pot_f_nit_vr_col(c,:)
+ pot_f_denit_vr(c,:) = clm_bgc_data%pot_f_denit_vr_col(c,:)
+ f_nit_vr(c,:) = clm_bgc_data%f_nit_vr_col(c,:)
+ f_denit_vr(c,:) = clm_bgc_data%f_denit_vr_col(c,:)
+ n2_n2o_ratio_denit_vr(c,:) = clm_bgc_data%n2_n2o_ratio_denit_vr_col(c,:)
+ f_n2o_denit_vr(c,:) = clm_bgc_data%f_n2o_denit_vr_col(c,:)
+ f_n2o_nit_vr(c,:) = clm_bgc_data%f_n2o_nit_vr_col(c,:)
end do
end associate
end subroutine update_bgc_flux_nitdenit
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_flux_gas_pf(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
+ bounds, num_soilc, filter_soilc, &
carbonflux_vars, nitrogenflux_vars)
-! use clm_time_manager, only : get_step_size, get_nstep
-
! PFLOTRAN gas fluxes
implicit none
@@ -1161,15 +1241,11 @@ subroutine update_bgc_flux_gas_pf(clm_bgc_data, &
type(carbonflux_type) , intent(inout) :: carbonflux_vars
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype) , intent(in) :: clm_bgc_data
!character(len=256) :: subname = "get_pf_bgc_gaslosses"
integer :: fc, c, g, j
-! integer :: gcount, cellcount
-! real(r8) :: dtime ! land model time step (sec)
-! integer :: nstep
-
!------------------------------------------------------------------------------------
associate ( &
@@ -1184,37 +1260,31 @@ subroutine update_bgc_flux_gas_pf(clm_bgc_data, &
! ------------------------------------------------------------------------
do fc = 1,num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
-!
- f_co2_soil_vr(c,:) = clm_bgc_data%f_co2_soil_vr_col(c,:)
- f_n2_soil_vr(c,:) = clm_bgc_data%f_n2_soil_vr_col(c,:)
- f_n2o_soil_vr(c,:) = clm_bgc_data%f_n2o_soil_vr_col(c,:)
-
- hr_vr(c,:) = clm_bgc_data%hr_vr_col(c,:)
- f_ngas_decomp_vr(c,:) = clm_bgc_data%f_ngas_decomp_vr_col(c,:)
- f_ngas_nitri_vr(c,:) = clm_bgc_data%f_ngas_nitri_vr_col(c,:)
- f_ngas_denit_vr(c,:) = clm_bgc_data%f_ngas_denit_vr_col(c,:)
-! enddo
+ f_co2_soil_vr(c,:) = clm_bgc_data%f_co2_soil_vr_col(c,:)
+ f_n2_soil_vr(c,:) = clm_bgc_data%f_n2_soil_vr_col(c,:)
+ f_n2o_soil_vr(c,:) = clm_bgc_data%f_n2o_soil_vr_col(c,:)
+
+ hr_vr(c,:) = clm_bgc_data%hr_vr_col(c,:)
+ f_ngas_decomp_vr(c,:) = clm_bgc_data%f_ngas_decomp_vr_col(c,:)
+ f_ngas_nitri_vr(c,:) = clm_bgc_data%f_ngas_nitri_vr_col(c,:)
+ f_ngas_denit_vr(c,:) = clm_bgc_data%f_ngas_denit_vr_col(c,:)
+
enddo ! do c = begc, endc
!
end associate
end subroutine update_bgc_flux_gas_pf
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, &
num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
- atm2lnd_vars, &
- waterstate_vars, waterflux_vars, &
- soilstate_vars, temperature_vars, energyflux_vars, &
- soilhydrology_vars, soil_water_retention_curve, &
cnstate_vars, carbonflux_vars, carbonstate_vars, &
nitrogenflux_vars, nitrogenstate_vars, &
phosphorusflux_vars, phosphorusstate_vars, &
ch4_vars)
- !! USES
- use clm_varctl , only : use_pflotran, pf_tmode, pf_hmode, pf_cmode
+ ! USES
+ use clm_varctl , only : use_pflotran, pf_cmode
implicit none
@@ -1224,13 +1294,6 @@ subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, &
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
integer , intent(in) :: num_soilp ! number of soil patches in filter
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
- type(atm2lnd_type) , intent(in) :: atm2lnd_vars
- type(waterstate_type) , intent(inout) :: waterstate_vars
- type(waterflux_type) , intent(inout) :: waterflux_vars
- type(soilstate_type) , intent(inout) :: soilstate_vars
- type(temperature_type) , intent(inout) :: temperature_vars
- type(soilhydrology_type) , intent(inout) :: soilhydrology_vars
- type(energyflux_type) , intent(inout) :: energyflux_vars
type(cnstate_type) , intent(inout) :: cnstate_vars
type(carbonflux_type) , intent(inout) :: carbonflux_vars
@@ -1241,17 +1304,16 @@ subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, &
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
type(ch4_type) , intent(inout) :: ch4_vars
- class(soil_water_retention_curve_type) , intent(in) :: soil_water_retention_curve
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype), intent(in):: clm_bgc_data
!-----------------------------------------------------------------------
- character(len=256) :: subname = "get_clm_bgc_data"
+ character(len=256) :: subname = "update_bgc_data_pf2clm"
if (pf_cmode) then
- !! bgc_state_decomp is updated in CLM
- !! by passing bgc_flux_decomp_sourcesink into CNSoilLittVertTransp
+ ! bgc_state_decomp is updated in CLM
+ ! by passing bgc_flux_decomp_sourcesink into CNSoilLittVertTransp
call update_bgc_flux_decomp_sourcesink(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
carbonflux_vars, nitrogenflux_vars, &
@@ -1272,29 +1334,16 @@ subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, &
end if
- if (pf_tmode) then
- call update_soil_temperature(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
- temperature_vars)
- end if
-
- if (pf_hmode) then
- call update_soil_moisture(clm_bgc_data, &
- bounds, num_soilc, filter_soilc, &
- waterstate_vars)
- end if
-
end subroutine update_bgc_data_pf2clm
-!!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
! BEG of CLM-bgc through interface
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
! !INTERFACE:
- subroutine clm_bgc_run(clm_bgc_data, bounds, &
+ subroutine clm_bgc_run(clm_interface_data, bounds, &
num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
canopystate_vars, soilstate_vars, &
@@ -1304,16 +1353,15 @@ subroutine clm_bgc_run(clm_bgc_data, bounds, &
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !! USES:
+ ! USES:
use CNDecompMod , only: CNDecompAlloc
- !! ARGUMENTS:
+ ! ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilc ! number of soil columns in filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
integer , intent(in) :: num_soilp ! number of soil patches in filter
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
-! type(photosyns_type) , intent(in) :: photosyns_vars
type(canopystate_type) , intent(inout) :: canopystate_vars
type(soilstate_type) , intent(inout) :: soilstate_vars
type(temperature_type) , intent(inout) :: temperature_vars
@@ -1322,19 +1370,16 @@ subroutine clm_bgc_run(clm_bgc_data, bounds, &
type(ch4_type) , intent(inout) :: ch4_vars
type(carbonstate_type) , intent(inout) :: carbonstate_vars
type(carbonflux_type) , intent(inout) :: carbonflux_vars
-! type(carbonflux_type) , intent(inout) :: c13_carbonflux_vars
-! type(carbonflux_type) , intent(inout) :: c14_carbonflux_vars
type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
-! type(crop_type) , intent(inout) :: crop_vars
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type) , intent(inout) :: clm_bgc_data
+ type(clm_interface_data_type) , intent(inout) :: clm_interface_data
- !!-------------------------------------------------------------
- !! STEP-2: (i) pass data from clm_bgc_data to CNDecompAlloc
- call clm_bgc_get_data(clm_bgc_data, bounds, &
+ !-------------------------------------------------------------
+ ! STEP-2: (i) pass data from clm_bgc_data to CNDecompAlloc
+ call clm_bgc_get_data(clm_interface_data, bounds, &
num_soilc, filter_soilc, &
canopystate_vars, soilstate_vars, &
temperature_vars, waterstate_vars, &
@@ -1343,7 +1388,7 @@ subroutine clm_bgc_run(clm_bgc_data, bounds, &
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !! STEP-2: (ii) run CNDecompAlloc
+ ! STEP-2: (ii) run CNDecompAlloc
call CNDecompAlloc (bounds, num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
canopystate_vars, soilstate_vars, &
@@ -1353,20 +1398,20 @@ subroutine clm_bgc_run(clm_bgc_data, bounds, &
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !! STEP-2: (iii) update clm_bgc_data from CNDecompAlloc
- call clm_bgc_update_data(clm_bgc_data, bounds, &
- num_soilc, filter_soilc, &
- cnstate_vars, carbonflux_vars, &
+ ! STEP-2: (iii) update clm_bgc_data from CNDecompAlloc
+ call clm_bgc_update_data(clm_interface_data%bgc, bounds, &
+ num_soilc, filter_soilc, &
+ cnstate_vars, carbonflux_vars, &
nitrogenflux_vars, phosphorusflux_vars)
end subroutine clm_bgc_run
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
! !INTERFACE:
- !! pass data from clm_bgc_data to clm original data-types that used by CNDecompAlloc
- subroutine clm_bgc_get_data(clm_bgc_data, bounds, &
- num_soilc, filter_soilc, &
+ ! pass data from clm_bgc_data to clm original data-types that used by CNDecompAlloc
+ subroutine clm_bgc_get_data(clm_interface_data, &
+ bounds, num_soilc, filter_soilc, &
canopystate_vars, soilstate_vars, &
temperature_vars, waterstate_vars, &
cnstate_vars, ch4_vars, &
@@ -1374,16 +1419,13 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, &
nitrogenstate_vars, nitrogenflux_vars, &
phosphorusstate_vars,phosphorusflux_vars)
- !! USES:
+ ! USES:
- !! ARGUMENTS:
+ ! ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilc ! number of soil columns in filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
-! integer , intent(in) :: num_soilp ! number of soil patches in filter
-! integer , intent(in) :: filter_soilp(:) ! filter for soil patches
-! type(photosyns_type) , intent(in) :: photosyns_vars
type(canopystate_type) , intent(inout) :: canopystate_vars
type(soilstate_type) , intent(inout) :: soilstate_vars
type(temperature_type) , intent(inout) :: temperature_vars
@@ -1392,23 +1434,18 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, &
type(ch4_type) , intent(inout) :: ch4_vars
type(carbonstate_type) , intent(inout) :: carbonstate_vars
type(carbonflux_type) , intent(inout) :: carbonflux_vars
-! type(carbonflux_type) , intent(inout) :: c13_carbonflux_vars
-! type(carbonflux_type) , intent(inout) :: c14_carbonflux_vars
type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
-! type(crop_type) , intent(in) :: crop_vars
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
type(phosphorusflux_type) , intent(inout) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
- !! LOCAL VARIABLES:
+ ! LOCAL VARIABLES:
integer :: fc, c, j, k
!-----------------------------------------------------------------------
associate(&
-! initial_cn_ratio => decomp_cascade_con%initial_cn_ratio , & ! Input: [real(r8) (:) ] c:n ratio for initialization of pools
-! initial_cp_ratio => decomp_cascade_con%initial_cp_ratio , & ! Input: [real(r8) (:) ] c:p ratio for initialization of pools
decomp_cpools_vr => carbonstate_vars%decomp_cpools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
decomp_npools_vr => nitrogenstate_vars%decomp_npools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
decomp_ppools_vr => phosphorusstate_vars%decomp_ppools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) P pools
@@ -1423,12 +1460,12 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, &
sminp_vr => phosphorusstate_vars%sminp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil mineral P = solutionp + labilep + secondp
occlp_vr => phosphorusstate_vars%occlp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil occluded mineral P
primp_vr => phosphorusstate_vars%primp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil primary mineral P
-
+ !
plant_ndemand_col => nitrogenflux_vars%plant_ndemand_col , &
plant_pdemand_col => phosphorusflux_vars%plant_pdemand_col , &
-
- alt_indx => canopystate_vars%alt_indx_col , & ! Input: [integer (:) ] current depth of thaw
-
+ !
+ !alt_indx => canopystate_vars%alt_indx_col , & ! Input: [integer (:) ] current depth of thaw
+ !
watsat => soilstate_vars%watsat_col , & ! Input: [real(r8) (:,:) ] volumetric soil water at saturation (porosity) (nlevgrnd)
bd => soilstate_vars%bd_col , & ! Input: [real(r8) (:,:) ] bulk density of dry soil material [kg/m3]
watfc => soilstate_vars%watfc_col , & ! Input: [real(r8) (:,:) ] volumetric soil water at field capacity (nlevsoi)
@@ -1450,97 +1487,88 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, &
o2stress_sat => ch4_vars%o2stress_sat_col , & ! Input: [real(r8) (:,:) ] Ratio of oxygen available to that demanded by roots, aerobes, & methanotrophs (nlevsoi)
finundated => ch4_vars%finundated_col & ! Input: [real(r8) (:) ] fractional inundated area (excluding dedicated wetland columns)
- )
+ )
- !! soil properties & thermohydrology
+ ! soil properties & thermohydrology
do fc = 1, num_soilc
c = filter_soilc(fc)
- plant_ndemand_col(c) = clm_bgc_data%plant_ndemand_col(c)
- plant_pdemand_col(c) = clm_bgc_data%plant_pdemand_col(c)
+ plant_ndemand_col(c) = clm_interface_data%bgc%plant_ndemand_col(c)
+ plant_pdemand_col(c) = clm_interface_data%bgc%plant_pdemand_col(c)
- alt_indx(c) = clm_bgc_data%alt_indx_col(c)
- finundated(c) = clm_bgc_data%finundated_col(c)
+ finundated(c) = clm_interface_data%bgc%finundated_col(c)
-! do j = 1,nlevsoi
- bd(c,:) = clm_bgc_data%bd_col(c,:)
- watsat(c,:) = clm_bgc_data%watsat_col(c,:)
- bsw(c,:) = clm_bgc_data%bsw_col(c,:)
- sucsat(c,:) = clm_bgc_data%sucsat_col(c,:)
- watfc(c,:) = clm_bgc_data%watfc_col(c,:)
- cellorg(c,:) = clm_bgc_data%cellorg_col(c,:)
+ bd(c,:) = clm_interface_data%bd_col(c,:)
+ watsat(c,:) = clm_interface_data%watsat_col(c,:)
+ bsw(c,:) = clm_interface_data%bsw_col(c,:)
+ sucsat(c,:) = clm_interface_data%sucsat_col(c,:)
+ watfc(c,:) = clm_interface_data%watfc_col(c,:)
+ cellorg(c,:) = clm_interface_data%cellorg_col(c,:)
- soilpsi(c,:) = clm_bgc_data%soilpsi_col(c,:)
- h2osoi_vol(c,:) = clm_bgc_data%h2osoi_vol_col(c,:)
- h2osoi_liq(c,:) = clm_bgc_data%h2osoi_liq_col(c,:)
+ soilpsi(c,:) = clm_interface_data%th%soilpsi_col(c,:)
+ h2osoi_vol(c,:) = clm_interface_data%th%h2osoi_vol_col(c,:)
+ h2osoi_liq(c,:) = clm_interface_data%th%h2osoi_liq_col(c,:)
- t_soisno(c,:) = clm_bgc_data%t_soisno_col(c,:)
+ t_soisno(c,:) = clm_interface_data%th%t_soisno_col(c,:)
- o2stress_unsat(c,:) = clm_bgc_data%o2stress_unsat_col(c,:)
- o2stress_sat(c,:) = clm_bgc_data%o2stress_sat_col(c,:)
- o2_decomp_depth_unsat(c,:) = clm_bgc_data%o2_decomp_depth_unsat_col(c,:)
- conc_o2_unsat(c,:) = clm_bgc_data%conc_o2_unsat_col(c,:)
- o2_decomp_depth_sat(c,:) = clm_bgc_data%o2_decomp_depth_sat_col(c,:)
- conc_o2_sat(c,:) = clm_bgc_data%conc_o2_sat_col(c,:)
+ o2stress_unsat(c,:) = clm_interface_data%bgc%o2stress_unsat_col(c,:)
+ o2stress_sat(c,:) = clm_interface_data%bgc%o2stress_sat_col(c,:)
+ o2_decomp_depth_unsat(c,:) = clm_interface_data%bgc%o2_decomp_depth_unsat_col(c,:)
+ conc_o2_unsat(c,:) = clm_interface_data%bgc%conc_o2_unsat_col(c,:)
+ o2_decomp_depth_sat(c,:) = clm_interface_data%bgc%o2_decomp_depth_sat_col(c,:)
+ conc_o2_sat(c,:) = clm_interface_data%bgc%conc_o2_sat_col(c,:)
-! end do
end do
- !!state variables
+ !state variables
do fc = 1, num_soilc
c = filter_soilc(fc)
-! do j = 1, nlevdecomp
do k = 1, ndecomp_pools
- decomp_cpools_vr(c,:,k) = clm_bgc_data%decomp_cpools_vr_col(c,:,k)
- decomp_npools_vr(c,:,k) = clm_bgc_data%decomp_npools_vr_col(c,:,k)
- decomp_ppools_vr(c,:,k) = clm_bgc_data%decomp_ppools_vr_col(c,:,k)
+ decomp_cpools_vr(c,:,k) = clm_interface_data%bgc%decomp_cpools_vr_col(c,:,k)
+ decomp_npools_vr(c,:,k) = clm_interface_data%bgc%decomp_npools_vr_col(c,:,k)
+ decomp_ppools_vr(c,:,k) = clm_interface_data%bgc%decomp_ppools_vr_col(c,:,k)
end do
- smin_no3_vr(c,:) = clm_bgc_data%smin_no3_vr_col(c,:)
- smin_nh4_vr(c,:) = clm_bgc_data%smin_nh4_vr_col(c,:)
- smin_nh4sorb_vr(c,:) = clm_bgc_data%smin_nh4sorb_vr_col(c,:)
+ smin_no3_vr(c,:) = clm_interface_data%bgc%smin_no3_vr_col(c,:)
+ smin_nh4_vr(c,:) = clm_interface_data%bgc%smin_nh4_vr_col(c,:)
+ smin_nh4sorb_vr(c,:) = clm_interface_data%bgc%smin_nh4sorb_vr_col(c,:)
- solutionp_vr(c,:) = clm_bgc_data%solutionp_vr_col(c,:)
- labilep_vr(c,:) = clm_bgc_data%labilep_vr_col(c,:)
- secondp_vr(c,:) = clm_bgc_data%secondp_vr_col(c,:)
- sminp_vr(c,:) = clm_bgc_data%sminp_vr_col(c,:)
- occlp_vr(c,:) = clm_bgc_data%occlp_vr_col(c,:)
- primp_vr(c,:) = clm_bgc_data%primp_vr_col(c,:)
-! end do
+ solutionp_vr(c,:) = clm_interface_data%bgc%solutionp_vr_col(c,:)
+ labilep_vr(c,:) = clm_interface_data%bgc%labilep_vr_col(c,:)
+ secondp_vr(c,:) = clm_interface_data%bgc%secondp_vr_col(c,:)
+ sminp_vr(c,:) = clm_interface_data%bgc%sminp_vr_col(c,:)
+ occlp_vr(c,:) = clm_interface_data%bgc%occlp_vr_col(c,:)
+ primp_vr(c,:) = clm_interface_data%bgc%primp_vr_col(c,:)
end do
end associate
end subroutine clm_bgc_get_data
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
! !INTERFACE:
- !! pass data from clm_bgc to clm_bgc_data
+ ! pass data from clm_bgc to clm_bgc_data
subroutine clm_bgc_update_data(clm_bgc_data, bounds, &
num_soilc, filter_soilc, &
cnstate_vars, carbonflux_vars, &
nitrogenflux_vars, phosphorusflux_vars)
- !! USES:
+ ! USES:
- !! ARGUMENTS:
+ ! ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilc ! number of soil columns in filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
-! integer , intent(in) :: num_soilp ! number of soil patches in filter
-! integer , intent(in) :: filter_soilp(:) ! filter for soil patches
type(cnstate_type) , intent(in) :: cnstate_vars
type(carbonflux_type) , intent(in) :: carbonflux_vars
-! type(carbonflux_type) , intent(in) :: c13_carbonflux_vars
-! type(carbonflux_type) , intent(in) :: c14_carbonflux_vars
type(nitrogenflux_type) , intent(in) :: nitrogenflux_vars
type(phosphorusflux_type) , intent(in) :: phosphorusflux_vars
- type(clm_bgc_interface_data_type) , intent(inout) :: clm_bgc_data
+ type(clm_interface_bgc_datatype) , intent(inout) :: clm_bgc_data
- !! LOCAL VARIABLES:
+ ! LOCAL VARIABLES:
integer :: fc, c, j, k
!-----------------------------------------------------------------------
@@ -1587,7 +1615,8 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, &
net_nmin_vr => nitrogenflux_vars%net_nmin_vr_col , & ! Output: [real(r8) (:,:) ]
gross_nmin => nitrogenflux_vars%gross_nmin_col , & ! Output: [real(r8) (:) ] gross rate of N mineralization (gN/m2/s)
net_nmin => nitrogenflux_vars%net_nmin_col , & ! Output: [real(r8) (:) ] net rate of N mineralization (gN/m2/s)
- !!! add phosphorus
+
+ ! add phosphorus
decomp_cascade_ptransfer_vr => phosphorusflux_vars%decomp_cascade_ptransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vert-res transfer of P from donor to receiver pool along decomp. cascade (gP/m3/s)
decomp_cascade_sminp_flux_vr => phosphorusflux_vars%decomp_cascade_sminp_flux_vr_col , & ! Output: [real(r8) (:,:,:) ] vert-res mineral P flux for transition along decomposition cascade (gP/m3/s)
potential_immob_p_vr => phosphorusflux_vars%potential_immob_p_vr_col , & ! Output: [real(r8) (:,:) ]
@@ -1598,7 +1627,6 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, &
decomp_cascade_hr_vr => carbonflux_vars%decomp_cascade_hr_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
decomp_cascade_ctransfer_vr => carbonflux_vars%decomp_cascade_ctransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
-! decomp_k => carbonflux_vars%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
phr_vr => carbonflux_vars%phr_vr_col , & ! Output: [real(r8) (:,:) ] potential HR (gC/m3/s)
fphr => carbonflux_vars%fphr_col & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
)
@@ -1644,7 +1672,7 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, &
clm_bgc_data%gross_nmin_vr_col = gross_nmin_vr
clm_bgc_data%net_nmin_vr_col = net_nmin_vr
- !! phosphorus
+ ! phosphorus
clm_bgc_data%decomp_cascade_ptransfer_vr_col = decomp_cascade_ptransfer_vr
clm_bgc_data%decomp_cascade_sminp_flux_vr_col = decomp_cascade_sminp_flux_vr
clm_bgc_data%potential_immob_p_vr_col = potential_immob_p_vr
@@ -1660,21 +1688,17 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, &
end associate
end subroutine clm_bgc_update_data
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
subroutine update_bgc_data_clm2clm(clm_bgc_data,bounds, &
num_soilc, filter_soilc, &
num_soilp, filter_soilp, &
- atm2lnd_vars, &
- waterstate_vars, waterflux_vars, &
- soilstate_vars, temperature_vars, energyflux_vars, &
- soilhydrology_vars, soil_water_retention_curve, &
cnstate_vars, carbonflux_vars, carbonstate_vars, &
nitrogenflux_vars, nitrogenstate_vars, &
phosphorusflux_vars, phosphorusstate_vars, &
ch4_vars)
- !! USES
+ ! USES
implicit none
@@ -1685,13 +1709,6 @@ subroutine update_bgc_data_clm2clm(clm_bgc_data,bounds, &
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
integer , intent(in) :: num_soilp ! number of soil patches in filter
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
- type(atm2lnd_type) , intent(in) :: atm2lnd_vars
- type(waterstate_type) , intent(inout) :: waterstate_vars
- type(waterflux_type) , intent(inout) :: waterflux_vars
- type(soilstate_type) , intent(inout) :: soilstate_vars
- type(temperature_type) , intent(inout) :: temperature_vars
- type(soilhydrology_type) , intent(inout) :: soilhydrology_vars
- type(energyflux_type) , intent(inout) :: energyflux_vars
type(cnstate_type) , intent(inout) :: cnstate_vars
type(carbonflux_type) , intent(inout) :: carbonflux_vars
@@ -1702,15 +1719,14 @@ subroutine update_bgc_data_clm2clm(clm_bgc_data,bounds, &
type(phosphorusstate_type) , intent(inout) :: phosphorusstate_vars
type(ch4_type) , intent(inout) :: ch4_vars
- class(soil_water_retention_curve_type) , intent(in) :: soil_water_retention_curve
- type(clm_bgc_interface_data_type) , intent(in) :: clm_bgc_data
+ type(clm_interface_bgc_datatype), intent(in):: clm_bgc_data
!-----------------------------------------------------------------------
- character(len=256) :: subname = "get_clm_bgc_data"
+ character(len=256) :: subname = "update_bgc_data_clm2clm"
- !! bgc_state_decomp is updated in CLM
- !! by passing bgc_flux_decomp_sourcesink into CNSoilLittVertTransp
+ ! bgc_state_decomp is updated in CLM
+ ! by passing bgc_flux_decomp_sourcesink into CNSoilLittVertTransp
call update_bgc_flux_decomp_cascade(clm_bgc_data, &
bounds, num_soilc, filter_soilc, &
carbonflux_vars, nitrogenflux_vars, &
@@ -1726,9 +1742,10 @@ subroutine update_bgc_data_clm2clm(clm_bgc_data,bounds, &
nitrogenflux_vars, phosphorusflux_vars)
end subroutine update_bgc_data_clm2clm
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
! END of CLM-bgc through interface
-!!--------------------------------------------------------------------------------------
+!--------------------------------------------------------------------------------------
+
-end module clm_bgc_interfaceMod
+end module clm_interface_funcsMod
diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90
new file mode 100644
index 000000000000..59a81f449880
--- /dev/null
+++ b/components/clm/src/main/clm_interface_pflotranMod.F90
@@ -0,0 +1,4893 @@
+module clm_interface_pflotranMod
+
+!#define CLM_PFLOTRAN
+! the above #directive IS for explicit coupling CLM and PFLOTRAN (i.e. this interface)
+
+!#define COLUMN_MODE
+! the above #define IS for column-wised 1D grid CLM-PF coupling (i.e. 'VERTICAL_ONLY_FLOW/TRAN').
+! (1) active columns ('filter(:)%soilc', i.e. only including both 'istsoil' and 'istcrop');
+! (2) 'soilc' are arranged arbitrarily by 'clumps', following by orders in 'soilc', along X-direction;
+! (3) The order/sequence in (2) are forced passing to over-ride PF's fakely reading input cards.
+! (4) MUST with pflotran%option%flow%only_vertical_flow and %option%tran%only_vertical_transport TRUE.
+! (5) Since PF fake mesh will be over-rided, mapping_files are NOT needed.
+
+!----------------------------------------------------------------------------------------------
+! NGEE-Arctic CLM-PFLOTRAN soil Thermal-Hydrology & bgC coupling interface
+! authors: Fengming YUAN1, Gautam Bishit1,2, and Guoping Tang1
+!
+! 1.Climate Change Science Institute & Environmental Science Division
+! Oak Ridge National Laboratory
+!
+! 2.Lawrence Berkley National Laboratory
+!
+! date: 2012 - 2017
+!
+! modified by Gangsheng Wang @ ORNL based on clm_interface: 8/28/2015, 2/2/2017
+!
+! yfm: Added Thermal-Hydrology coupling subroutines: 04/2017
+!----------------------------------------------------------------------------------------------
+
+#include "shr_assert.h"
+
+ !-----------------------------------------------------------------------
+ !BOP
+ !
+ ! !MODULE: clm_pflotran_interfaceMod
+ !
+ ! !DESCRIPTION:
+ ! Performs
+ !
+ ! !USES:
+ ! Most 'USES' are declaired in each subroutine
+ ! use shr_const_mod, only : SHR_CONST_G
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use decompMod , only : bounds_type
+ use filterMod , only : clumpfilter
+ use abortutils , only : endrun
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+
+ ! currently only works with soil columns, i.e. luntype of 'istsoil/istcrop'
+ ! use landunit_varcon , only : istsoil, istcrop
+
+ ! (dummy) variable definitions
+ ! ALM types/variables are replaced by clm_interface_data
+ use clm_interface_dataType, only : clm_interface_data_type
+
+
+#ifdef CLM_PFLOTRAN
+ use clm_pflotran_interface_data
+ use pflotran_clm_main_module
+ use pflotran_clm_setmapping_module
+#endif
+
+ ! !PUBLIC TYPES:
+ implicit none
+
+ save
+
+ private ! By default everything is private
+
+#ifdef CLM_PFLOTRAN
+ type(pflotran_model_type), pointer, public :: pflotran_m
+
+ logical, pointer, public :: mapped_gcount_skip(:) ! dim: inactive grid mask in (1:bounds%endg-bounds%begg+1),
+ ! or inactive column in (1:bounds%endc-bounds%endc+1)
+#endif
+ !
+ character(len=256), private:: pflotran_prefix = ''
+ character(len=32), private :: restart_stamp = ''
+
+ real(r8), parameter :: rgas = 8.3144621d0 ! m3 Pa K-1 mol-1
+
+ ! !PUBLIC MEMBER FUNCTIONS:
+ public :: clm_pf_readnl
+
+ ! wrappers around '#ifdef CLM_PFLOTRAN .... #endif' block statements to maintain sane runtime behavior
+ ! when pflotran is not available.
+ public :: clm_pf_interface_init
+ public :: clm_pf_set_restart_stamp
+ public :: clm_pf_run
+ public :: clm_pf_write_restart
+ public :: clm_pf_finalize
+
+ private :: pflotran_not_available
+
+#ifdef CLM_PFLOTRAN
+ ! private work functions that truely require '#ifdef CLM_PFLOTRAN .... #endif'
+ !
+ private :: interface_init
+ private :: pflotran_run_onestep
+ private :: pflotran_write_checkpoint
+ private :: pflotran_finalize
+ private :: clm_pf_checkerr
+ !
+ private :: get_clm_soil_dimension
+ private :: get_clm_soil_properties
+ !
+ private :: get_clm_soil_th
+ private :: get_clm_iceadj_porosity
+ !
+ private :: get_clm_bgc_conc
+ private :: get_clm_bgc_rate
+ private :: update_soil_bgc_pf2clm
+ private :: update_bgc_gaslosses_pf2clm
+ ! pflotran mass balance check
+ private :: clm_pf_BeginCBalance
+ private :: clm_pf_BeginNBalance
+ private :: clm_pf_CBalanceCheck
+ private :: clm_pf_NBalanceCheck
+ !
+ private :: get_clm_bcwflx
+ private :: get_clm_bceflx
+ private :: update_soil_temperature_pf2clm
+ private :: update_soil_moisture_pf2clm
+ private :: update_bcflow_pf2clm
+
+#endif
+
+contains
+
+!-----------------------------------------------------------------------
+!
+! public interface functions allowing runtime behavior regardless of
+! whether pflotran is compiled in.
+!
+!-----------------------------------------------------------------------
+
+ !-----------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: clm_pf_readnl
+ !
+ ! !INTERFACE:
+ subroutine clm_pf_readnl( NLFilename )
+ !
+ ! !DESCRIPTION:
+ ! Read namelist for clm-pflotran interface
+ !
+ ! !USES:
+ use clm_varctl , only : iulog
+ use spmdMod , only : masterproc, mpicom
+ use fileutils , only : getavu, relavu, opnfil
+ use clm_nlUtilsMod, only : find_nlgroup_name
+ use shr_nl_mod , only : shr_nl_find_group_name
+ use shr_mpi_mod , only : shr_mpi_bcast
+
+ implicit none
+
+ ! !ARGUMENTS:
+ character(len=*), intent(IN) :: NLFilename ! Namelist filename
+ ! !LOCAL VARIABLES:
+ integer :: ierr ! error code
+ integer :: unitn ! unit for namelist file
+ character(len=32) :: subname = 'clm_pf_readnl' ! subroutine name
+ !EOP
+ !-----------------------------------------------------------------------
+ namelist / clm_pflotran_inparm / pflotran_prefix
+
+ ! ----------------------------------------------------------------------
+ ! Read namelist from standard namelist file.
+ ! ----------------------------------------------------------------------
+
+ if ( masterproc )then
+
+ unitn = getavu()
+ write(iulog,*) 'Read in clm-pflotran namelist'
+ call opnfil (NLFilename, unitn, 'F')
+ call shr_nl_find_group_name(unitn, 'clm_pflotran_inparm', status=ierr)
+ if (ierr == 0) then
+ read(unitn, clm_pflotran_inparm, iostat=ierr)
+ if (ierr /= 0) then
+ call endrun(msg=subname //':: ERROR: reading clm_pflotran_inparm namelist.'//&
+ errMsg(__FILE__, __LINE__))
+ end if
+ end if
+ call relavu( unitn )
+ write(iulog, '(/, A)') " clm-pflotran namelist:"
+ write(iulog, '(A, " : ", A,/)') " pflotran_prefix", trim(pflotran_prefix)
+ end if
+
+ ! Broadcast namelist variables read in
+ call shr_mpi_bcast(pflotran_prefix, mpicom)
+
+ end subroutine clm_pf_readnl
+
+ !-----------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: clm_pf_set_restart_stamp
+ !
+ ! !INTERFACE:
+ subroutine clm_pf_set_restart_stamp(clm_restart_filename)
+ !
+ ! !DESCRIPTION: Set the pflotran restart date stamp. Note we do NOT
+ ! restart here, that gets handled by pflotran's internal
+ ! initialization during interface_init_clm_pf()
+ !
+ ! !USES:
+ ! !ARGUMENTS:
+ character(len=256), intent(in) :: clm_restart_filename
+ ! !LOCAL VARIABLES:
+ integer :: name_length, start_pos, end_pos
+ character(len=32) :: clm_stamp
+ !EOP
+ !-----------------------------------------------------------------------
+
+ ! clm restart file name is of the form:
+ ! ${CASE_NAME}.clm2.r.YYYY-MM-DD-SSSSS.nc
+ ! we need to extract the: YYYY-MM-DD-SSSSS
+ write(*, '("clm-pf : clm restart file name : ", A/)') trim(clm_restart_filename)
+ name_length = len(trim(clm_restart_filename))
+ start_pos = name_length - 18
+ end_pos = name_length - 3
+ clm_stamp = clm_restart_filename(start_pos : end_pos)
+ write(*, '("clm-pf : clm date stamp : ", A/)') trim(clm_stamp)
+ restart_stamp = clm_stamp
+
+ end subroutine clm_pf_set_restart_stamp
+
+
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: pflotran_not_available
+ !
+ ! !INTERFACE:
+ subroutine pflotran_not_available(subname)
+ !
+ ! !DESCRIPTION:
+ ! Print an error message and abort.
+ !
+ ! !USES:
+
+ ! !ARGUMENTS:
+ implicit none
+ character(len=*), intent(in) :: subname
+ ! !LOCAL VARIABLES:
+ !EOP
+ !-----------------------------------------------------------------------
+ call endrun(trim(subname) // ": ERROR: CLM-PFLOTRAN interface has not been compiled " // &
+ "into this version of ALM.")
+ end subroutine pflotran_not_available
+
+
+!******************************************************************************************!
+!
+! public interface function wrappers
+!
+!------------------------------------------------------------------------------------------!
+
+ !-----------------------------------------------------------------------------
+ subroutine clm_pf_interface_init(bounds)
+
+ implicit none
+
+ type(bounds_type), intent(in) :: bounds ! bounds
+
+ character(len=256) :: subname = "clm_pf_interface_init()"
+
+#ifdef CLM_PFLOTRAN
+ call interface_init(bounds)
+#else
+ call pflotran_not_available(subname)
+#endif
+ end subroutine clm_pf_interface_init
+
+ !--------------------------------------------------------------------------------------------
+
+ subroutine clm_pf_run(clm_interface_data, bounds, filters, ifilter)
+ use clm_time_manager, only : get_nstep
+
+ implicit none
+
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(inout) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ !-----------------------------------------------------------------------
+
+ character(len=256) :: subname = "clm_pf_run"
+ integer :: nstep
+
+#ifdef CLM_PFLOTRAN
+ call clm_pf_BeginCBalance(clm_interface_data, bounds, filters, ifilter)
+ call clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter)
+
+ call pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter)
+
+ nstep = get_nstep()
+
+ if (nstep > 1 )then
+ call clm_pf_CBalanceCheck(clm_interface_data, bounds, filters, ifilter)
+ call clm_pf_NBalanceCheck(clm_interface_data, bounds, filters, ifilter)
+ end if
+#else
+ call pflotran_not_available(subname)
+#endif
+ end subroutine clm_pf_run
+
+ !-----------------------------------------------------------------------------
+ subroutine clm_pf_write_restart(date_stamp)
+
+ implicit none
+ character(len=*), intent(in) :: date_stamp
+
+ character(len=32) :: subname = "clm_pf_write_restart"
+
+#ifdef CLM_PFLOTRAN
+ call pflotran_write_checkpoint(date_stamp)
+#else
+ call pflotran_not_available(subname)
+#endif
+ end subroutine clm_pf_write_restart
+
+
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !ROUTINE: clm_pf_finalize
+ !
+ ! !INTERFACE:
+ subroutine clm_pf_finalize()
+
+ implicit none
+ character(len=256) :: subname = "clm_pf_finalize"
+
+#ifdef CLM_PFLOTRAN
+ call pflotran_finalize()
+#else
+ call pflotran_not_available(subname)
+#endif
+ end subroutine clm_pf_finalize
+
+
+
+
+
+!************************************************************************************!
+! (BEGIN)
+! Private interface subroutines, requiring explicit coupling between CLM and PFLOTRAN
+!
+#ifdef CLM_PFLOTRAN
+
+ !====================================================================================================
+ ! !
+ ! Main Subroutines to Couple with PFLOTRAN !
+ ! !
+ !====================================================================================================
+
+ !-----------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: interface_init
+ !
+ ! !INTERFACE:
+ subroutine interface_init(bounds)
+ !
+ ! !DESCRIPTION:
+ ! initialize the pflotran iterface
+ !
+ ! !USES:
+ use clm_varctl , only : iulog
+ use GridcellType , only : grc_pp
+ use LandunitType , only : lun_pp
+ use ColumnType , only : col_pp
+ use landunit_varcon , only : istsoil, istcrop
+ use decompMod , only : get_proc_global, get_proc_clumps, ldecomp
+ use spmdMod , only : mpicom, masterproc, iam, npes
+ use domainMod , only : ldomain, lon1d, lat1d
+
+ use clm_time_manager, only : get_nstep
+ use clm_varcon , only : dzsoi, zisoi
+ use clm_varpar , only : nlevsoi, nlevgrnd, nlevdecomp_full, ndecomp_pools
+ use clm_varctl , only : pf_hmode, pf_tmode, pf_cmode, pf_frzmode, &
+ initth_pf2clm, pf_clmnstep0, &
+ pf_surfaceflow
+
+
+ use CNDecompCascadeConType , only : decomp_cascade_con
+
+
+ ! pflotran
+ use Option_module, only : printErrMsg
+ use Simulation_Base_class, only : simulation_base_type
+ use Simulation_Subsurface_class, only : simulation_subsurface_type
+ use Realization_Base_class, only : realization_base_type
+ use Realization_Subsurface_class, only : realization_subsurface_type
+
+ use PFLOTRAN_Constants_module
+ use pflotran_clm_setmapping_module
+ use Mapping_module
+ ! !ARGUMENTS:
+
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ !
+ ! !REVISION HISTORY:
+ ! Created by Gautam Bisht
+ ! Revised by Fengming Yuan, CCSI-ORNL
+ !
+ !EOP
+ !
+ ! LOCAL VARAIBLES:
+
+ type(bounds_type), intent(in) :: bounds ! bounds
+
+ integer :: global_numg ! total number of gridcells across all processors (active)
+ integer :: global_numc ! total number of columns across all processors (active)
+ integer :: g,l,c, pid ! indices
+ integer :: nc, nclumps, total_soilc, total_grid, start_mappedgid, nx, ny, npes_pf
+ integer, pointer :: total_soilc_pes(:) ! dim: npes
+ integer, pointer :: mapped_gid(:) ! dim: 'total_soilc' or 'total_grid'
+ integer :: gid, gcount, colcount, cellcount
+ integer :: gcolumns(1:bounds%endg-bounds%begg+1)
+ integer :: ierr
+
+ character(len= 32) :: subname = 'interface_init' ! subroutine name
+
+ integer, pointer :: clm_all_cell_ids_nindex(:)
+ integer, pointer :: clm_top_cell_ids_nindex(:)
+ integer, pointer :: clm_bot_cell_ids_nindex(:)
+ integer :: clm_all_npts
+ integer :: clm_top_npts
+ integer :: clm_bot_npts
+ real(r8):: x0, x1, y0, y1, dx_global(1:ldomain%ni), dy_global(1:ldomain%nj)
+ integer :: i, j
+ real(r8):: lon0, lat0 !origin of longitude/latitude
+ integer :: nv ! number of vertices
+ class(realization_subsurface_type), pointer :: realization
+
+ associate( &
+ ! Assign local pointers to derived subtypes components (landunit-level)
+ ltype => lun_pp%itype , & ! [integer (:)] landunit type index
+ lgridcell => lun_pp%gridcell , & ! [integer (:)] gridcell index of landunit
+ ! Assign local pointer to derived subtypes components (column-level)
+ cgridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
+ clandunit => col_pp%landunit , & ! [integer (:)] landunit index of column
+ cwtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell)
+ cactive => col_pp%active & ! [logic (:)] column active or not
+ )
+
+
+ ! beg----------------------------------------------------------------
+ ! lon0/lat0 have been added to ldomain
+ lon0 = ldomain%lon0
+ lat0 = ldomain%lat0
+ ! end----------------------------------------------------------------
+
+ ! (0) determines Total grids/columns and ids to be mapped between CLM and PFLOTRAN
+
+#ifdef COLUMN_MODE
+ ! counting 'soilc' in 'filters'
+ ! NOTE: only works for 'soilc', which actually includes natural soil and crop land units
+ !
+
+ total_soilc = 0
+
+ ! mark the inactive column (non-natveg/crop landunits)
+ ! will be used to skip inactive column index in 'bounds%begc:endc'
+ allocate(mapped_gcount_skip(1:bounds%endc-bounds%begc+1))
+ mapped_gcount_skip(:) = .true.
+
+ do c = bounds%begc, bounds%endc
+ l = clandunit(c)
+ g = cgridcell(c)
+
+ if (.not.cactive(c) .or. cwtgcell(c)<=0._r8) then
+ !write (iulog,*) 'WARNING: SOIL/CROP column with wtgcell <= 0 or inactive... within the domain'
+ !write (iulog,*) 'CLM-- PFLOTRAN does not include such a SOIL/CROP column, AND will skip it'
+
+ elseif ( .not.(ltype(l)==istsoil .or. ltype(l)==istcrop) ) then
+ !write (iulog,*) 'WARNING: non-SOIL/CROP column found in filter%num_soilc: nc, l, ltype', nc, l, ltype(l)
+ !write (iulog,*) 'CLM-- PFLOTRAN does not include such a SOIL/CROP column, AND will skip it'
+
+ else
+ total_soilc = total_soilc + 1
+
+ mapped_gcount_skip(c-bounds%begc+1) = .false.
+ endif
+
+ end do
+
+ call mpi_barrier(mpicom, ierr) ! needs all processes done first
+ ! sum of all active soil columns across all processors (information only)
+ call mpi_allreduce(total_soilc, global_numc, 1, MPI_INTEGER,MPI_SUM,mpicom,ierr)
+
+ ! (active) 'soilc' global indexing across all processes
+ allocate (total_soilc_pes(0:npes-1))
+ call mpi_gather(total_soilc, 1, MPI_INTEGER, &
+ total_soilc_pes, 1, MPI_INTEGER, 0, mpicom, ierr)
+ call mpi_bcast(total_soilc_pes, npes, MPI_INTEGER, 0, mpicom, ierr)
+
+ ! CLM's natural grid id, continued and ordered across processes, for mapping to PF mesh
+ ! will be assigned to calculate 'clm_cell_ids_nindex' below
+ allocate(mapped_gid(1:total_soilc))
+
+ start_mappedgid = 0
+ do pid=0, npes-1
+ if (pid==iam) then
+
+ colcount = 0
+ do c = bounds%begc, bounds%endc
+ if (.not.mapped_gcount_skip(c-bounds%begc+1)) then
+ colcount = colcount + 1
+ mapped_gid(colcount) = start_mappedgid+colcount
+ endif
+ enddo
+
+ exit ! do pid=0,npes-1
+
+ else
+ start_mappedgid = start_mappedgid + total_soilc_pes(pid)
+ ! cumulatively add-up active soil column no. by pid,
+ ! until 'pid==iam' at which globally-indexed 'id' (mapped_gid) then can be numberred continueously.
+ endif
+
+ end do
+
+
+#else
+ ! 'grid'-wised coupling
+ ! (1) grid without soil column IS allowed, but will be skipped.
+ ! This will allow exactly same grid domain for CLM and PFLOTRAN
+ ! (why? - we may be able to run CLM-PFLOTRAN for irregular mesh, by assigning non-soil grid in normally a CLM rectangulal surface domain.)
+ ! (2) if soil column within a grid, assumes that only 1 natural/cropped soil-column allowed per grid cell NOW
+
+ ! count active soil columns for a gridcell to do checking below
+ gcolumns(:) = 0
+ ! a note: grc%ncolumns NOT assigned values at all, so cannot be used here.
+ do c = bounds%begc, bounds%endc
+ l = clandunit(c)
+ g = cgridcell(c)
+
+ gcount = g - bounds%begg + 1
+ if ((.not.(ltype(l)==istsoil)) .and. (.not.(ltype(l)==istcrop)) ) then
+ !write (iulog,*) 'WARNING: Land Unit type of Non-SOIL/CROP... within the domain'
+ !write (iulog,*) 'CLM-- PFLOTRAN does not support this land unit at present, AND will skip it'
+
+ else
+ if (cactive(c) .and. cwtgcell(c)>0._r8) then
+ gcolumns(gcount) = gcolumns(gcount)+1
+ end if
+ endif
+
+ enddo ! do c = bounds%begc, bounds%endc
+
+ ! do checking on assumption: 1 soil col. (either natveg or crop, but not both) per grid
+ total_soilc = 0
+ do g = bounds%begg, bounds%endg
+ if (gcolumns(g-bounds%begg+1) > 1) then
+ write (iulog,*) 'ERROR: More than 1 ACTIVE soil column found in gridcell:', g, gcolumns(g-bounds%begg+1)
+ write (iulog,*) 'CLM-PFLOTRAN does not support this at present, AND please check your surface data, then re-run'
+ write (iulog,*) ' i.e., this mode is used for user-defined CLM grid, which may be generated together with PF mesh'
+
+ call endrun(trim(subname) // ": ERROR: Currently does not support multiple or inactive soil column per grid " // &
+ "in this version of CLM-PFLOTRAN.")
+
+ else
+ total_soilc = total_soilc + gcolumns(g-bounds%begg+1)
+
+ endif
+ enddo
+
+ call mpi_barrier(mpicom, ierr) ! needs all processes done first
+ ! sum of all active-soil-column gridcells across all processors (information only)
+ call mpi_allreduce(total_soilc, global_numg, 1, MPI_INTEGER,MPI_SUM,mpicom,ierr)
+
+ ! counting active gridcells in current pes
+ total_grid = bounds%endg-bounds%begg+1
+
+ ! CLM's natural grid id, continued and ordered across processors, for mapping to PF mesh
+ ! will be assigned to calculate 'clm_cell_ids_nindex' below
+ allocate(mapped_gid(1:total_grid))
+
+ ! mark the inactive grid (non-natveg/crop landunits)
+ ! will be used to skip inactive grids in 'bounds%begg:endg'
+ allocate(mapped_gcount_skip(1:bounds%endg-bounds%begg+1))
+ mapped_gcount_skip(:) = .true.
+ ! ideally it's better to loop with grc%numcol, but which seems not assigned a value
+ do c=bounds%begc, bounds%endc
+ l = clandunit(c)
+ g = cgridcell(c)
+ gcount = g-bounds%begg+1
+
+ if( (ltype(l)==istsoil .or. ltype(l)==istcrop) .and. &
+ (cactive(c) .and. cwtgcell(c)>0._r8) ) then
+ mapped_gid(gcount) = grc_pp%gindex(g) ! this is the globally grid-index, i.e. 'an' in its original calculation
+
+ mapped_gcount_skip(gcount) = .false.
+ endif
+
+ end do
+
+
+#endif
+
+
+ if (masterproc) then
+ write(iulog,*) '%%--------------------------------------------------------%%'
+ write(iulog,*) '%% %%'
+ write(iulog,*) '%% clm_pf_interface_init %%'
+ write(iulog,*) '%% %%'
+#ifdef COLUMN_MODE
+ write(iulog,*) '%% --- 1D COLUMN-MODE --- %%'
+ write(iulog,*) '%% Total soil columns (natveg+crop): ',global_numc,' %%'
+#else
+ write(iulog,*) '%% --- FULLY-3D COUPLED-MODE --- %%'
+ write(iulog,*) '%% Total grids with active soil columns: ',global_numg,' %%'
+#endif
+ write(iulog,*) '%% %%'
+ write(iulog,*) '%%--------------------------------------------------------%%'
+ write(iulog,*) ' '
+ endif
+
+
+ pf_clmnstep0 = get_nstep()
+
+ !----------------------------------------------------------------------------------------
+ ! (1) Initialize PETSc vector for data transfer between CLM and PFLOTRAN
+ call CLMPFLOTRANIDataInit()
+
+ !----------------------------------------------------------------------------------------
+ ! (2) passing grid/mesh info to interface_data so that PF mesh can be established/mapped
+
+ !(2a) domain/decompose
+ clm_pf_idata%nzclm_mapped = nlevgrnd ! the soil layer no. mapped btw CLM and PF for data-passing
+
+ if (masterproc) then
+ write(iulog,*) '%% %%'
+ write(iulog,*) '%% CLM-Layer-No. PF-Layer-NO. Thickness (m) %%'
+ do j=clm_pf_idata%nzclm_mapped, 1, -1
+ write(iulog,*) j, clm_pf_idata%nzclm_mapped-j+1, dzsoi(j)
+ enddo
+ write(iulog,*) '%% %%'
+ write(iulog,*) ' '
+ endif
+
+
+#ifdef COLUMN_MODE
+ clm_pf_idata%nxclm_mapped = global_numc ! 1-D format, along X direction
+ clm_pf_idata%nyclm_mapped = 1 ! 1-D format
+
+ clm_pf_idata%npx = npes
+ clm_pf_idata%npy = 1
+ clm_pf_idata%npz = 1
+
+ if(.not.associated(clm_pf_idata%clm_lx)) &
+ allocate(clm_pf_idata%clm_lx(1:clm_pf_idata%npx))
+ if(.not.associated(clm_pf_idata%clm_ly)) &
+ allocate(clm_pf_idata%clm_ly(1:clm_pf_idata%npy))
+ if(.not.associated(clm_pf_idata%clm_lz)) &
+ allocate(clm_pf_idata%clm_lz(1:clm_pf_idata%npz))
+
+ !
+ do pid=0, npes-1
+ clm_pf_idata%clm_lx(pid+1) = total_soilc_pes(pid)
+ end do
+ clm_pf_idata%clm_ly = 1
+ clm_pf_idata%clm_lz = clm_pf_idata%nzclm_mapped
+
+ deallocate(total_soilc_pes)
+
+#else
+ clm_pf_idata%nxclm_mapped = ldomain%ni ! longitudial
+ clm_pf_idata%nyclm_mapped = ldomain%nj ! latidudial
+
+ ! Currently, the following IS only good for user-defined non-global soil domain
+ ! AND, the CLM grids ONLY over-rides PF mesh, when 'mapping_files' not provided
+ ! i.e. only used for structured-grid.
+
+ ! due to virtually 2-D surface-grid, along which PF structured-grids are decomposed,
+ !the 'npes' used by PF must be some specific number
+ nx = ldomain%ni
+ ny = ldomain%nj
+ if(npes pflotran_m%simulation)
+ class is (simulation_subsurface_type)
+ realization => simulation%realization
+ class default
+ pflotran_m%option%io_buffer = "This version of clm-pflotran only works with subsurface simulations."
+ write(*, '(/A/)') pflotran_m%option%io_buffer
+ call printErrMsg(pflotran_m%option)
+ end select
+
+ if(pflotran_m%option%nsurfflowdof > 0) then
+ pflotran_m%option%io_buffer = "This version of clm-pflotran DOES NOT work with PF Surface simulation."
+ write(*, '(/A/)') pflotran_m%option%io_buffer
+ call printErrMsg(pflotran_m%option)
+ endif
+ pf_surfaceflow = .false.
+
+ !------------------------------------------------
+
+ ! Number of cells and Indexing in CLM domain's clumps on current process ('bounds')
+
+#ifdef COLUMN_MODE
+ ! soil column-wised for mapping.
+ clm_all_npts = total_soilc*clm_pf_idata%nzclm_mapped
+ clm_top_npts = total_soilc
+ clm_bot_npts = total_soilc
+ allocate(clm_all_cell_ids_nindex(1:clm_all_npts))
+ allocate(clm_top_cell_ids_nindex(1:clm_top_npts))
+ allocate(clm_bot_cell_ids_nindex(1:clm_bot_npts))
+
+ cellcount = 0
+ do colcount = 1, total_soilc
+ gid = mapped_gid(colcount)
+
+ ! Save cell IDs (0-based) of CLM columns in 1D array on current process ('bounds')
+ clm_top_cell_ids_nindex(colcount) = (gid-1)*clm_pf_idata%nzclm_mapped
+ do j = 1,clm_pf_idata%nzclm_mapped
+ cellcount = cellcount + 1
+ clm_all_cell_ids_nindex(cellcount) = (gid-1)*clm_pf_idata%nzclm_mapped + j - 1
+ enddo
+ clm_bot_cell_ids_nindex(colcount) = gid*clm_pf_idata%nzclm_mapped - 1
+
+ end do
+ deallocate(mapped_gid)
+
+#else
+ !grid-wised for mapping.
+ clm_all_npts = total_grid*clm_pf_idata%nzclm_mapped
+ clm_top_npts = total_grid
+ clm_bot_npts = total_grid
+ allocate(clm_all_cell_ids_nindex(1:clm_all_npts))
+ allocate(clm_top_cell_ids_nindex(1:clm_top_npts))
+ allocate(clm_bot_cell_ids_nindex(1:clm_bot_npts))
+
+ cellcount = 0
+ do gcount = 1, total_grid
+
+ gid = mapped_gid(gcount)
+
+ ! Save cell IDs of CLM grid
+ do j = 1,clm_pf_idata%nzclm_mapped
+ cellcount = cellcount + 1
+ clm_all_cell_ids_nindex(cellcount) = (gid-1)*clm_pf_idata%nzclm_mapped + j-1 ! zero-based
+ enddo
+ clm_top_cell_ids_nindex(gcount) = (gid-1)*clm_pf_idata%nzclm_mapped ! zero-based
+ clm_bot_cell_ids_nindex(gcount) = gid*clm_pf_idata%nzclm_mapped-1 ! zero-based
+
+ enddo
+ deallocate(mapped_gid)
+
+#endif
+
+
+ ! CLM: 3-D Subsurface domain (local and ghosted cells)
+ clm_pf_idata%nlclm_sub = clm_all_npts
+ clm_pf_idata%ngclm_sub = clm_all_npts
+
+ ! CLM: Surface/Bottom cells of subsurface domain (local and ghosted cells)
+ clm_pf_idata%nlclm_2dtop = clm_top_npts
+ clm_pf_idata%ngclm_2dtop = clm_top_npts
+
+ ! CLM: bottom face of subsurface domain
+ clm_pf_idata%nlclm_2dbot = clm_bot_npts
+ clm_pf_idata%ngclm_2dbot = clm_bot_npts
+
+ ! PFLOTRAN: 3-D Subsurface domain (local and ghosted cells)
+ clm_pf_idata%nlpf_sub = realization%patch%grid%nlmax
+ clm_pf_idata%ngpf_sub = realization%patch%grid%ngmax
+
+ ! For CLM/PF: ground surface NOT defined, so need to set the following to zero.
+ clm_pf_idata%nlclm_srf = 0
+ clm_pf_idata%ngclm_srf = 0
+ clm_pf_idata%nlpf_srf = 0
+ clm_pf_idata%ngpf_srf = 0
+
+ ! Initialize maps for transferring data between CLM and PFLOTRAN.
+ if(associated(pflotran_m%map_clm_sub_to_pf_sub) .and. &
+ pflotran_m%map_clm_sub_to_pf_sub%id == CLM_3DSUB_TO_PF_3DSUB) then
+ call pflotranModelInitMapping(pflotran_m, clm_all_cell_ids_nindex, &
+ clm_all_npts, CLM_3DSUB_TO_PF_3DSUB)
+ endif
+ if(associated(pflotran_m%map_pf_sub_to_clm_sub) .and. &
+ pflotran_m%map_pf_sub_to_clm_sub%id == PF_3DSUB_TO_CLM_3DSUB) then
+ call pflotranModelInitMapping(pflotran_m, clm_all_cell_ids_nindex, &
+ clm_all_npts, PF_3DSUB_TO_CLM_3DSUB)
+ endif
+ !
+ if(associated(pflotran_m%map_clm_2dtop_to_pf_2dtop) .and. &
+ pflotran_m%map_clm_2dtop_to_pf_2dtop%id == CLM_2DTOP_TO_PF_2DTOP) then
+ call pflotranModelInitMapping(pflotran_m, clm_top_cell_ids_nindex, &
+ clm_top_npts, CLM_2DTOP_TO_PF_2DTOP)
+ endif
+ if(associated(pflotran_m%map_pf_2dtop_to_clm_2dtop) .and. &
+ pflotran_m%map_pf_2dtop_to_clm_2dtop%id == PF_2DTOP_TO_CLM_2DTOP) then
+ call pflotranModelInitMapping(pflotran_m, clm_top_cell_ids_nindex, &
+ clm_top_npts, PF_2DTOP_TO_CLM_2DTOP)
+ endif
+ !
+ if(associated(pflotran_m%map_clm_2dbot_to_pf_2dbot) .and. &
+ pflotran_m%map_clm_2dbot_to_pf_2dbot%id == CLM_2DBOT_TO_PF_2DBOT) then
+ call pflotranModelInitMapping(pflotran_m, clm_bot_cell_ids_nindex, &
+ clm_bot_npts, CLM_2DBOT_TO_PF_2DBOT)
+ endif
+ if(associated(pflotran_m%map_pf_2dbot_to_clm_2dbot) .and. &
+ pflotran_m%map_pf_2dbot_to_clm_2dbot%id == PF_2DBOT_TO_CLM_2DBOT) then
+ call pflotranModelInitMapping(pflotran_m, clm_bot_cell_ids_nindex, &
+ clm_bot_npts, PF_2DBOT_TO_CLM_2DBOT)
+ endif
+
+ ! Allocate vectors for data transfer between CLM and PFLOTRAN.
+ call CLMPFLOTRANIDataCreateVec(MPI_COMM_WORLD)
+
+#ifdef COLUMN_MODE
+ ! if 'column-wised' mapping, vertical-flow/transport only mode IS ON by default
+ if(pflotran_m%option%nflowdof > 0) then
+ pflotran_m%option%flow%only_vertical_flow = PETSC_TRUE
+ endif
+ if(pflotran_m%option%ntrandof > 0) then
+ pflotran_m%option%transport%only_vertical_tran = PETSC_TRUE
+ endif
+
+ ! checking if 'option%mapping_files' turned off by default
+ if(pflotran_m%option%mapping_files) then
+ pflotran_m%option%io_buffer = " COLUMN_MODE coupled clm-pflotran DOES NOT need MAPPING_FILES ON."
+ write(*, '(/A/)') pflotran_m%option%io_buffer
+ call printErrMsg(pflotran_m%option)
+ endif
+
+#endif
+
+ ! if BGC is on
+ if(pflotran_m%option%ntrandof > 0) then
+
+ ! the CLM-CN/BGC decomposing pools
+ clm_pf_idata%decomp_pool_name = decomp_cascade_con%decomp_pool_name_history(1:ndecomp_pools)
+ clm_pf_idata%floating_cn_ratio = decomp_cascade_con%floating_cn_ratio_decomp_pools(1:ndecomp_pools)
+ ! PF bgc species names/IDs
+ call pflotranModelGetRTspecies(pflotran_m)
+ endif
+
+ deallocate(clm_all_cell_ids_nindex)
+ deallocate(clm_top_cell_ids_nindex)
+ deallocate(clm_bot_cell_ids_nindex)
+
+!-------------------------------------------------------------------------------------
+ ! coupled module controls betweeen PFLOTRAN and CLM45 (F.-M. Yuan, Aug. 2013)
+ if(pflotran_m%option%iflowmode==RICHARDS_MODE) then
+ pf_hmode = .true.
+ pf_tmode = .false.
+ pf_frzmode = .false.
+
+ elseif(pflotran_m%option%iflowmode==TH_MODE) then
+ pf_hmode = .true.
+ pf_tmode = .true.
+ if (pflotran_m%option%use_th_freezing) then
+ pf_frzmode = .true.
+ else
+ pf_frzmode = .false.
+ endif
+ endif
+
+ if(pflotran_m%option%ntrandof.gt.0) then
+ pf_cmode = .true. ! initialized as '.false.' in clm initialization
+ endif
+
+
+ ! Initialize PFLOTRAN states
+ call pflotranModelStepperRunInit(pflotran_m)
+
+ end associate
+ end subroutine interface_init
+
+ !-----------------------------------------------------------------------------
+ !
+ ! !SUBROUTINE: pflotran_run_onestep
+ !
+ ! !INTERFACE:
+
+ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ !
+ ! F.-M. YUAN: based on Gautam's 'step_th_clm_pf',
+ ! 'chemistry' (PF_CMODE) added (Sept. 6, 2013)
+ !
+ ! !USES:
+ use spmdMod , only : mpicom, masterproc, iam, npes
+ use clm_time_manager , only : get_step_size, get_nstep, nsstep, nestep, &
+ is_first_step, is_first_restart_step, calc_nestep
+ use clm_varctl , only : pf_tmode, pf_hmode, pf_cmode, &
+ pf_frzmode, pf_clmnstep0, initth_pf2clm
+
+ !
+ implicit none
+
+ type(bounds_type) , intent(in) :: bounds
+ type(clumpfilter) , intent(inout) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operate
+
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ !LOCAL VARIABLES:
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: nstep ! time step number
+ integer :: total_clmstep ! total clm time step number
+ logical :: ispfprint ! let PF printout or not
+ logical :: isinitpf = .FALSE. ! (re-)initialize PF from CLM or not
+ integer :: ierr
+
+ !-----------------------------------------------------------------------
+
+ nstep = get_nstep() - pf_clmnstep0 !nsstep
+ dtime = get_step_size()
+
+ if (is_first_step() .or. is_first_restart_step()) then
+ isinitpf = .TRUE.
+ else
+ isinitpf = .FALSE.
+ endif
+
+
+ ! (0)
+ if (isinitpf) then
+ call calc_nestep() ! nestep
+ total_clmstep = nestep - pf_clmnstep0 !nestep - nsstep
+ ispfprint = .true. ! turn-on or shut-off PF's *.h5 output
+
+ call pflotranModelUpdateFinalWaypoint(pflotran_m, total_clmstep*dtime, dtime, ispfprint)
+
+ ! beg------------------------------------------------
+ ! move from 'interface_init'
+ ! force CLM soil domain into PFLOTRAN subsurface grids
+ call get_clm_soil_dimension(clm_interface_data, bounds)
+
+ ! Currently always set soil hydraulic/BGC properties from CLM to PF
+ call get_clm_soil_properties(clm_interface_data, bounds, filters)
+
+ ! Get top surface area of 3-D pflotran subsurface domain
+ call pflotranModelGetTopFaceArea(pflotran_m)
+
+ ! end------------------------------------------------
+
+ ! always initializing soil 'TH' states from CLM to pflotran
+ call get_clm_soil_th(clm_interface_data, .not.initth_pf2clm, .not.initth_pf2clm, bounds, filters, ifilter)
+
+ call pflotranModelUpdateTHfromCLM(pflotran_m, .FALSE., .FALSE.) ! pass TH to global_auxvar
+
+ endif
+
+
+ ! (1)
+ ! if PF T/H mode not available, have to pass those from CLM to global variable in PF to drive BGC/H
+ if (.not. isinitpf .and. (.not.pf_tmode .or. .not.pf_hmode)) then ! always initialize from CLM to pF, if comment out this 'if'block
+ call get_clm_soil_th(clm_interface_data, .TRUE., .TRUE., bounds, filters, ifilter)
+
+ call pflotranModelUpdateTHfromCLM(pflotran_m, .FALSE., .FALSE.) ! pass TH to global_auxvar
+
+ end if
+
+ ! ice-len adjusted porostiy, if PF-ice mode off
+ if (.not.pf_frzmode) then
+ call get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter)
+
+ call pflotranModelResetSoilPorosityFromCLM(pflotran_m)
+
+ endif
+
+ ! (2) CLM thermal BC to PFLOTRAN-CLM interface
+ if (pf_tmode) then
+ call get_clm_bceflx(clm_interface_data, bounds, filters, ifilter)
+ call pflotranModelUpdateSubsurfTCond( pflotran_m ) ! E-SrcSink and T bc
+ end if
+
+ ! (3) pass CLM water fluxes to PFLOTRAN-CLM interface
+ if (pf_hmode) then !if coupled 'H' mode between CLM45 and PFLOTRAN
+ call get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter)
+
+ ! pass flux 'vecs' from CLM to pflotran
+ call pflotranModelUpdateHSourceSink( pflotran_m ) ! H SrcSink
+ call pflotranModelSetSoilHbcsFromCLM( pflotran_m ) ! H bc
+ end if
+
+ ! (4)
+ if (pf_cmode) then
+
+ ! (4a) always (re-)initialize PFLOTRAN soil bgc state variables from CLM-CN
+ ! (this will be easier to maintain balance error-free)
+
+ call get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter)
+ call pflotranModelSetBgcConcFromCLM(pflotran_m)
+ if ((.not.pf_hmode .or. .not.pf_frzmode)) then
+ ! this is needed, because at step 0, PF's interface data is empty
+ ! which causes Aq. conc. adjustment balacne issue
+ call pflotranModelGetSaturationFromPF(pflotran_m)
+ endif
+
+
+ ! MUST reset PFLOTRAN soil aq. bgc state variables from CLM-CN due to liq. water volume change
+ ! when NOT coupled with PF Hydrology or NOT in freezing-mode (porosity will be forced to vary from CLM)
+ if (.not.pf_hmode .or. .not.pf_frzmode) then
+ call pflotranModelUpdateAqConcFromCLM(pflotran_m)
+ endif
+
+ ! (4b) bgc rate (fluxes) from CLM to PFLOTRAN
+ call get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter)
+ call pflotranModelSetBgcRatesFromCLM(pflotran_m)
+
+ endif
+
+ ! (5) the main callings of PFLOTRAN
+ call mpi_barrier(mpicom, ierr)
+
+ if(mod(nstep+1,48) == 0) then ! this will allow PFLOTRAN write out every 48 CLM time-step, if relevant option is ON.
+ ispfprint = .TRUE.
+ else
+ ispfprint = .FALSE.
+ endif
+
+ call pflotranModelStepperRunTillPauseTime( pflotran_m, (nstep+1.0d0)*dtime, dtime, ispfprint )
+ call mpi_barrier(mpicom, ierr)
+
+ ! (6) update CLM variables from PFLOTRAN
+
+ if (pf_hmode) then
+ call pflotranModelGetSaturationFromPF( pflotran_m ) ! hydrological states
+ call update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ ! the actual infiltration/runoff/drainage and solute flux with BC, if defined,
+ ! are retrieving from PFLOTRAN using 'update_bcflow_pf2clm' subroutine
+ call pflotranModelGetBCMassBalanceDeltaFromPF( pflotran_m )
+ call update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ endif
+
+ if (pf_tmode) then
+ call pflotranModelGetTemperatureFromPF( pflotran_m ) ! thermal states
+ call update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, ifilter)
+ endif
+
+ if (pf_cmode) then
+ call pflotranModelGetBgcVariablesFromPF( pflotran_m) ! bgc variables
+
+ call update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ call update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ ! need to save the current time-step PF porosity/liq. saturation for bgc species mass conservation
+ ! if CLM forced changing them into PF at NEXT timestep
+ if (.not.pf_hmode .or. .not.pf_frzmode) then
+ call pflotranModelGetSaturationFromPF(pflotran_m)
+ endif
+
+ endif
+
+ end subroutine pflotran_run_onestep
+
+ !-----------------------------------------------------------------------
+ !BOP
+ !
+ ! !ROUTINE: write_checkpoint
+ !
+ ! !INTERFACE:
+ subroutine pflotran_write_checkpoint(date_stamp)
+ !
+ ! !DESCRIPTION:
+ ! Trigger a pflotran checkpoint file to be written
+ !
+ ! !USES:
+ ! !ARGUMENTS:
+ character(len=32), intent(in) :: date_stamp ! file name date stamp
+
+ ! !LOCAL VARIABLES:
+
+ !EOP
+ !-----------------------------------------------------------------------
+
+ ! temporarily OFF - it's not working well for BGC
+ ! So, now must initializing PF variables from CLM each start/restart.
+
+ !call pflotranModelStepperCheckpoint(pflotran_m, date_stamp)
+
+ end subroutine pflotran_write_checkpoint
+
+ !-----------------------------------------------------------------------------
+ !
+ ! !IROUTINE: pflotran_finalize
+ !
+ ! !INTERFACE:
+ subroutine pflotran_finalize()
+ !
+ ! !DESCRIPTION:
+ !
+ ! finalizing pflotran runs and destroying objects
+ !
+ ! !USES:
+ use clm_varctl , only : use_pflotran
+
+ implicit none
+
+ !-----------------------------------------------------------------------
+
+ if (use_pflotran) then
+ call pflotranModelDestroy(pflotran_m)
+ endif
+
+ deallocate(mapped_gcount_skip)
+
+ end subroutine pflotran_finalize
+
+
+ !====================================================================================================
+ ! !
+ ! Subroutines to GET CLM Dimension & Properties to PFLOTRAN !
+ ! !
+ !====================================================================================================
+ !BOP
+ !
+ ! !IROUTINE: get_clm_soil_dimension
+ !
+ ! !INTERFACE:
+ subroutine get_clm_soil_dimension(clm_interface_data, bounds)
+ !
+ ! !DESCRIPTION:
+ ! get soil column dimension to PFLOTRAN
+ !
+ ! !USES:
+ use GridcellType , only : grc_pp
+ use LandunitType , only : lun_pp
+ use ColumnType , only : col_pp
+
+ use clm_varpar , only : nlevgrnd
+ use domainMod , only : ldomain
+ use landunit_varcon , only : istsoil, istcrop
+ use clm_varcon , only : re
+
+
+ !
+ ! !ARGUMENTS:
+
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ type(bounds_type) , intent(in) :: bounds
+ type(clm_interface_data_type) , intent(in) :: clm_interface_data
+ !
+ ! !REVISION HISTORY:
+ ! Created by Gautam Bisht
+ ! Revised by Fengming Yuan, CCSI-ORNL, May 2015
+ !
+ !EOP
+ !
+ ! LOCAL VARAIBLES:
+
+ integer :: g,l,c,j ! indices
+ integer :: gcount, colcount, cellcount ! gcount: 0-based, colcount: 1-based, cellcount: 1-based
+ integer :: v, n1, n2
+ real(r8) :: p1, p2
+ real(r8) :: dxsoil_clm(1:bounds%endg-bounds%begg+1)
+ real(r8) :: dysoil_clm(1:bounds%endg-bounds%begg+1)
+#ifdef COLUMN_MODE
+ real(r8) :: wtgcell_sum(1:bounds%endc-bounds%begc+1)
+#else
+ real(r8) :: wtgcell_sum(1:bounds%endg-bounds%begg+1)
+ integer :: xwtgcell_c(1:bounds%endg-bounds%begg+1)
+#endif
+
+ character(len= 32) :: subname = 'get_clm_soil_dimension' ! subroutine name
+
+ PetscScalar, pointer :: cellid_clm_loc(:)
+ PetscScalar, pointer :: zisoil_clm_loc(:) ! 3-D PF-cell's z-node coordinates (elevation-adjusted, unit: m)
+ PetscScalar, pointer :: dxsoil_clm_loc(:) ! 3-D PF-cell's soil length (unit: degrees)
+ PetscScalar, pointer :: dysoil_clm_loc(:) ! 3-D PF-cell's soil width (unit: degrees)
+ PetscScalar, pointer :: dzsoil_clm_loc(:) ! 3-D PF-cell's soil thickness (unit: m)
+ PetscScalar, pointer :: xsoil_clm_loc(:) ! 3-D PF-cell's center x coordinates (unit: m)
+ PetscScalar, pointer :: ysoil_clm_loc(:) ! 3-D PF-cell's center y coordinates (unit: m)
+ PetscScalar, pointer :: zsoil_clm_loc(:) ! 3-D PF-cell's soil depth from ground surface at the layer center (unit: m)
+ PetscScalar, pointer :: toparea_clm_loc(:) ! 3-D PF-cell (unit: m^2)
+
+ PetscErrorCode :: ierr
+
+
+ ! for calling functions in 'geodesic.for'
+ double precision a, f, dummy1, dummy2
+ double precision lats(4), lons(4)
+ a = 6378137.0d0 ! major-axis length of Earth Ellipsoid in metres in WGS-84
+ f = 1.d0/298.257223563d0 ! flatening of Earth Ellipsoid in WGS-84
+
+ associate( &
+ ! Assign local pointers to derived subtypes components (gridcell-level)
+ latc => ldomain%latc , & ! [real(r8) (:)]
+ lonc => ldomain%lonc , & ! [real(r8) (:)]
+ ! latv/lonv missing in ACME1
+ latv => ldomain%latv , & ! [real(r8) (:,:)]
+ lonv => ldomain%lonv , & ! [real(r8) (:,:)]
+
+ lelev => ldomain%topo , & ! [real(r8) (:)]
+ larea => ldomain%area , & ! [real(r8) (:)]
+ ! landunit
+ ltype => lun_pp%itype , & ! [integer (:)] landunit type index
+ ! Assign local pointer to derived subtypes components (column-level)
+ clandunit => col_pp%landunit , & ! [integer (:)] landunit index of column
+ cgridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
+ cwtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell)
+ cactive => col_pp%active , & ! [logic (:)] column active or not
+ !
+ z => col_pp%z , & ! [real(r8) (:,:)] layer depth (m) (sort of centroid from surface 0 )
+ zi => col_pp%zi , & ! [real(r8) (:,:)] layer interface depth (m)
+ dz => col_pp%dz & ! [real(r8) (:,:)] layer thickness (m)
+ )
+
+
+#ifdef COLUMN_MODE
+ wtgcell_sum(:) = 1._r8 ! this is a fake value for column because cannot use the real 'cwtgcell', which may be ZERO (but will skip when do data passing)
+
+#else
+ ! active column weight summation for 1 grid
+ wtgcell_sum(:) = 0._r8
+ xwtgcell_c(:) = 0
+
+ do c = bounds%begc, bounds%endc
+ gcount = cgridcell(c) - bounds%begc + 1
+ if (xwtgcell_c(gcount)<=0) xwtgcell_c(gcount) = c
+ if (cactive(c)) then
+ wtgcell_sum(gcount) = wtgcell_sum(gcount)+cwtgcell(c)
+
+ if( (cwtgcell(c)>=cwtgcell(xwtgcell_c(gcount))) .or. &
+ (.not.cactive(xwtgcell_c(gcount))) ) then
+ xwtgcell_c(gcount) = c ! column index with max. weight in a gridcell
+ end if
+
+ end if
+
+ enddo
+#endif
+
+ do g = bounds%begg, bounds%endg
+ gcount = g - bounds%begg ! 0-based
+ ! re-calculating 2-D grid area if vertices are known from input file
+ ! NOTE: this will over-write the grid area read-in from either 'ldomain' file or 'surfdata' file
+ if (ldomain%nv==4 .or. ldomain%nv==3) then
+ if (ldomain%nv==4) then
+ lats = latv(g,1:4)
+ lons = lonv(g,1:4)
+ call area(a, f, lats, lons, 4, dummy1, dummy2)
+ else if (ldomain%nv==3) then
+ lats(1:3) = latv(g,1:3)
+ lons(1:3) = lonv(g,1:3)
+ call area(a, f, lats(1:3), lons(1:3), 3, dummy1, dummy2)
+ endif
+
+ if (dummy1 < 1.d-20) then
+ call endrun(trim(subname) // ": ERROR: re-calculated ldomain%area is less than 0. " // &
+ "Please check the grid vertices lat/lon in ldomain file")
+ else
+ larea(g) = dummy1 * 1.e-6_r8
+ endif
+
+ ! for 1-D grid, either 'dx' or 'dy' may be variable and acceptable in the model
+ ! (though, currently NOT YET used for PF mesh)
+ ! (NOTE: for 2-D grid, dx/dy in lon/lat can NOT be variable)
+ if(.not.ldomain%isgrid2d) then
+
+ p1 = 0._r8
+ p2 = 0._r8
+ n1 = 0
+ n2 = 0
+ do v = 1, ldomain%nv ! ldomain%nv missing in ACME1
+ if (lonv(g,v)lonc(g)) then
+ p2 = p2 + lonv(g,v)
+ n2 = n2 + 1
+ end if
+ end do
+ if (n1 > 0 .and. n2 > 0) then
+ dxsoil_clm(gcount+1) = abs(p2/n2-p1/n1) ! degs
+ endif
+
+ p1 = 0._r8
+ p2 = 0._r8
+ n1 = 0
+ n2 = 0
+ do v = 1, ldomain%nv ! ldomain%nv missing in ACME1
+ if (latv(g,v)latc(g)) then
+ p2 = p2 + latv(g,v)
+ n2 = n2 + 1
+ end if
+ end do
+ if (n1 > 0 .and. n2 > 0) then
+ dysoil_clm(gcount+1) = abs(p2/n2-p1/n1) ! degs
+ endif
+
+ endif !if(.not.ldomain%isgrid2d)
+
+ endif !if (ldomain%nv==4 .or. 3)
+
+ end do
+
+ call VecGetArrayF90(clm_pf_idata%cellid_clmp, cellid_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%zisoil_clmp, zisoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%dxsoil_clmp, dxsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%dysoil_clmp, dysoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%dzsoil_clmp, dzsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%area_top_face_clmp, toparea_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%xsoil_clmp, xsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%ysoil_clmp, ysoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%zsoil_clmp, zsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ zisoil_clm_loc(:) = 0._r8
+ dxsoil_clm_loc(:) = 0._r8
+ dysoil_clm_loc(:) = 0._r8
+ dzsoil_clm_loc(:) = 0._r8
+
+ toparea_clm_loc(:) = 0._r8
+ xsoil_clm_loc(:) = 0._r8
+ ysoil_clm_loc(:) = 0._r8
+ zsoil_clm_loc(:) = 0._r8
+
+
+#ifdef COLUMN_MODE
+ gcount = -1
+ do c = bounds%begc, bounds%endc
+ g = cgridcell(c)
+ l = clandunit(c)
+
+ colcount = c - bounds%begc + 1
+ ! note that filters%soilc includes 'istsoil' and 'istcrop'
+ ! (TODO: checking col%itype and lun%itype - appears not match with each other, and col%itype IS messy)
+ if (.not.mapped_gcount_skip(colcount) ) then
+ gcount = gcount + 1 ! 0-based: the active soil column count
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+ if (j <= nlevgrnd) then
+
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ xsoil_clm_loc(cellcount) = lonc(g)
+ ysoil_clm_loc(cellcount) = latc(g)
+ !
+ dzsoil_clm_loc(cellcount) = dz(c, j) ! cell vertical thickness (m)
+ zisoil_clm_loc(cellcount) = -zi(c, j-1) + lelev(g) ! cell-node (top) elevation (m)
+ zsoil_clm_loc(cellcount) = z(c, j) ! cell-center vertical depth from surface (m)
+
+ ! top face area, scaled by active column weight and land fraction
+ toparea_clm_loc(cellcount) = wtgcell_sum(colcount) * ldomain%frac(g) * larea(g) * 1.e6_r8 ! m^2
+
+
+ ! after knowing 'toparea', we may get a pseudo 'dx' and 'dy' so that PF will not crash
+ ! (note: PF needs these information otherwise throw-out error message, even with 'vertical_only' option)
+
+ if (ldomain%nv == 4) then ! ldomain%nv missing in ACME1
+ ! having 4 vertices
+ lats = latv(g,1:4)
+ lons = lonv(g,1:4)
+ dxsoil_clm_loc(cellcount) = abs(lons(1)+lons(4)-lons(2)-lons(3))/2.0_r8 &
+ * wtgcell_sum(colcount) * ldomain%frac(g)
+ ! note: since in 'column_wise' mode, the columns are in 1D array by x-axis,
+ ! only need to scale 'dx' by column area fraction
+ dysoil_clm_loc(cellcount) = abs(lats(1)+lats(2)-lats(3)-lats(4))/2.0_r8
+
+ else
+ dxsoil_clm_loc(cellcount) = larea(g)/(re**2) & ! in degrees of great circle length
+ * wtgcell_sum(colcount) * ldomain%frac(g)
+ dysoil_clm_loc(cellcount) = larea(g)/(re**2)
+ endif
+
+ else
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+
+ endif
+
+ enddo ! do j=1,nzclm_mapped
+
+ endif
+ enddo ! do c = bounds%begc, bounds%endc
+
+#else
+
+ do g = bounds%begg, bounds%endg
+ gcount = g - bounds%begg ! 0-based
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+
+ if (j <= nlevgrnd) then
+
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ cellid_clm_loc(cellcount) = (grc_pp%gindex(g)-1)*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ xsoil_clm_loc(cellcount) = lonc(g)
+ ysoil_clm_loc(cellcount) = latc(g)
+ dxsoil_clm_loc(cellcount) = -9999.d0
+ dysoil_clm_loc(cellcount) = -9999.d0
+
+ !
+ dzsoil_clm_loc(cellcount) = dz(xwtgcell_c(gcount+1), j) ! cell vertical thickness (m), by column of max. weight in a grid
+ zisoil_clm_loc(cellcount) = -zi(xwtgcell_c(gcount+1), j-1) + lelev(g) ! cell-node (top) elevation (m)
+ zsoil_clm_loc(cellcount) = z(xwtgcell_c(gcount+1), j) ! cell-center vertical depth from surface (m)
+
+ ! top face area, scaled by active column weight (summed) and land fraction
+ toparea_clm_loc(cellcount) = wtgcell_sum(gcount+1) * ldomain%frac(g) * larea(g) * 1.e6_r8 ! m^2
+
+ else
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+
+ endif
+
+ enddo ! do j=1,nzclm_mapped
+ enddo ! do g = bounds%begg, bounds%endg
+
+#endif
+
+ call VecRestoreArrayF90(clm_pf_idata%cellid_clmp, cellid_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%zisoil_clmp, zisoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%dxsoil_clmp, dxsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%dysoil_clmp, dysoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%dzsoil_clmp, dzsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%area_top_face_clmp, toparea_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%xsoil_clmp, xsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%ysoil_clmp, ysoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%zsoil_clmp, zsoil_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! Set CLM soil domain onto PFLOTRAN grid
+ call pflotranModelSetSoilDimension(pflotran_m)
+
+ end associate
+ end subroutine get_clm_soil_dimension
+
+ !-----------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: get_clm_soil_properties
+ !
+ ! !INTERFACE:
+ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters)
+ !
+ ! !DESCRIPTION:
+ ! get soil column physical properties to PFLOTRAN
+ !
+ ! !USES:
+ use LandunitType , only : lun_pp
+ use ColumnType , only : col_pp
+ use landunit_varcon , only : istsoil, istcrop
+
+ use clm_varpar , only : nlevgrnd, ndecomp_pools, ndecomp_cascade_transitions
+ use CNDecompCascadeConType , only : decomp_cascade_con
+
+ ! pflotran
+ !
+ ! !ARGUMENTS:
+
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+#include "petsc/finclude/petscviewer.h"
+
+ !
+ ! !REVISION HISTORY:
+ ! Created by Gautam Bisht
+ ! Revised by Fengming Yuan, CCSI-ORNL
+ !
+ !EOP
+ !
+ ! LOCAL VARAIBLES:
+
+ type(bounds_type), intent(in) :: bounds ! bounds
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ ! LOCAL VARAIBLES:
+
+ integer :: fc, c, l, g, j ! indices
+ integer :: k,ki,kj
+ integer :: gcount, cellcount ! gcount: 0-based, cellcount: 1-based
+ integer :: soilc1, layer1
+ real(r8) :: CN_ratio_mass_to_mol
+ real(r8) :: wtgcount
+
+ character(len= 32) :: subname = 'get_clm_soil_properties' ! subroutine name
+
+
+ PetscScalar, pointer :: hksat_x_clm_loc(:) ! hydraulic conductivity in x-dir at saturation (mm H2O /s)
+ PetscScalar, pointer :: hksat_y_clm_loc(:) ! hydraulic conductivity in y-dir at saturation (mm H2O /s)
+ PetscScalar, pointer :: hksat_z_clm_loc(:) ! hydraulic conductivity in z-dir at saturation (mm H2O /s)
+ PetscScalar, pointer :: watsat_clm_loc(:) ! minimum soil suction (mm)
+ PetscScalar, pointer :: sucsat_clm_loc(:) ! volumetric soil water at saturation (porosity)
+ PetscScalar, pointer :: bsw_clm_loc(:) ! Clapp and Hornberger "b"
+ PetscScalar, pointer :: watfc_clm_loc(:)
+ PetscScalar, pointer :: bulkdensity_dry_clm_loc(:)
+
+ PetscScalar, pointer :: tkwet_clm_loc(:)
+ PetscScalar, pointer :: tkdry_clm_loc(:)
+ PetscScalar, pointer :: tkfrz_clm_loc(:)
+ PetscScalar, pointer :: hcvsol_clm_loc(:)
+
+ PetscErrorCode :: ierr
+
+ associate( &
+ ! Assign local pointer to derived subtypes components (column-level)
+ ltype => lun_pp%itype , & ! [integer (:)] landunit type index
+ ! Assign local pointer to derived subtypes components (column-level)
+ clandunit => col_pp%landunit , & ! [integer (:)] landunit index of column
+ cgridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
+ cwtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell
+ cactive => col_pp%active , & !
+ z => col_pp%z , & ! [real(r8) (:,:)] layer depth (m)
+ dz => col_pp%dz , & ! [real(r8) (:,:)] layer thickness depth (m)
+ zi => col_pp%zi , & ! [real(r8) (:,:)] interface level below a "z" level (m)
+ !
+ bd => clm_interface_data%bd_col , & !
+ bsw => clm_interface_data%bsw_col , & ! [real(r8) (:,:)] Clapp and Hornberger "b" (nlevgrnd)
+ hksat => clm_interface_data%hksat_col , & ! [real(r8) (:,:)] hydraulic conductivity at saturation (mm H2O /s) (nlevgrnd)
+ sucsat => clm_interface_data%sucsat_col , & ! [real(r8) (:,:)] minimum soil suction (mm) (nlevgrnd)
+ watsat => clm_interface_data%watsat_col , & ! [real(r8) (:,:)] volumetric soil water at saturation (porosity) (nlevgrnd)
+ watfc => clm_interface_data%watfc_col , & ! [real(r8) (:,:)] volumetric soil water at field capacity (nlevgrnd)
+ !
+ tkwet => clm_interface_data%tkwet_col , & ! [real(r8) (:,:)] (nlevgrnd)
+ tkdry => clm_interface_data%tkdry_col , & ! [real(r8) (:,:)] (nlevgrnd)
+ tkfrz => clm_interface_data%tkfrz_col , & ! [real(r8) (:,:)] (nlevgrnd)
+ csol => clm_interface_data%csol_col , & ! [real(r8) (:,:)] (nlevgrnd)
+ !
+ rf_decomp_cascade => clm_interface_data%bgc%rf_decomp_cascade_col , &
+ pathfrac_decomp_cascade => clm_interface_data%bgc%pathfrac_decomp_cascade_col , &
+ initial_cn_ratio => clm_interface_data%bgc%initial_cn_ratio , &
+ kd_decomp_pools => clm_interface_data%bgc%decomp_k_pools , &
+ kd_adfactor_pools => clm_interface_data%bgc%adfactor_kd_pools &
+ )
+
+!-------------------------------------------------------------------------------------
+ if(pflotran_m%option%ntrandof > 0) then
+ ! the following assumes 'nclumps' in current process greater than 0 (at least 1)
+
+ CN_ratio_mass_to_mol = clm_pf_idata%N_molecular_weight/clm_pf_idata%C_molecular_weight
+ clm_pf_idata%decomp_element_ratios(:,1) = 1.0_r8
+ clm_pf_idata%decomp_element_ratios(:,2) = 1.0_r8/initial_cn_ratio(1:ndecomp_pools) &
+ /CN_ratio_mass_to_mol ! ratio in moles
+
+ ! note: the following 'kd' and ad-factors for each pool are separated
+ clm_pf_idata%ck_decomp_c = kd_decomp_pools(1:ndecomp_pools)
+ clm_pf_idata%adfactor_ck_c = kd_adfactor_pools(1:ndecomp_pools)
+
+ ! find the first active SOIL Column to pick up the decomposition constants
+ ! NOTE: this only is good for CLM-CN reaction-network;
+ ! for CLM-BGC (century-type), those constants are 'cell' dependent
+ ! So, here we do the data passing by cell (although only 1 now) that can be extended by adding two loops in the future
+ !
+ soilc1 = filters(1)%soilc(1)
+ layer1 = 1
+
+ clm_pf_idata%fr_decomp_c = 0._r8
+ do k = 1, ndecomp_cascade_transitions
+ ki=decomp_cascade_con%cascade_donor_pool(k)
+ kj=decomp_cascade_con%cascade_receiver_pool(k)
+
+ if (ki>0) then
+ ! taking the first 'cell' as default ('pathfrac' is 'cell'-related, which will be adjusted if needed)
+ if (clm_pf_idata%fr_decomp_c(ki,ki) <=0._r8) then
+ ! not-yet assign 'co2' fraction for donor-pool
+ clm_pf_idata%fr_decomp_c(ki,ki) = rf_decomp_cascade(soilc1,layer1,k) ! CO2-C respiration fraction
+ elseif(clm_pf_idata%fr_decomp_c(ki,ki) .ne. rf_decomp_cascade(soilc1,layer1,k)) then
+ ! have assigned 'co2' fraction for same donor-pool with different receive-pool,
+ ! BUT 'co2' fraction inconsistent
+ call endrun(trim(subname) // ": ERROR: CLM-PFLOTRAN interface finds different respiration fraction for " // &
+ "same decomposition pool: " //trim(decomp_cascade_con%decomp_pool_name_history(ki)) )
+
+ endif
+
+ if (kj>0) then
+ clm_pf_idata%fr_decomp_c(ki,kj) = (1.0_r8-rf_decomp_cascade(soilc1,layer1,k)) &
+ * pathfrac_decomp_cascade(soilc1,layer1,k)
+ else
+ if(clm_pf_idata%fr_decomp_c(ki,ki) .ne. 1.0) then
+ ! if no receivor, respiration fraction must be 1.0
+ call endrun(trim(subname) // ": ERROR: CLM-PFLOTRAN interface finds respiration fraction not 1.0 for " // &
+ "no-down decomposition pool: " //trim(decomp_cascade_con%decomp_pool_name_history(ki)) )
+ endif
+
+ endif
+
+ endif
+
+ enddo
+
+ call pflotranModelSetSOMKfromCLM(pflotran_m)
+ endif
+
+
+ call VecGetArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%tkwet_clmp, tkwet_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%tkdry_clmp, tkdry_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%tkfrz_clmp, tkfrz_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%hcvsol_clmp, hcvsol_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ hksat_x_clm_loc(:) = 0._r8
+ hksat_y_clm_loc(:) = 0._r8
+ hksat_z_clm_loc(:) = 0._r8
+ sucsat_clm_loc(:) = 0._r8
+ watsat_clm_loc(:) = 0._r8
+ bsw_clm_loc(:) = 0._r8
+ watfc_clm_loc(:) = 0._r8
+ bulkdensity_dry_clm_loc(:) = 0._r8
+
+ tkwet_clm_loc(:) = 0._r8
+ tkdry_clm_loc(:) = 0._r8
+ tkfrz_clm_loc(:) = 0._r8
+ hcvsol_clm_loc(:) = 0._r8
+
+ gcount = -1
+ ! note: the following data-passing will be looping for all columns, instead of filters,
+ ! so that NO void grids in PF mesh even for inactive (and skipped) gridcell.
+ do c = bounds%begc, bounds%endc
+ ! Set gridcell and landunit indices
+ g = cgridcell(c)
+ l = clandunit(c)
+
+ if ( (ltype(l)==istsoil .or. ltype(l)==istcrop) .and. &
+ (cactive(c) .and. cwtgcell(c)>0._r8) ) then ! skip inactive or zero-weighted column (may be not needed, but in case)
+
+#ifdef COLUMN_MODE
+ gcount = gcount + 1 ! 0-based column (fake grid) count
+ wtgcount = 1._r8
+#else
+ gcount = g - bounds%begg ! 0-based actual grid numbering
+ wtgcount = cwtgcell(c)
+#endif
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+
+ if (j <= nlevgrnd) then
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ ! CLM calculation of wet thermal-conductivity as following:
+ ! dksat = tkmg(c,j)*tkwat**(fl*watsat(c,j))*tkice**((1._r8-fl)*watsat(c,j))
+ ! where, fl is the liq. saturation/total saturation
+ ! so, if fl=0, it's the frozen-wet thermal-conductitivity
+ ! if fl=1, it's the liq.-wet thermal-conductivity, i.e. 'tksatu'
+
+ tkwet_clm_loc(cellcount ) = & !(W/m/K)
+ tkwet_clm_loc(cellcount ) + tkwet(c,j)*wtgcount
+ tkdry_clm_loc(cellcount ) = &
+ tkdry_clm_loc(cellcount ) + tkdry(c,j)*wtgcount
+ tkfrz_clm_loc(cellcount ) = &
+ tkfrz_clm_loc(cellcount ) + tkfrz(c,j)*wtgcount
+ hcvsol_clm_loc(cellcount ) = &
+ hcvsol_clm_loc(cellcount ) + csol(c,j)*wtgcount ! (J/m3/K)
+
+ hksat_x_clm_loc(cellcount ) = &
+ hksat_x_clm_loc(cellcount ) + hksat(c,j)*wtgcount
+ hksat_y_clm_loc(cellcount ) = &
+ hksat_y_clm_loc(cellcount ) + hksat(c,j)*wtgcount
+ hksat_z_clm_loc(cellcount ) = &
+ hksat_z_clm_loc(cellcount ) + hksat(c,j)*wtgcount
+
+ sucsat_clm_loc( cellcount ) = &
+ sucsat_clm_loc( cellcount ) + sucsat(c,j)*wtgcount
+ watsat_clm_loc( cellcount ) = &
+ watsat_clm_loc( cellcount ) + watsat(c,j)*wtgcount
+ bsw_clm_loc( cellcount ) = &
+ bsw_clm_loc( cellcount ) + bsw(c,j)*wtgcount
+ watfc_clm_loc( cellcount ) = &
+ watfc_clm_loc( cellcount ) + watfc(c,j)*wtgcount
+ bulkdensity_dry_clm_loc( cellcount ) = &
+ bulkdensity_dry_clm_loc( cellcount ) + bd(c,j)*wtgcount
+
+ else
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+
+ endif
+ enddo
+ endif
+
+ enddo ! do c = bounds%begc, bounds%endc
+
+ call VecRestoreArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+! call VecRestoreArrayF90(clm_pf_idata%zsoi_clmp, zsoi_clm_loc, ierr)
+! call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%tkwet_clmp, tkwet_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%tkdry_clmp, tkdry_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%tkfrz_clmp, tkfrz_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%hcvsol_clmp, hcvsol_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! Set CLM soil properties onto PFLOTRAN grid
+ call pflotranModelSetSoilProp(pflotran_m)
+
+ end associate
+ end subroutine get_clm_soil_properties
+
+
+ !====================================================================================================
+ ! !
+ ! Subroutines to GET CLM initial/src-sink/BC to PFLOTRAN !
+ ! !
+ !====================================================================================================
+
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !ROUTINE: get_clm_soil_th
+ !
+ ! !INTERFACE:
+ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, filters, ifilter)
+
+ !
+ ! !DESCRIPTION:
+ ! update soil temperature/saturation from CLM to PFLOTRAN for driving PF's BGC
+ ! if either NOT available inside PFLOTRAN
+ !
+ ! !USES:
+ use clm_time_manager , only : get_nstep, is_first_step, is_first_restart_step
+ use shr_const_mod , only : SHR_CONST_G
+ use ColumnType , only : col_pp
+ use clm_varctl , only : iulog
+ use clm_varcon , only : denh2o, denice, tfrz
+ use clm_varpar , only : nlevgrnd
+ use shr_infnan_mod , only : shr_infnan_isnan
+
+ use PFLOTRAN_Constants_module
+ use clm_varctl , only : pf_frzmode
+
+ ! !ARGUMENTS:
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+ logical , intent(in) :: initpftmode, initpfhmode
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, g, gcount, cellcount ! indices
+
+ PetscScalar, pointer :: soilpress_clmp_loc(:)
+ PetscScalar, pointer :: soilpsi_clmp_loc(:)
+ PetscScalar, pointer :: soillsat_clmp_loc(:)
+ PetscScalar, pointer :: soilisat_clmp_loc(:)
+ PetscScalar, pointer :: soilvwc_clmp_loc(:) !
+ PetscScalar, pointer :: soilt_clmp_loc(:) !
+ PetscScalar, pointer :: t_scalar_clmp_loc(:) !
+ PetscScalar, pointer :: w_scalar_clmp_loc(:) !
+ PetscScalar, pointer :: o_scalar_clmp_loc(:) !
+ PetscErrorCode :: ierr
+ integer :: j,nstep
+ real(r8):: sattmp, psitmp, itheta, sucmin_pa, psitmp0
+
+ character(len= 32) :: subname = 'get_clm_soil_th' ! subroutine name
+
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ dz => col_pp%dz , & ! layer thickness depth (m)
+ !
+ sucsat => clm_interface_data%sucsat_col , & ! minimum soil suction (mm) (nlevgrnd)
+ bsw => clm_interface_data%bsw_col , & ! Clapp and Hornberger "b"
+ watsat => clm_interface_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd)
+ watmin => clm_interface_data%watmin_col , & ! col minimum volumetric soil water (nlevsoi)
+ sucmin => clm_interface_data%sucmin_col , & ! col minimum allowable soil liquid suction pressure (mm) [Note: sucmin_col is a negative value, while sucsat_col is a positive quantity]
+ !
+ soilpsi => clm_interface_data%th%soilpsi_col , & ! soil water matric potential in each soil layer (MPa)
+ h2osoi_liq => clm_interface_data%th%h2osoi_liq_col, & ! liquid water (kg/m2)
+ h2osoi_ice => clm_interface_data%th%h2osoi_ice_col, & ! ice lens (kg/m2)
+ h2osoi_vol => clm_interface_data%th%h2osoi_vol_col, & ! volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3]
+ t_soisno => clm_interface_data%th%t_soisno_col , & ! snow-soil temperature (Kelvin)
+ !
+ t_scalar => clm_interface_data%bgc%t_scalar_col , & ! soil temperature scalar for decomp
+ w_scalar => clm_interface_data%bgc%w_scalar_col , & ! soil water scalar for decomp
+ o_scalar => clm_interface_data%bgc%o_scalar_col & ! fraction by which decomposition is limited by anoxia
+ )
+
+ !--------------------------------------------------------------------------------------
+ nstep = get_nstep()
+
+ call VecGetArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%h2osoi_vol_clmp, soilvwc_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%t_scalar_clmp, t_scalar_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%w_scalar_clmp, w_scalar_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%o_scalar_clmp, o_scalar_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+
+ if (j<=nlevgrnd) then
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ if (initpfhmode) then
+ ! this adjusting should be done first, if PF-freezing-mode off,
+ ! so that the following calculation can be done correctly
+ itheta = h2osoi_ice(c,j) / (dz(c,j) * denice)
+ itheta = min(itheta, watsat(c,j)-watmin(c,j))
+ soilisat_clmp_loc(cellcount) = itheta/watsat(c,j)
+
+ if(.not.pf_frzmode) then
+ ! porosity will be ice-adjusted for PF, if PF freezing-mode is off,
+ ! so need to adjust 'psi' so that 'saturation' in PF is correct
+ sattmp = h2osoi_liq(c,j) / ((watsat(c,j)-itheta)*dz(c,j)*denh2o)
+ sattmp = min(max(0.01d0, sattmp/(watsat(c,j)-itheta)),1._r8)
+
+ ! soil matric potential re-done by Clapp-Hornburger method (this is the default used by CLM)
+ ! this value IS different from what CLM used (not ice-content adjusted)
+ ! So that in PF, if not ice-adjusted, the PSI is very small (negative) which implies possible water movement
+
+ ! sucsat > 0, sucmin < 0, sucsat & sucmin have units of mm
+ ! psitmp = psitmp0, as denh2o*1.e-3_r8 = 1.0
+ psitmp0 = sucsat(c,j) * (-SHR_CONST_G) * (sattmp**(-bsw(c,j))) ! -Pa
+
+ psitmp = denh2o*(-SHR_CONST_G)*(sucsat(c,j)*1.e-3_r8)*(sattmp**(-bsw(c,j))) ! -Pa
+ sucmin_pa = denh2o*SHR_CONST_G*sucmin(c,j)*1.e-3_r8 ! -Pa
+ psitmp = min(max(psitmp,sucmin_pa),0._r8) !Pa
+
+ else
+ sattmp = h2osoi_liq(c,j) / (watsat(c,j)*dz(c,j)*denh2o)
+ sattmp = min(max(0.01d0, sattmp/watsat(c,j)),1._r8)
+
+ psitmp = soilpsi(c,j)*1.e6_r8 ! MPa -> Pa
+ if (shr_infnan_isnan(soilpsi(c,j)) .or. nstep<=0) then ! only for initialization, in which NOT assigned a value
+ psitmp0 = sucsat(c,j) * (-SHR_CONST_G) * ((sattmp+itheta)**(-bsw(c,j))) ! -Pa: included both ice and liq. water as CLM does
+ psitmp = denh2o*(-SHR_CONST_G)*(sucsat(c,j)*1.e-3_r8) * ((sattmp+itheta)**(-bsw(c,j)))
+ sucmin_pa = denh2o*SHR_CONST_G*sucmin(c,j)*1.e-3_r8
+ psitmp = min(max(psitmp,sucmin_pa),0._r8)
+ endif
+
+ endif !if(.not.pf_frzmode)
+ soillsat_clmp_loc(cellcount) = sattmp
+
+ soilpsi_clmp_loc(cellcount) = psitmp
+ soilpress_clmp_loc(cellcount) = psitmp+clm_pf_idata%pressure_reference
+
+ w_scalar_clmp_loc(cellcount) = w_scalar(c,j)
+ o_scalar_clmp_loc(cellcount) = o_scalar(c,j)
+
+ soilvwc_clmp_loc(cellcount) = h2osoi_vol(c,j)
+
+ endif !if (initpfhmode) then
+
+ if (initpftmode) then
+ soilt_clmp_loc(cellcount)=t_soisno(c,j)-tfrz
+ t_scalar_clmp_loc(cellcount)=t_scalar(c,j)
+ endif
+
+ else
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+
+ endif !if (j<=nlevgrnd) then
+
+ enddo !do j = 1, clm_pf_idata%nzclm_mapped
+ enddo !do fc = 1,filters(ifilter)%num_soilc
+
+ call VecRestoreArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%h2osoi_vol_clmp, soilvwc_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%t_scalar_clmp, t_scalar_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%w_scalar_clmp, w_scalar_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%o_scalar_clmp, o_scalar_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine get_clm_soil_th
+
+
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !ROUTINE: get_clm_iceadj_porosity
+ !
+ ! !INTERFACE:
+ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ ! update soil effective porosity from CLM to PFLOTRAN if PF freezing mode is off
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_varctl , only : iulog
+ use clm_varcon , only : denice
+ use clm_varpar , only : nlevgrnd
+
+ use PFLOTRAN_Constants_module
+ use clm_varctl , only : pf_frzmode
+
+ ! !ARGUMENTS:
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ type(bounds_type) , intent(in) :: bounds ! bounds
+ type(clumpfilter) , intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, g, j, gcount, cellcount ! indices
+ real(r8) :: itheta
+
+ PetscScalar, pointer :: adjporosity_clmp_loc(:) !
+ PetscScalar, pointer :: soilisat_clmp_loc(:) !
+ PetscErrorCode :: ierr
+
+ character(len= 32) :: subname = 'get_clm_iceadj_porosity' ! subroutine name
+
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ dz => col_pp%dz , & ! layer thickness depth (m)
+ !
+ watsat => clm_interface_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd)
+ h2osoi_ice => clm_interface_data%th%h2osoi_ice_col & ! ice lens (kg/m2)
+ )
+
+ ! if 'pf_tmode' is NOT using freezing option, the phase-change of soil water done in 'SoilTemperatureMod.F90' in 'bgp2'
+ ! must be included to adjust porosity (effective porosity) in pflotran
+ ! This is doing prior to the real liquid water source/sink, because 'h2osoi_liq' will be updated during those calls after 'bgp2'.
+ if (.not. pf_frzmode) then
+
+ ! re-calculate the effective porosity (CLM ice-len adjusted), which should be pass to pflotran
+ call VecGetArrayF90(clm_pf_idata%effporosity_clmp, adjporosity_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+ if (j<=nlevgrnd) then
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ itheta = h2osoi_ice(c,j) / (dz(c,j) * denice)
+ itheta = min(itheta, 0.99_r8*watsat(c,j))
+ adjporosity_clmp_loc(cellcount ) = watsat(c,j) - itheta
+ soilisat_clmp_loc(cellcount ) = itheta/watsat(c,j)
+ else
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer number is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+
+ endif
+
+ end do
+ end do
+
+ call VecRestoreArrayF90(clm_pf_idata%effporosity_clmp, adjporosity_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end if
+
+ end associate
+ end subroutine get_clm_iceadj_porosity
+ !
+
+!-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: get_clm_bcwflx
+ !
+ ! !INTERFACE:
+ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ !
+ ! F.-M. YUAN: the water fluxes in CLM4.5 are separately calculated in a few subroutines
+ ! in 'SoilHydrologyMod.F90'. When coupled with pflotran, it's hard to get those together
+ ! like GB does in 'step_th_clm_pf' subroutine. So, this subroutine is a collective call of
+ ! that and others in 'Hydrology2Mod.F90' so that pflotran can be called out of 'hydrology2'.
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_varcon , only : tfrz, denh2o
+ use clm_varpar , only : nlevsoi, nlevgrnd
+ use clm_time_manager, only : get_step_size, get_nstep
+ use shr_infnan_mod , only : shr_infnan_isnan
+ use shr_const_mod , only : SHR_CONST_G
+
+ use clm_pflotran_interface_data
+ use clm_varctl , only : pf_clmnstep0
+
+ ! !ARGUMENTS:
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(inout) :: filters(:) ! filters on current process
+ integer, intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, g, c, j ! do loop indices
+ integer :: gcount, cellcount
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: nstep ! time step number
+ real(r8) :: area
+ real(r8) :: qflx_evap(bounds%begc:bounds%endc) ! weighted soil surface evaporation (mmH2O/s)
+ real(r8) :: qflx, qflx_sink, qflx_source, soilvwc
+ real(r8) :: dsoilliq1 = 0._r8, dsoilliq2 = 0._r8, dsoilliq3 = 0._r8
+
+ real(r8) :: qflx_ground, kbot
+ real(r8) :: reference_pressure, ponding_pressure ! Pa
+ real(r8) :: pondmax(bounds%begc:bounds%endc) ! mm H2O: max. ponding depth for column
+ real(r8) :: sr = 0.10_r8
+ real(r8) :: tempreal, reductor
+
+ ! for PF --> CLM (seq.)
+ PetscScalar, pointer :: press_clms_loc(:) !
+ PetscScalar, pointer :: soillsat_clms_loc(:) !
+ PetscScalar, pointer :: soilisat_clms_loc(:) !
+ PetscScalar, pointer :: porosity_clms_loc(:) !
+ PetscScalar, pointer :: sr_pcwmax_clms_loc(:) !
+
+ PetscScalar, pointer :: area_clms_loc(:) !
+
+ ! for CLM (mpi) --> PF
+ PetscScalar, pointer :: qflw_clmp_loc(:) ! source/sink term for plant Transpiration: unit in mass rate (kgH2O/sec)
+ PetscScalar, pointer :: qflwt_clmp_loc(:) ! temperature of source/sink term for plant Transpiration: oC (ET water temperature for thermal contact with soil)
+ PetscScalar, pointer :: press_top_clmp_loc(:) ! BC in pressure type: unit in Pa
+ PetscScalar, pointer :: press_base_clmp_loc(:) !
+ PetscScalar, pointer :: qfluxw_top_clmp_loc(:) ! BC in neumann flux type: unit in m/s (liq.)
+ PetscScalar, pointer :: qfluxev_top_clmp_loc(:) ! BC in neumann flux type: unit in m/s (evaporation)
+ PetscScalar, pointer :: qfluxw_base_clmp_loc(:) ! BC in neumann flux type: unit in m/s (liq.)
+ PetscScalar, pointer :: press_maxponding_clmp_loc(:) !
+ PetscErrorCode :: ierr
+
+ character(len= 32) :: subname = 'get_clm_bcwflx' ! subroutine name
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ cwtgcell => col_pp%wtgcell , & ! weight (relative to gridcell)
+ dz => col_pp%dz , & ! layer thickness depth (m)
+ !
+ bsw => clm_interface_data%bsw_col , &! Clapp and Hornberger "b" (nlevgrnd)
+ hksat => clm_interface_data%hksat_col , &! hydraulic conductivity at saturation (mm H2O /s) (nlevgrnd)
+ watsat => clm_interface_data%watsat_col , &! volumetric soil water at saturation (porosity) (nlevgrnd)
+ sucsat => clm_interface_data%sucsat_col , &! minimum soil suction (mm) (nlevgrnd)
+ watmin => clm_interface_data%watmin_col , &! restriction for min of volumetric soil water, or, residual vwc (-) (nlevgrnd)
+ sucmin => clm_interface_data%sucmin_col , &! restriction for min of soil potential (mm) (nlevgrnd)
+ !
+ frac_sno_eff => clm_interface_data%th%frac_sno_eff_col , &! [real(r8) (:) ] fraction of ground covered by snow (0 to 1)
+ frac_h2osfc => clm_interface_data%th%frac_h2osfc_col , &! [real(r8) (:) ] fraction of ground covered by surface water (0 to 1)
+ t_soisno => clm_interface_data%th%t_soisno_col , &! [real(r8) (:,:) ] snow-soil layered temperature [K]
+ t_grnd => clm_interface_data%th%t_grnd_col , &! [real(r8) (:) ] col ground(-air interface averaged) temperature (Kelvin)
+ t_nearsurf => clm_interface_data%th%t_nearsurf_col , &! [real(r8) (:) ] col mixed air/veg. temperature near surface (for coupling with PFLOTRAN as BC)
+ qflx_top_soil => clm_interface_data%th%qflx_top_soil_col , &! [real(r8) (:) ] column-level net liq. water input into soil from top (mm/s)
+ qflx_evap_h2osfc => clm_interface_data%th%qflx_evap_h2osfc_col , &! [real(r8) (:) ] column-level p-aggregated evaporation flux from h2osfc (mm H2O/s) [+ to atm]
+ qflx_evap_soil => clm_interface_data%th%qflx_evap_soil_col , &! [real(r8) (:) ] column-level p-aggregated evaporation flux from soil (mm H2O/s) [+ to atm]
+ qflx_evap_snow => clm_interface_data%th%qflx_evap_snow_col , &! [real(r8) (:) ] column-level p-aggregated evaporation (inc. subl.) flux from snow (mm H2O/s) [+ to atm]
+ qflx_rootsoil => clm_interface_data%th%qflx_rootsoil_col , &! [real(r8) (:,:) ] column-level p-aggregated vertically-resolved vegetation/soil water exchange (m H2O/s) (+ = to atm)
+ h2osoi_liq => clm_interface_data%th%h2osoi_liq_col , &! [real(r8) (:,:) ] liquid water (kg/m2)
+ h2osoi_ice => clm_interface_data%th%h2osoi_ice_col &! [real(r8) (:,:) ] ice lens (kg/m2)
+ )
+
+!----------------------------------------------------------------------------
+ nstep = get_nstep()
+ dtime = get_step_size()
+
+ ! (1) pass the clm_qflx to the vecs
+ ! NOTE the following unit conversions:
+ ! qflx_soil_top and qflx_tran_veg are in [mm/sec] from CLM;
+ ! qflx_clm_loc is in [kgH2O/sec] as mass rate for pflotran (as input)
+
+ ! previous time-step soil water pressure and saturation for adjusting qflx
+ ! note that this is a temporary workaround - waiting for PF's solution
+ call VecGetArrayF90(clm_pf_idata%press_clms, press_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soillsat_clms, soillsat_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%soilisat_clms, soilisat_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%effporosity_clms, porosity_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%sr_pcwmax_clms, sr_pcwmax_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%qflow_clmp, qflw_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%qflowt_clmp, qflwt_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%press_subsurf_clmp, press_top_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%press_subbase_clmp, press_base_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%qfluxw_subsurf_clmp, qfluxw_top_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%qfluxev_subsurf_clmp, qfluxev_top_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%qfluxw_subbase_clmp, qfluxw_base_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%press_maxponding_clmp, press_maxponding_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+
+ if (t_grnd(c) < tfrz .and. qflx_evap_soil(c)<0._r8) then
+ ! frozen ground, no dew contribution to subsurface infiltration (will likely cause trouble in PFLOTRAN)
+ ! (NOTE: this will modify 'qflx_evap_soil' globally)
+ qflx_evap_soil (c) = 0._r8
+ endif
+ ! bare-soil fraction-weighted col-level evaporation (this is the actual water by EV from the whole 1st soil layer)
+ qflx_evap(c)=(1.0_r8 - frac_sno_eff(c) - frac_h2osfc(c))*qflx_evap_soil(c)
+
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+ if(j<=nlevgrnd) then
+
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j
+
+ qflw_clmp_loc(cellcount ) = 0.0_r8
+ qflwt_clmp_loc(cellcount ) = t_nearsurf(gcount+1) - tfrz
+
+ if (j .eq. 1) then
+ qfluxw_top_clmp_loc(gcount+1) = 0.0_r8
+ qfluxev_top_clmp_loc(gcount+1) = 0.0_r8
+ press_top_clmp_loc(gcount+1) = press_clms_loc(cellcount) ! same as the first top layer
+ end if
+
+ if (j .eq. clm_pf_idata%nzclm_mapped) then
+ qfluxw_base_clmp_loc(gcount+1) = 0.0_r8
+ press_base_clmp_loc(gcount+1) = press_clms_loc((gcount+1)*clm_pf_idata%nzclm_mapped) ! same as the bottom layer
+ end if
+
+ else
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+
+ endif
+ end do
+
+ end do
+
+ pondmax(:) = 0.0_r8 ! this is temporarily set (not yet figure out how CLM get this value)
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ area = area_clms_loc(gcount*clm_pf_idata%nzclm_mapped+1)
+ reference_pressure = clm_pf_idata%pressure_reference
+ ponding_pressure = pondmax(c)*SHR_CONST_G ! max. ponding water depth (mm) ==> pressure (Pa)
+
+ press_maxponding_clmp_loc(gcount+1) = reference_pressure+ponding_pressure
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+
+ if (j<=nlevgrnd) then
+
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j
+
+ ! CLM soil hydrology ONLY works down to 'nlevsoi' (one exception for 'vwc_zwt' when tnlevsoi) cycle ! comment out so that it can be down to 'nlevgrnd', although NOT really now.
+
+ ! previous time-step soil water saturation for adjusting qflx to avoid too wet or too dry to cause PF math issue
+ ! (this is a temporary workaround - waiting for PF's solution)
+ soilvwc = soillsat_clms_loc(cellcount) * &
+ porosity_clms_loc(cellcount) ! PF saturation ==> real vwc (using adjusted porosity???)
+
+ dsoilliq1 = (0.99_r8*porosity_clms_loc(cellcount)-soilvwc) &
+ *dz(c,j)*area*denh2o/dtime ! mH2O ==> kgH2O/sec to be filled at most (1% for hard-accessible pore and error-handling )
+ dsoilliq1 = max(0._r8, dsoilliq1) ! always +
+
+ sr = 1.01_r8*sr_pcwmax_clms_loc(cellcount) * & ! '1.01' will give 1% for hard-accessible pore and holding error in the calculation
+ porosity_clms_loc(cellcount) ! PF saturation ==> 'real' vwc
+ dsoilliq2 = (sr-soilvwc)*dz(c,j)*area*denh2o/dtime ! mH2O ==> kgH2O/sec to be extracted at most (-)
+ dsoilliq2 = min(0._r8, dsoilliq2) ! always -
+
+ ! top BC
+ if (j .eq. 1) then
+
+ ! mmH2O/sec ==> mH2O/sec of soil evaporation as top BC (neumann): negative to soil
+ if (.not.shr_infnan_isnan(qflx_evap(c))) then
+ ! it's better to limit 'qflx_evap' (but not if dew formation),
+ ! although causes water/energy-balance errors which should be accounted for later on (NOT YET - TODO!)
+ reductor = 1.0_r8
+ if( qflx_evap(c)>0._r8) then
+ reductor = min(qflx_evap(c), max(0._r8,-dsoilliq2/denh2o/area*1.e3))
+ reductor = reductor/qflx_evap(c)
+
+ ! frozen condition evaporation has issue, temperarily OFF (TODO - further thought needed)
+ if (t_soisno(c,1) mH2O/sec, - = out of soil
+ endif
+
+ ! net liq water input/output to soil column
+ ! mmH2O/sec ==> mH2O/sec of potential infiltration (flux) rate as top BC (neumann): positive to soil
+ qflx_ground = 0._r8
+ if (.not.shr_infnan_isnan(qflx_top_soil(c))) then
+
+ qflx_ground = qflx_top_soil(c) ! unit: mm/sec
+
+ if(qflx_ground>0._r8 ) then
+ if (t_soisno(c,1)=0.95_r8 .and. &
+ (soillsat_clms_loc(cellcount)+soilisat_clms_loc(cellcount)) >= 0.9999_r8) then ! ice-blocked first-layer
+ qflx_ground = 0._r8
+ endif
+
+ qfluxw_top_clmp_loc(gcount+1) = qflx_ground*1.e-3 ! mm/sec --> kg/m2/sec
+ endif
+ endif
+
+ ! if net input potential, it's forming TOP BC of pressure type (water ponding potetial)
+ ! both waterhead and flux calcuated here, but not applied in PFLOTRAN in the same time (upon BC type picked-up by PF)
+ if ( qflx_ground .gt. 0._r8) then
+ ! Newly ADDED mmH2O ==> pressure (Pa) as top BC (dirichlet) by forming a layer of surface water column
+ ! AND, the actual infiltration/runoff are retrieving from PFLOTRAN using 'update_surflow_pf2clm' subroutine
+ if (soillsat_clms_loc(cellcount) >= 1._r8) then
+ ! water-head formed on saturated below-ground soil layer
+ press_top_clmp_loc(gcount+1) = press_clms_loc(gcount*clm_pf_idata%nzclm_mapped+1) + &
+ qflx_ground*dtime*SHR_CONST_G
+ else
+ ! ground-water-head discontinued from below-ground (atm. pressure applied at both ends)
+ press_top_clmp_loc(gcount+1) = reference_pressure + &
+ qflx_ground*dtime*SHR_CONST_G
+ endif
+
+ end if
+
+ end if
+
+ ! plant root extraction of water (transpiration: negative to soil)
+ ! mmH2O/sec ==> kgH2O/sec of source rate
+ qflx = -qflx_rootsoil(c,j)*area*1.e-3*denh2o
+ qflx = qflx * cwtgcell(c) ! clm column fraction of grid-cell adjustment
+
+ ! checking if over-filled when sinking (excluding infiltration)
+ qflx_sink = max(0._r8, qflx) ! sink (+) only (kgH2O/sec)
+ qflx_sink = min(qflx_sink, max(0._r8,dsoilliq1))
+
+ ! checking if too dry to be ETed (or other sourced): lower than 'sr_pcwmax'
+ qflx_source = min(0._r8, qflx) ! source (-) only (kgH2O/sec)
+ qflx_source = max(qflx_source, min(0._r8,dsoilliq2))
+
+ qflw_clmp_loc(cellcount) = (qflx_sink+qflx_source)/area/dz(c,j) ! source/sink unit: kg/m3/sec
+ qflwt_clmp_loc(cellcount)= t_soisno(c,j) - tfrz !
+
+ ! bottom BC (neumman type): m/sec
+ if (j .eq. clm_pf_idata%nzclm_mapped) then
+ ! available water flux-out rate (-) adjusted by source(-)/sink(+) term
+ dsoilliq3 = min(0._r8, dsoilliq2 - qflw_clmp_loc(cellcount)) &
+ /area/denh2o ! kgH2O/sec ==> mH2O/sec
+
+ ! free drainage at bottom
+ tempreal = soilvwc/watsat(c,j) ! using 'real' saturation
+ kbot = hksat(c,j)*(tempreal**(2._r8*bsw(c,j)+3._r8))*1.e-3 ! mmH2O/sec ==> mH2O/sec
+ qfluxw_base_clmp_loc(gcount+1) = max(dsoilliq3, -kbot) ! mH2O/sec
+
+ end if
+
+ else !j>clm_varpar%nlevgrnd
+ call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // &
+ " 'clm_varpar%nlevgrnd'. Please check")
+ endif
+
+ end do
+
+ end do
+
+ call VecRestoreArrayF90(clm_pf_idata%press_clms, press_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soillsat_clms, soillsat_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%soilisat_clms, soilisat_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%sr_pcwmax_clms, sr_pcwmax_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%effporosity_clms, porosity_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%qflow_clmp, qflw_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%qflowt_clmp, qflwt_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%press_subsurf_clmp, press_top_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%press_subbase_clmp, press_base_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%qfluxw_subsurf_clmp, qfluxw_top_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%qfluxev_subsurf_clmp, qfluxev_top_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%qfluxw_subbase_clmp, qfluxw_base_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%press_maxponding_clmp, press_maxponding_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine get_clm_bcwflx
+
+ !-----------------------------------------------------------------------------
+ !
+ !
+ ! !INTERFACE:
+ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ !
+ ! F.-M. YUAN: the boundary heat fluxes in CLM4.5 are extracted to drive pflotran TH mode.
+ ! GB only defined ground-heaf-flux.
+ ! So, this subroutine is a collective setting on either heat-flux (neumann type)
+ ! or interface thermal state (temperature) (dirichlet type)
+ ! at both ground and bottom interface (BC).
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_time_manager, only : get_step_size, get_nstep
+ use clm_varcon , only : tfrz
+ use clm_varpar , only : nlevgrnd
+ use shr_infnan_mod , only : shr_infnan_isnan
+
+ use clm_pflotran_interface_data
+ use clm_varctl , only : pf_clmnstep0
+
+ ! !ARGUMENTS:
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+ integer, intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, g, gcount ! do loop indices
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: nstep ! time step number
+ real(r8) :: t_grnd0, eflx_fgr0, eflx_ev0, eflx_rnet0
+ real(r8) :: area
+
+ ! for CLM (mpi) --> PF
+ PetscScalar, pointer :: geflx_subsurf_clmp_loc(:) ! all-form energy flux: unit MJ/m2/s
+ PetscScalar, pointer :: geflxr_subsurf_clmp_loc(:) ! radiation energy flux: unit MJ/m2/s
+ PetscScalar, pointer :: geflxl_subsurf_clmp_loc(:) ! soil evap. LE flux: unit MJ/m2/s
+ PetscScalar, pointer :: gtemp_subsurf_clmp_loc(:) ! BC in dirichlet type: unit in degC
+ PetscScalar, pointer :: geflx_subbase_clmp_loc(:) ! all-form energy flux: unit MJ/m2/s
+ PetscScalar, pointer :: gtemp_subbase_clmp_loc(:) ! BC in dirichlet type: unit in degC
+
+ PetscScalar, Pointer :: area_clms_loc(:)
+
+ PetscErrorCode :: ierr
+
+ character(len= 32) :: subname = 'get_clm_bceflx' ! subroutine name
+
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , &! column's gridcell
+ dz => col_pp%dz , &! layer thickness depth (m)
+ snl => col_pp%snl , &! number of snow layers (negative)
+ !
+ frac_sno_eff => clm_interface_data%th%frac_sno_eff_col , &! fraction of ground covered by snow (0 to 1)
+ frac_h2osfc => clm_interface_data%th%frac_h2osfc_col , &! fraction of ground covered by surface water (0 to 1)
+ !
+ htvp => clm_interface_data%th%htvp_col , &! latent heat of vapor of water (or sublimation) [j/kg]
+ eflx_fgr0_snow => clm_interface_data%th%eflx_fgr0_snow_col , &! heat flux from snow column (W/m**2) [+ = into soil]
+ eflx_fgr0_h2osfc => clm_interface_data%th%eflx_fgr0_h2osfc_col , &! heat flux from surface water column (W/m**2) [+ = into soil]
+ eflx_fgr0_soil => clm_interface_data%th%eflx_fgr0_soil_col , &! heat flux from near-surface air (W/m**2) [+ = into soil]
+ eflx_rnet_soil => clm_interface_data%th%eflx_rnet_soil_col , &! heat flux between soil layer 1 and above-air, excluding SH and LE (i.e. radiation form) (W/m2) [+ = into soil]
+ eflx_bot => clm_interface_data%th%eflx_bot_col , &! heat flux from beneath column (W/m**2) [+ = upward]
+ t_soisno => clm_interface_data%th%t_soisno_col , &! snow-soil layered temperature [K]
+ t_h2osfc => clm_interface_data%th%t_h2osfc_col , &! surface-water temperature [K]
+ t_nearsurf => clm_interface_data%th%t_nearsurf_col , &! mixed air/veg. temperature near surface (for coupling with PFLOTRAN as BC)
+ qflx_evap_soil => clm_interface_data%th%qflx_evap_soil_col &! non-urban column-level p-aggregated evaporation flux from soil (mm H2O/s) [+ to atm]
+ )
+
+!----------------------------------------------------------------------------
+ nstep = get_nstep()
+ dtime = get_step_size()
+
+ ! (1) pass the clm_gflux/gtemp to the vec
+
+ call VecGetArrayF90(clm_pf_idata%eflux_subsurf_clmp, geflx_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%efluxr_subsurf_clmp, geflxr_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%efluxl_subsurf_clmp, geflxl_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%eflux_subbase_clmp, geflx_subbase_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%gtemp_subsurf_clmp, gtemp_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%gtemp_subbase_clmp, gtemp_subbase_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ geflx_subsurf_clmp_loc(:) = 0._r8
+ geflxr_subsurf_clmp_loc(:) = 0._r8
+ geflxl_subsurf_clmp_loc(:) = 0._r8
+ geflx_subbase_clmp_loc(:) = 0._r8
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ area = area_clms_loc(gcount*clm_pf_idata%nzclm_mapped+1)
+
+ ! (1) Dirichlet-Type BC for energy
+ ! near-surface/subsurface interface temperature
+ ! NOTE that this is not exactly ground temperature from CLM, which is for air/ground (snow/surfwater-1st soil) interface
+
+ if (snl(c) < 0) then
+ if(frac_h2osfc(c) /= 0._r8) then
+ t_grnd0 = frac_sno_eff(c) * t_soisno(c,0) & ! a note here: 't_soisno(c,0)' NOT always has a meanful value
+ + (1.0_r8 - frac_sno_eff(c) - frac_h2osfc(c)) * t_nearsurf(c) &
+ + frac_h2osfc(c) * t_h2osfc(c) ! a note here: 't_h2osfc' NOT always has a meanful value
+ else
+ t_grnd0 = frac_sno_eff(c) * t_soisno(c,0) &
+ + (1.0_r8 - frac_sno_eff(c)) * t_nearsurf(c)
+
+ endif
+ else
+ if(frac_h2osfc(c) /= 0._r8) then
+ t_grnd0 = (1.0_r8 - frac_h2osfc(c)) * t_nearsurf(c) &
+ + frac_h2osfc(c) * t_h2osfc(c)
+ else
+ t_grnd0 = t_nearsurf(c)
+ endif
+ endif
+
+ gtemp_subsurf_clmp_loc(gcount+1) = t_grnd0 - tfrz
+ gtemp_subbase_clmp_loc(gcount+1) = -9999 ! not yet get it from CLM (i.e.,dirichlet type bottom BC not available)
+
+ ! (2) Neumann-Type BC for energy
+ ! THREE (3) types: radiation flux, latent heat flux, and sensible heat flux
+
+ ! net (sw+lw) radiation into soil, if not covered by surface water or snow
+ eflx_rnet0 = (1.0_r8 - frac_sno_eff(c) - frac_h2osfc(c))*eflx_rnet_soil(c)
+
+ ! soil surface evaporation (NOTE which adjusted by liq. water available in the first soil layer in 'get_clm_wflx' subroutine)
+ eflx_ev0 = -qflx_evap_soil(c)*htvp(c)*(1.0_r8 - frac_sno_eff(c) - frac_h2osfc(c)) ! - = LE out of soil
+
+ ! net heat flux into soil
+ eflx_fgr0 = (1.0_r8 - frac_sno_eff(c) - frac_h2osfc(c))*eflx_fgr0_soil(c)
+
+ ! if snow/surface-water covered, need to add snow/water-soil interface heat flux
+ ! (in this case, no radiation/soil-evap)
+ if(snl(c) < 0) then
+ eflx_fgr0 = eflx_fgr0 + frac_sno_eff(c)*eflx_fgr0_snow(c)
+ endif
+ if(frac_h2osfc(c)>0._r8) then
+ eflx_fgr0 = eflx_fgr0 + frac_h2osfc(c)*eflx_fgr0_h2osfc(c)
+ endif
+
+ ! for heat flux boundry only (i.e. NO thermal-state boundary or LE flux BC)
+ if (.not.shr_infnan_isnan(eflx_fgr0)) & ! when initializing, it's a NAN
+ geflx_subsurf_clmp_loc(gcount+1) = eflx_fgr0*1.0e-6_r8 ! positive = into soil, unit: MJ/m2/sec
+
+ ! if thermal-state boundary (i.e. dirichlet-type, temperature)
+ ! it must include non-heat-conductance energy fluxes, such as radiation and LE, which usually occurs if not covered by snow or h2osfc.
+ if (.not.shr_infnan_isnan(eflx_ev0)) &
+ geflxl_subsurf_clmp_loc(gcount+1) = eflx_ev0*1.0e-6_r8 ! positive = into soil, unit: MJ/m2/sec
+
+ if (.not.shr_infnan_isnan(eflx_rnet0)) &
+ geflxr_subsurf_clmp_loc(gcount+1) = eflx_rnet0*1.0e-6_r8 ! positive = into soil, unit: MJ/m2/sec
+
+ if (.not.shr_infnan_isnan(eflx_bot(c))) &
+ geflx_subbase_clmp_loc(gcount+1) = eflx_bot(c)*1.0e-6_r8 ! positive = into soil
+
+ end do
+
+ call VecRestoreArrayF90(clm_pf_idata%eflux_subsurf_clmp, geflx_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%efluxr_subsurf_clmp, geflxr_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%efluxl_subsurf_clmp, geflxl_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%eflux_subbase_clmp, geflx_subbase_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%gtemp_subsurf_clmp, gtemp_subsurf_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%gtemp_subbase_clmp, gtemp_subbase_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine get_clm_bceflx
+
+ !
+ !-----------------------------------------------------------------------------
+ !
+ !
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !ROUTINE: get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !INTERFACE:
+
+ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter)
+ use ColumnType , only : col_pp
+ use clm_varctl , only : iulog
+ use clm_varpar , only : ndecomp_pools, nlevdecomp_full
+
+ implicit none
+
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ character(len=256) :: subname = "get_clm_bgc_concentration"
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ ! Local variables
+ integer :: fc, c, g, j, k ! do loop indices
+ integer :: gcount, cellcount
+ real(r8) :: CN_ratio_mass_to_mol
+
+ integer :: vec_offset
+ PetscScalar, pointer :: decomp_cpools_vr_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ PetscScalar, pointer :: decomp_npools_vr_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+! PetscScalar, pointer :: decomp_ppools_vr_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) P pools
+
+ PetscScalar, pointer :: smin_no3_vr_clm_loc(:) ! (gN/m3) vertically-resolved soil mineral NO3
+ PetscScalar, pointer :: smin_nh4_vr_clm_loc(:) ! (gN/m3) vertically-resolved soil mineral NH4
+ PetscScalar, pointer :: smin_nh4sorb_vr_clm_loc(:) ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
+
+ PetscErrorCode :: ierr
+ !
+ !------------------------------------------------------------------------------------------
+ !
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ !
+ initial_cn_ratio => clm_interface_data%bgc%initial_cn_ratio , &
+ initial_cp_ratio => clm_interface_data%bgc%initial_cp_ratio , &
+
+ decomp_cpools_vr => clm_interface_data%bgc%decomp_cpools_vr_col , & ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ decomp_npools_vr => clm_interface_data%bgc%decomp_npools_vr_col , & ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+ smin_no3_vr => clm_interface_data%bgc%smin_no3_vr_col , & ! (gN/m3) vertically-resolved soil mineral NO3
+ smin_nh4_vr => clm_interface_data%bgc%smin_nh4_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4
+ smin_nh4sorb_vr => clm_interface_data%bgc%smin_nh4sorb_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
+
+ decomp_ppools_vr => clm_interface_data%bgc%decomp_ppools_vr_col , & ! [real(r8) (:,:,:) ! col (gP/m3) vertically-resolved decomposing (litter, cwd, soil) P pools
+ solutionp_vr => clm_interface_data%bgc%solutionp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil solution P
+ labilep_vr => clm_interface_data%bgc%labilep_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil labile mineral P
+ secondp_vr => clm_interface_data%bgc%secondp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil secondary mineralP
+ occlp_vr => clm_interface_data%bgc%occlp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil occluded mineral P
+ primp_vr => clm_interface_data%bgc%primp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil primary mineral P
+ sminp_vr => clm_interface_data%bgc%sminp_vr_col & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil mineral P = solutionp + labilep + secondp
+ )
+
+ call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ CN_ratio_mass_to_mol = clm_pf_idata%N_molecular_weight/clm_pf_idata%C_molecular_weight
+
+ !
+ decomp_cpools_vr_clm_loc(:) = 0._r8
+ decomp_npools_vr_clm_loc(:) = 0._r8
+ smin_no3_vr_clm_loc(:) = 0._r8
+ smin_nh4_vr_clm_loc(:) = 0._r8
+ smin_nh4sorb_vr_clm_loc(:) = 0._r8
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ ! note: all clm-pf soil layers are 'clm_pf_idata%nzclm_mapped' for both TH/BGC,
+ ! but in CLM, T is within 'nlevgrnd', H is within 'nlevsoi', bgc within 'nlevdecomp'
+
+ if(j <= nlevdecomp_full) then
+
+ do k = 1, ndecomp_pools
+ vec_offset = (k-1)*clm_pf_idata%nlclm_sub ! 0-based
+ ! decomp_pool vec: 'cell' first, then 'species' (i.e. cell by cell for 1 species, then species by species)
+ ! Tips: then when doing 3-D data-mapping, no need to stride the vecs BUT to do segmentation.
+
+ decomp_cpools_vr_clm_loc(vec_offset+cellcount) = decomp_cpools_vr(c,j,k) &
+ /clm_pf_idata%C_molecular_weight
+
+ if (clm_pf_idata%floating_cn_ratio(k)) then
+ decomp_npools_vr_clm_loc(vec_offset+cellcount) = decomp_npools_vr(c,j,k) &
+ /clm_pf_idata%N_molecular_weight
+ else
+ decomp_npools_vr_clm_loc(vec_offset+cellcount) = &
+ decomp_cpools_vr_clm_loc(vec_offset+cellcount) &
+ /(initial_cn_ratio(k)*CN_ratio_mass_to_mol) ! initial_cn_ratio: in unit of mass
+ endif
+
+ enddo ! do k=1, ndecomp_pools
+
+ smin_no3_vr_clm_loc(cellcount) = smin_no3_vr(c,j) &
+ /clm_pf_idata%N_molecular_weight
+ smin_nh4_vr_clm_loc(cellcount) = smin_nh4_vr(c,j) &
+ /clm_pf_idata%N_molecular_weight
+ smin_nh4sorb_vr_clm_loc(cellcount) = smin_nh4sorb_vr(c,j) &
+ /clm_pf_idata%N_molecular_weight
+
+ endif
+
+ enddo ! do j = 1, clm_pf_idata%nzclm_mapped
+
+ enddo ! do fc = 1, num_soilc
+
+ call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine get_clm_bgc_conc
+
+ !-----------------------------------------------------------------------------
+ !
+ ! !IROUTINE: get_clm_bgc_rate()
+ !
+ ! !INTERFACE:
+ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter)
+! TODO: add phosphorus vars
+ !
+ ! !DESCRIPTION:
+ !
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_time_manager , only : get_step_size, get_nstep, is_first_step, is_first_restart_step
+ use clm_varpar , only : ndecomp_pools, nlevdecomp_full
+ use clm_varctl , only : iulog, pf_hmode
+
+ ! !ARGUMENTS:
+ implicit none
+
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ character(len=256) :: subname = "get_clm_bgc_rate"
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, g, j, k ! do loop indices
+ integer :: gcount, cellcount
+
+ real(r8) :: dtime ! land model time step (sec)
+
+ ! C/N source/sink rates as inputs for pflotran: Units - moles/m3/s (note: do unit conversion here for input rates)
+ integer :: vec_offset
+ PetscScalar, pointer :: rate_decomp_c_clm_loc(:) !
+ PetscScalar, pointer :: rate_decomp_n_clm_loc(:) !
+! PetscScalar, pointer :: rate_decomp_p_clm_loc(:) !
+
+ PetscScalar, pointer :: kscalar_decomp_c_clm_loc(:) !
+
+ PetscScalar, pointer :: rate_plantndemand_clm_loc(:) !
+ PetscScalar, pointer :: rate_smin_no3_clm_loc(:) !
+ PetscScalar, pointer :: rate_smin_nh4_clm_loc(:) !
+
+ PetscErrorCode :: ierr
+
+ !
+ !---------------------------------------------------------------------------
+ !
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ !
+ decomp_cpools_vr => clm_interface_data%bgc%decomp_cpools_vr_col , & ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ decomp_npools_vr => clm_interface_data%bgc%decomp_npools_vr_col , & ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+ decomp_k_scalar_vr => clm_interface_data%bgc%sitefactor_kd_vr_col , & ! (-) vertically-resolved decomposing rate adjusting factor relevant to location (site)
+ smin_no3_vr => clm_interface_data%bgc%smin_no3_vr_col , & ! (gN/m3) vertically-resolved soil mineral NO3
+ smin_nh4_vr => clm_interface_data%bgc%smin_nh4_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4
+ smin_nh4sorb_vr => clm_interface_data%bgc%smin_nh4sorb_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
+ ! plant litering and removal + SOM/LIT vertical transport
+ col_net_to_decomp_cpools_vr => clm_interface_data%bgc%externalc_to_decomp_cpools_col , &
+ col_net_to_decomp_npools_vr => clm_interface_data%bgc%externaln_to_decomp_npools_col , &
+ ! inorg. nitrogen sink potential
+ col_plant_ndemand_vr => clm_interface_data%bgc%plant_ndemand_vr_col , &
+ ! inorg. N source/sink
+ externaln_to_nh4_vr => clm_interface_data%bgc%externaln_to_nh4_col , &
+ externaln_to_no3_vr => clm_interface_data%bgc%externaln_to_no3_col , &
+
+ col_net_to_decomp_ppools_vr => clm_interface_data%bgc%externalp_to_decomp_ppools_col , &
+ externalp_to_primp_vr => clm_interface_data%bgc%externalp_to_primp_col , &
+ externalp_to_labilep_vr => clm_interface_data%bgc%externalp_to_labilep_col , &
+ externalp_to_solutionp => clm_interface_data%bgc%externalp_to_solutionp_col , &
+ sminp_net_transport_vr => clm_interface_data%bgc%sminp_net_transport_vr_col , &
+ col_plant_pdemand_vr => clm_interface_data%bgc%plant_pdemand_vr_col &
+ )
+
+ dtime = get_step_size()
+
+
+ call VecGetArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%kscalar_decomp_c_clmp, kscalar_decomp_c_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! Initialize to ZERO
+
+ rate_decomp_c_clm_loc(:) = 0.0_r8
+ rate_decomp_n_clm_loc(:) = 0.0_r8
+
+ rate_smin_no3_clm_loc(:) = 0.0_r8
+ rate_smin_nh4_clm_loc(:) = 0.0_r8
+ rate_plantndemand_clm_loc(:) = 0.0_r8
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ ! note: all clm-pf soil layers are 'clm_pf_idata%nzclm_mapped' for both TH/BGC,
+ ! but in CLM, T is within 'nlevgrnd', H is within 'nlevsoi', bgc within 'nlevdecomp'
+ ! (nlevdecomp_full = nlevgrnd)
+
+ if(j <= nlevdecomp_full) then
+ ! just in case, we need to do some checking first (actually already done before)
+ do k = 1,ndecomp_pools
+ if (col_net_to_decomp_cpools_vr(c,j,k) < 0._r8) then
+ col_net_to_decomp_cpools_vr(c,j,k) = &
+ max(col_net_to_decomp_cpools_vr(c,j,k), &
+ -max(decomp_cpools_vr(c,j,k)/dtime, 0._r8))
+ endif
+
+ if (col_net_to_decomp_npools_vr(c,j,k) < 0._r8) then
+ col_net_to_decomp_npools_vr(c,j,k) = &
+ max(col_net_to_decomp_npools_vr(c,j,k), &
+ -max(decomp_npools_vr(c,j,k)/dtime, 0._r8))
+ endif
+ end do
+
+ do k = 1, ndecomp_pools
+ vec_offset = (k-1)*clm_pf_idata%nlclm_sub ! 0-based
+ ! decomp_pool vec: 'cell' first, then 'species' (i.e. cell by cell for 1 species, then species by species)
+ ! Tips: then when doing 3-D data-mapping, no need to stride the vecs BUT to do segmentation.
+
+ rate_decomp_c_clm_loc(vec_offset+cellcount) = &
+ col_net_to_decomp_cpools_vr(c,j,k) &
+ /clm_pf_idata%C_molecular_weight
+
+ if (rate_decomp_c_clm_loc(vec_offset+cellcount)<0._r8) then
+ rate_decomp_c_clm_loc(vec_offset+cellcount) = max( &
+ rate_decomp_c_clm_loc(vec_offset+cellcount), &
+ -max(decomp_cpools_vr(c,j,k)/clm_pf_idata%C_molecular_weight/dtime, 0._r8))
+ endif
+
+ if (clm_pf_idata%floating_cn_ratio(k)) then
+ rate_decomp_n_clm_loc(vec_offset+cellcount) = &
+ col_net_to_decomp_npools_vr(c,j,k) &
+ /clm_pf_idata%N_molecular_weight
+
+ if (rate_decomp_n_clm_loc(vec_offset+cellcount)<0._r8) then
+ rate_decomp_n_clm_loc(vec_offset+cellcount) = max( &
+ rate_decomp_n_clm_loc(vec_offset+cellcount), &
+ -max(decomp_npools_vr(c,j,k)/clm_pf_idata%N_molecular_weight/dtime, 0._r8))
+ endif
+
+ endif
+
+ enddo ! do k=1, ndecomp_pools
+
+ ! site-scalar to adjust decomposition rate constants
+ ! note: (1) this only works for CTC, together with adspinup_factor(k)>1
+ ! (2) coding here is because of its time (year)-dependent, which implies checking each time-step
+ kscalar_decomp_c_clm_loc(cellcount) = decomp_k_scalar_vr(c,j)
+
+ rate_smin_nh4_clm_loc(cellcount) = externaln_to_nh4_vr(c,j)/ &
+ clm_pf_idata%N_molecular_weight
+ if (rate_smin_nh4_clm_loc(cellcount)<0._r8) then
+ rate_smin_nh4_clm_loc(cellcount) = max( &
+ rate_smin_nh4_clm_loc(cellcount), &
+ -max(smin_nh4_vr(c,j)/clm_pf_idata%N_molecular_weight/dtime, 0._r8))
+ endif
+
+ rate_smin_no3_clm_loc(cellcount) = externaln_to_no3_vr(c,j)/ &
+ clm_pf_idata%N_molecular_weight
+ if (rate_smin_no3_clm_loc(cellcount)<0._r8) then
+ rate_smin_no3_clm_loc(cellcount) = max( &
+ rate_smin_no3_clm_loc(cellcount), &
+ -max(smin_no3_vr(c,j)/clm_pf_idata%N_molecular_weight/dtime, 0._r8))
+ endif
+
+ ! plant N uptake rate here IS the N demand (potential uptake)
+ rate_plantndemand_clm_loc(cellcount) = &
+ col_plant_ndemand_vr(c,j)/clm_pf_idata%N_molecular_weight
+
+ endif ! if (j<=nlevdecomp_full)
+
+ enddo ! do j=1, clm_pf_idata%nzclm_mapped
+
+ enddo ! do fc=1,numsoic
+
+ call VecRestoreArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%kscalar_decomp_c_clmp, kscalar_decomp_c_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecRestoreArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine get_clm_bgc_rate
+
+
+
+ !====================================================================================================
+ ! !
+ ! Subroutines to UPDATE PFLOTRAN evolving variables to CLM !
+ ! !
+ !====================================================================================================
+ !
+ ! !IROUTINE: update_soil_moisture_pf2clm
+ !
+ ! !INTERFACE:
+ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ !
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_varcon , only : denh2o, denice
+ use clm_varctl , only : pf_frzmode
+ use clm_varpar , only : nlevgrnd
+
+ ! !ARGUMENTS:
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+ integer, intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, j, g ! indices
+ integer :: cellcount, gcount
+
+ PetscScalar, pointer :: sat_ice_clm_loc(:)
+ PetscScalar, pointer :: sat_clm_loc(:)
+ PetscScalar, pointer :: effporo_clm_loc(:)
+ PetscScalar, pointer :: soilpsi_clm_loc(:)
+ PetscErrorCode :: ierr
+
+ character(len=256) :: subname = "update_soil_moisture_pf2clm"
+
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ dz => col_pp%dz , & ! layer thickness depth (m)
+ !
+ watsat => clm_interface_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd)
+ !
+ soilpsi => clm_interface_data%th%soilpsi_col , & ! soil water matric potential in each soil layer (MPa)
+ h2osoi_liq => clm_interface_data%th%h2osoi_liq_col, & ! liquid water (kg/m2)
+ h2osoi_ice => clm_interface_data%th%h2osoi_ice_col, & ! ice lens (kg/m2)
+ h2osoi_vol => clm_interface_data%th%h2osoi_vol_col & ! volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3]
+ )
+ !
+ call VecGetArrayReadF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%effporosity_clms, effporo_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%soilpsi_clms, soilpsi_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ if (pf_frzmode) then
+ call VecGetArrayReadF90(clm_pf_idata%soilisat_clms, sat_ice_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ do j = 1, nlevgrnd
+
+ if (j<=clm_pf_idata%nzclm_mapped) then
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j
+
+ h2osoi_liq(c,j) = sat_clm_loc(cellcount) * &
+ effporo_clm_loc(cellcount) * dz(c,j) * denh2o ! 'watsat_clm_loc' may be effective porosity
+ if (pf_frzmode) then
+ ! since 'effporo' may be expanding when freezing, and 'soilpsi' is actually what PF works on
+ ! it's better to use CLM's 'watsat'
+ h2osoi_liq(c,j) = sat_clm_loc(cellcount) * &
+ !effporo_clm_loc(cellcount) * dz(c,j) * denh2o
+ watsat(c,j) * dz(c,j) * denh2o
+ h2osoi_ice(c,j) = sat_ice_clm_loc(cellcount) * &
+ !effporo_clm_loc(cellcount) * dz(c,j) * denice
+ watsat(c,j) * dz(c,j) * denice
+ end if
+
+ soilpsi(c,j) = soilpsi_clm_loc(cellcount)*1.e-6_r8 ! Pa --> MPa (negative)
+
+ else
+ h2osoi_liq(c,j) = sat_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) * &
+ effporo_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) * &
+ dz(c,j) * denh2o ! 'watsat_clm_loc' may be effective porosity
+ if (pf_frzmode) then
+ h2osoi_liq(c,j) = sat_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) * &
+ !effporo_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) * dz(c,j) * denh2o ! 'watsat_clm_loc' may be effective porosity
+ watsat(c,clm_pf_idata%nzclm_mapped) * dz(c,j) * denh2o
+ h2osoi_ice(c,j) = sat_ice_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) * &
+ !effporo_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) * dz(c,j) * denice
+ watsat(c,clm_pf_idata%nzclm_mapped) * dz(c,j) * denice
+ end if
+
+ soilpsi(c,j) = soilpsi(c,clm_pf_idata%nzclm_mapped)
+ end if
+
+ h2osoi_vol(c,j) = h2osoi_liq(c,j) / dz(c,j) / denh2o + &
+ h2osoi_ice(c,j) / dz(c,j) / denice
+ h2osoi_vol(c,j) = min(h2osoi_vol(c,j), watsat(c,j))
+
+ enddo
+
+ enddo
+
+ call VecRestoreArrayReadF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%effporosity_clms, effporo_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%soilpsi_clms, soilpsi_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ if (pf_frzmode) then
+ call VecRestoreArrayReadF90(clm_pf_idata%soilisat_clms, sat_ice_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ end associate
+ end subroutine update_soil_moisture_pf2clm
+
+ !-----------------------------------------------------------------------------
+ !
+ ! !IROUTINE: update_soil_temperature_pf2clm
+ !
+ ! !INTERFACE:
+ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ !
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_varpar , only : nlevgrnd
+ use clm_varcon , only : tfrz
+
+ ! !ARGUMENTS:
+ implicit none
+
+ type(clm_interface_data_type), intent(in) :: clm_interface_data
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+ integer, intent(in) :: ifilter ! which filter to be operated
+
+ ! !LOCAL VARIABLES:
+ integer :: fc, c, j, g ! indices
+ integer :: cellcount, gcount
+ integer :: j_frz
+
+ PetscScalar, pointer :: soilt_clms_loc(:)
+ PetscErrorCode :: ierr
+
+ character(len=256) :: subname = "update_soil_temperature_pf2clm"
+
+ !EOP
+ !-----------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! column's gridcell
+ z => col_pp%z , & ! [real(r8) (:,:) ] layer depth (m)
+ !
+ t_soisno => clm_interface_data%th%t_soisno_col , & ! [real(r8)(:,:)] snow-soil temperature (Kelvin) [:, 1:nlevgrnd]
+ frost_table => clm_interface_data%th%frost_table_col & ! [real(r8)(:)] frost table depth (m)
+ )
+
+ !
+ call VecGetArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ do j = 1, nlevgrnd
+
+ if (j<=clm_pf_idata%nzclm_mapped) then
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j
+
+ t_soisno(c,j) = soilt_clms_loc(cellcount) + tfrz
+ else
+ t_soisno(c,j) = t_soisno(c, clm_pf_idata%nzclm_mapped)
+ end if
+
+ ! a simple (and temporary) checking of TH mode fake convergence
+ if(t_soisno(c,j)<173.d0) then
+ print *, 'col: ', c, 'level: ', j, t_soisno(c,j)
+ call endrun(trim(subname) // ": ERROR: PF TH mode appears NOT correct - fake convergence: " // &
+ " 't_soisno(c,j)'. STOP!")
+ endif
+
+ enddo
+
+ enddo
+
+ call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+
+ ! define frost table as first frozen layer with unfrozen layer above it
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+
+ if(t_soisno(c,1) > tfrz) then
+ j_frz = nlevgrnd
+ else
+ j_frz=1
+ endif
+
+ do j = 2, nlevgrnd
+ if (t_soisno(c,j-1) > tfrz .and. t_soisno(c,j) <= tfrz) then
+ j_frz=j
+ exit
+ endif
+ enddo
+
+ frost_table(c)=z(c,j_frz)
+ enddo
+
+
+ end associate
+ end subroutine update_soil_temperature_pf2clm
+
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !IROUTINE: update_bcflow_pf2clm
+ !
+ ! !INTERFACE:
+ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ ! update qflx_surf, qflx_infl from PF's
+ ! 'mass_balance' retrieving from PFLOTRAN
+ !
+ ! !USES:
+ use ColumnType , only : col_pp
+ use clm_varpar , only : nlevgrnd
+ use clm_varcon , only : tfrz, denh2o
+ use landunit_varcon , only : istsoil, istcrop
+ use clm_time_manager , only : get_step_size, get_nstep
+
+ !
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+ integer, intent(in) :: ifilter ! which filter to be operated
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ ! !LOCAL VARIABLES:
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ integer :: fc, c, g, gcount ! indices
+ real(r8) :: area ! top face area
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: nstep
+ real(r8) :: qflx_evap ! bare-soil surface evaporation (mmH2O/s)
+
+ PetscScalar, pointer :: area_clm_loc(:)
+ PetscScalar, pointer :: qinfl_subsurf_clm_loc(:) ! kgH2O/time-step
+ PetscScalar, pointer :: qsurf_subsurf_clm_loc(:) ! kgH2O/time-step
+ PetscScalar, pointer :: qflux_subbase_clm_loc(:) ! kgH2O/time-step
+ PetscErrorCode :: ierr
+ character(len=32) :: subname = 'update_bcflow_pf2clm' ! subroutine name
+
+ !-----------------------------------------------------------------------
+
+ associate(&
+ cgridcell => col_pp%gridcell , & ! gridcell index of column
+ !
+ frac_sno_eff => clm_interface_data%th%frac_sno_eff_col , & ! fraction of ground covered by snow (0 to 1)
+ frac_h2osfc => clm_interface_data%th%frac_h2osfc_col , & ! fraction of ground covered by surface water (0 to 1)
+ !
+ forc_pbot => clm_interface_data%th%forc_pbot_grc , & ! [real(r8) (:)] atmospheric pressure (Pa)
+ t_grnd => clm_interface_data%th%t_grnd_col , & ! [real(r8) (:)] ground surface temperature [K]
+ qflx_top_soil => clm_interface_data%th%qflx_top_soil_col , & ! [real(r8) (:)] net liq. water input into soil from top (mm/s)
+ qflx_ev_h2osfc => clm_interface_data%th%qflx_evap_h2osfc_col , & ! [real(r8) (:)] column-level evaporation flux from h2osfc (mm H2O/s) [+ to atm]
+ qflx_ev_soil => clm_interface_data%th%qflx_evap_soil_col , & ! [real(r8) (:)] column-level evaporation flux from soil (mm H2O/s) [+ to atm]
+ qflx_surf => clm_interface_data%th%qflx_surf_col , & ! [real(r8) (:)] surface runoff (mm H2O /s)
+ qflx_infl => clm_interface_data%th%qflx_infl_col , & ! [real(r8) (:)] soil infiltration (mm H2O /s)
+ qflx_drain => clm_interface_data%th%qflx_drain_col , & ! [real(r8) (:,:)] sub-surface runoff (drainage) (mm H2O /s)
+ qflx_drain_vr => clm_interface_data%th%qflx_drain_vr_col & ! [real(r8) (:)] vertically-resolved sub-surface runoff (drainage) (mm H2O /s)
+ )
+
+ dtime = get_step_size()
+ nstep = get_nstep()
+
+ ! from PF==>CLM
+ call VecGetArrayReadF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayReadF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ ! the following was actually duplicated from 'get_clm_bcwflx' to calculate total water evap from 'qflx_topsoil'
+ ! in order to get potential infiltration from CLM, because 'qflx_ev_soil' might be reduced due to water limits
+ qflx_evap = (1.0_r8 - frac_sno_eff(c) - frac_h2osfc(c))*qflx_ev_soil(c)
+ if (t_grnd(c) < tfrz .and. qflx_evap<0._r8) then
+ qflx_evap = 0._r8
+ endif
+
+ !'from PF: qinfl_subsurf_clm_loc: positive - in, negative - out
+ area = area_clm_loc(gcount*clm_pf_idata%nzclm_mapped+1)
+ qflx_infl(c) = qinfl_subsurf_clm_loc(gcount+1) &
+ /dtime/(area*denh2o*1.e-3) ! kgH2O/time-step ==> mmH2O/sec
+
+ qflx_surf(c) = qflx_top_soil(c) - qflx_infl(c) - qflx_evap
+ qflx_surf(c) = max(0._r8, qflx_surf(c))
+
+ !'from PF: qflux_subbase_clm_loc: positive - in, negative - out)
+ area = area_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) ! note: this 'area_clm_loc' is in 3-D for all subsurface domain
+ qflx_drain(c) = -qflux_subbase_clm_loc(gcount+1) &
+ /dtime/(area*denh2o*1.e-3) ! kgH2O/time-step ==> mmH2O/sec (+ drainage, - upward-in)
+
+ end do
+
+
+ call VecRestoreArrayReadF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine update_bcflow_pf2clm
+
+ !
+ !-----------------------------------------------------------------------------
+ !
+ !
+ !-----------------------------------------------------------------------------
+ ! !ROUTINE: update_soil_bgc_pf2clm()
+ !
+ ! !INTERFACE:
+ !
+ ! ! calculating BGC state variable changes over one time-step (rates)
+ ! NOTE: Don't update the organic C/N state variables, which will be updated in those 'update' subroutines
+ ! and the 'CNSoilLittVertTranspMod.F90' after 'update1'.
+ !
+ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter)
+! TODO: add phosphorus vars
+ use ColumnType , only : col_pp
+ use clm_varctl , only : iulog, use_ed
+ use CNDecompCascadeConType , only : decomp_cascade_con
+ use clm_varpar , only : ndecomp_pools, nlevdecomp_full
+ use clm_varctl , only : pf_hmode
+ use clm_time_manager , only : get_step_size,get_nstep
+
+ use clm_varcon , only : dzsoi_decomp
+
+ implicit none
+
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ character(len=256) :: subname = "update_soil_bgc_pf2clm"
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ integer :: fc,c,g,j,k,l
+ integer :: gcount, cellcount
+
+ real(r8) :: dtime ! land model time step (sec)
+
+ integer :: vec_offset
+ PetscScalar, pointer :: decomp_cpools_vr_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ PetscScalar, pointer :: decomp_npools_vr_clm_loc(:) ! (moleN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+
+ PetscScalar, pointer :: smin_no3_vr_clm_loc(:) ! (moleN/m3) vertically-resolved soil mineral NO3
+ PetscScalar, pointer :: smin_nh4_vr_clm_loc(:) ! (moleN/m3) vertically-resolved total soil mineral NH4
+ PetscScalar, pointer :: smin_nh4sorb_vr_clm_loc(:) ! (moleN/m3) vertically-resolved absorbed soil mineral NH4
+
+ ! 'accextrn_vr' - accumulative (root) extracted N, i.e., actual plant N uptake from each soil layer, within a CLM timestep
+ PetscScalar, pointer :: accextrnh4_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil mineral N root-extraction (accumulated)
+ PetscScalar, pointer :: accextrno3_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil mineral N root-extraction (accumulated)
+
+ ! 'accnmin_vr' - accumulative gross N mineralization within a CLM timestep
+ PetscScalar, pointer :: accnmin_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil N mineralization (accumulated)
+
+ ! 'accnimm_vr' - accumulative N immobilization within a CLM timestep
+ PetscScalar, pointer :: accnimmp_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil N potential immoblilization (accumulated)
+ PetscScalar, pointer :: accnimm_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil N immoblilization (accumulated)
+
+ PetscErrorCode :: ierr
+
+!------------------------------------------------------------------------------------
+ !
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
+ !
+ initial_cn_ratio => clm_interface_data%bgc%initial_cn_ratio , &
+ decomp_cpools_vr => clm_interface_data%bgc%decomp_cpools_vr_col , &
+ decomp_npools_vr => clm_interface_data%bgc%decomp_npools_vr_col , &
+ sminn_vr => clm_interface_data%bgc%sminn_vr_col , &
+ smin_no3_vr => clm_interface_data%bgc%smin_no3_vr_col , &
+ smin_nh4_vr => clm_interface_data%bgc%smin_nh4_vr_col , &
+ smin_nh4sorb_vr => clm_interface_data%bgc%smin_nh4sorb_vr_col , &
+
+ decomp_cpools_delta_vr => clm_interface_data%bgc%decomp_cpools_sourcesink_col , &
+ decomp_npools_delta_vr => clm_interface_data%bgc%decomp_npools_sourcesink_col , &
+
+ sminn_to_plant_vr => clm_interface_data%bgc%sminn_to_plant_vr_col , &
+ smin_no3_to_plant_vr => clm_interface_data%bgc%smin_no3_to_plant_vr_col , &
+ smin_nh4_to_plant_vr => clm_interface_data%bgc%smin_nh4_to_plant_vr_col , &
+ potential_immob_vr => clm_interface_data%bgc%potential_immob_vr_col , &
+ actual_immob_vr => clm_interface_data%bgc%actual_immob_vr_col , &
+ gross_nmin_vr => clm_interface_data%bgc%gross_nmin_vr_col &
+ )
+! ------------------------------------------------------------------------
+ dtime = get_step_size()
+
+ ! soil C/N pool increments set to the previous timestep (i.e., not yet updated)
+ decomp_cpools_delta_vr = 0._r8-decomp_cpools_vr
+ decomp_npools_delta_vr = 0._r8-decomp_npools_vr
+
+ ! clm-pf interface data updated
+ call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_clms, decomp_cpools_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_clms, decomp_npools_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+
+ call VecGetArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%accextrno3_vr_clms, accextrno3_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ if(clm_pf_idata%ispec_nmin>0) then
+ call VecGetArrayReadF90(clm_pf_idata%acctotnmin_vr_clms, accnmin_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecGetArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ if(clm_pf_idata%ispec_nimp>0) then
+ call VecGetArrayReadF90(clm_pf_idata%acctotnimmp_vr_clms, accnimmp_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecGetArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ if(clm_pf_idata%ispec_nimm>0) then
+ call VecGetArrayReadF90(clm_pf_idata%acctotnimm_vr_clms, accnimm_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecGetArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ do j = 1, nlevdecomp_full
+
+ gross_nmin_vr(c,j) = 0._r8
+ actual_immob_vr(c,j) = 0._r8
+ potential_immob_vr(c,j) = 0._r8
+
+ if(j <= clm_pf_idata%nzclm_mapped) then
+
+ cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based
+
+ do k=1, ndecomp_pools
+
+ vec_offset = (k-1)*clm_pf_idata%ngclm_sub ! 0-based
+ ! decomp_pool vec: 'cell' first, then 'species' (i.e. cell by cell for 1 species, then species by species)
+ ! Tips: then when doing 3-D data-mapping, no need to stride the vecs BUT to do segmentation.
+
+ decomp_cpools_delta_vr(c,j,k) = ( decomp_cpools_delta_vr(c,j,k) &
+ + decomp_cpools_vr_clm_loc(vec_offset+cellcount) &
+ * clm_pf_idata%C_molecular_weight ) !decomp_cpools_delta_vr=> clm_bgc_data%decomp_cpools_sourcesink_col
+
+ if (clm_pf_idata%floating_cn_ratio(k)) then
+ decomp_npools_delta_vr(c,j,k) = ( decomp_npools_delta_vr(c,j,k) &
+ + decomp_npools_vr_clm_loc(vec_offset+cellcount) &
+ * clm_pf_idata%N_molecular_weight ) !/dtime
+ else
+ decomp_npools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k)/ &
+ initial_cn_ratio(k) ! initial_cn_ratio: already in unit of mass
+ endif
+
+ if (abs(decomp_cpools_delta_vr(c,j,k))<=1.d-20) decomp_cpools_delta_vr(c,j,k)=0._r8
+ if (abs(decomp_npools_delta_vr(c,j,k))<=1.d-21) decomp_npools_delta_vr(c,j,k)=0._r8
+
+ !
+ if (clm_pf_idata%ispec_decomp_nmin(k)>0 .and. clm_pf_idata%ispec_nmin<=0) then
+ gross_nmin_vr(c,j) = gross_nmin_vr(c,j) &
+ + (accnmin_vr_clm_loc(vec_offset+cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ endif
+
+ !
+ if (clm_pf_idata%ispec_decomp_nimm(k)>0 .and. clm_pf_idata%ispec_nimm<=0) then
+ actual_immob_vr(c,j) = actual_immob_vr(c,j) &
+ + (accnimm_vr_clm_loc(vec_offset+cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ endif
+
+ !
+ if (clm_pf_idata%ispec_decomp_nimp(k)>0 .and. clm_pf_idata%ispec_nimp<=0) then
+ potential_immob_vr(c,j) = potential_immob_vr(c,j) &
+ + (accnimmp_vr_clm_loc(vec_offset+cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ endif
+
+ enddo ! do k=1, ndecomp_pools
+
+ if (clm_pf_idata%ispec_nmin>0) then
+ gross_nmin_vr(c,j) = gross_nmin_vr(c,j) &
+ + (accnmin_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ endif
+ if (clm_pf_idata%ispec_nimm>0) then
+ actual_immob_vr(c,j) = actual_immob_vr(c,j) &
+ + (accnimm_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ endif
+ if (clm_pf_idata%ispec_nimp>0) then
+ potential_immob_vr(c,j) = potential_immob_vr(c,j) &
+ + (accnimmp_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ endif
+
+ ! beg:--------------------------------------------------------------------------------
+ ! directly update the 'smin' N pools (SO, must bypass the 'CNNStateUpdate1,2,3' relevant to soil N)
+ smin_no3_vr(c,j) = &
+ smin_no3_vr_clm_loc(cellcount)*clm_pf_idata%N_molecular_weight
+
+ smin_nh4_vr(c,j) = &
+ smin_nh4_vr_clm_loc(cellcount)*clm_pf_idata%N_molecular_weight
+
+ smin_nh4sorb_vr(c,j) = &
+ smin_nh4sorb_vr_clm_loc(cellcount)*clm_pf_idata%N_molecular_weight
+
+ sminn_vr(c,j) = smin_no3_vr(c,j) + smin_nh4_vr(c,j) + smin_nh4sorb_vr(c,j)
+ ! end:--------------------------------------------------------------------------------
+
+ ! flows or changes
+ smin_nh4_to_plant_vr(c,j) = (accextrnh4_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ smin_no3_to_plant_vr(c,j) = (accextrno3_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+ sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j)
+
+ else ! just in case 'clm_pf_idata%nzclm_mapped0) then
+ call VecRestoreArrayReadF90(clm_pf_idata%acctotnmin_vr_clms, accnmin_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecRestoreArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ if(clm_pf_idata%ispec_nimp>0) then
+ call VecRestoreArrayReadF90(clm_pf_idata%acctotnimmp_vr_clms, accnimmp_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecRestoreArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ if(clm_pf_idata%ispec_nimm>0) then
+ call VecRestoreArrayReadF90(clm_pf_idata%acctotnimm_vr_clms, accnimm_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecRestoreArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ ! update bgc gas losses
+ call update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ end associate
+ end subroutine update_soil_bgc_pf2clm
+
+
+ !-----------------------------------------------------------------------------
+ !
+ ! !ROUTINE: update_bgc_gaslosses_pf2clm()
+ !
+ ! !INTERFACE:
+ !
+ ! This is a temporary solution to estimate pflotran bgc gaseous emission and transport loss
+ ! from their aq. phase states
+ ! (due to not yet available in pflotran bgc)
+ !
+ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ use ColumnType , only : col_pp
+ use clm_time_manager , only : get_step_size, get_nstep
+ use clm_varpar , only : nlevdecomp_full
+ use clm_varcon , only : tfrz
+
+ use clm_varctl , only : pf_tmode, pf_hmode, pf_frzmode
+
+ !
+ implicit none
+
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ character(len=256) :: subname = "get_pf_bgc_gaslosses"
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ integer :: fc, c, g, j, k
+ integer :: gcount, cellcount
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: nstep
+
+ ! for gas species
+ real(r8) :: tc, tk, total_p ! temperature (oC, K), total air pressure (Pa)
+ real(r8) :: co2_p, n2_p, n2o_p ! partial pressure (Pa) of CO2, N2, N2O
+ real(r8) :: cgas, cgas_p ! mole-C(N)/m3(bulk soil)
+ real(r8) :: air_vol, air_molar, wfps
+ integer :: lair_barrier(bounds%begc:bounds%endc) ! toppest soil layer that little air space for air flow into deep soil (-1: no, 0: ground, >0: soil layer)
+
+ ! gases from PFLOTRAN are timely accumulated, so gas fluxes are calculated here if over atm. partial pressure (no explicit transport available from PF now)
+ PetscScalar, pointer :: gco2_vr_clms_loc(:) ! (M: molC/m3 bulk soil) vertically-resolved soil gas CO2 from PF's evolution
+ PetscScalar, pointer :: gn2_vr_clms_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2 from PF's evolution
+ PetscScalar, pointer :: gn2o_vr_clms_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2O from PF's evolution
+ PetscScalar, pointer :: gco2_vr_clmp_loc(:) ! (M: molC/m3 bulk soil) vertically-resolved soil gas CO2 to reset PF's CO2g
+ PetscScalar, pointer :: gn2_vr_clmp_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2 to reset PF's N2g
+ PetscScalar, pointer :: gn2o_vr_clmp_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2O to reset PF's N2Og
+
+ ! 'acchr_vr' - accumulative CO2 proudction from decompositon (for tracking HR, not involving mass-balance)
+ PetscScalar, pointer :: acchr_vr_clm_loc(:) ! (moleC/m3/timestep) vertically-resolved soil CO2 production (accumulated)
+ ! 'accngasmin_vr' - accumulative N gas proudction from mineralization (for tracking, not involving mass-balance)
+ PetscScalar, pointer :: accngasmin_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil gaseous N production (accumulated)
+ ! 'accngasnitr_vr' - accumulative N gas proudction from nitrification (for tracking)
+ PetscScalar, pointer :: accngasnitr_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil gaseous N production (accumulated)
+ ! 'accngasdeni_vr' - accumulative N gas proudction from denitrification (for tracking)
+ PetscScalar, pointer :: accngasdeni_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil gaseous N production (accumulated)
+
+ !
+ PetscScalar, pointer :: soillsat_clm_loc(:)
+ PetscScalar, pointer :: soilisat_clm_loc(:)
+ PetscScalar, pointer :: soilpor_clm_loc(:)
+ PetscScalar, pointer :: soilt_clm_loc(:)
+ PetscScalar, pointer :: soilpress_clm_loc(:)
+ PetscErrorCode :: ierr
+
+ real(r8), parameter :: rgas = 8.3144621 ! m3 Pa K-1 mol-1
+
+!------------------------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! gridcell index of column
+ dz => col_pp%dz , & ! soil layer thickness depth (m)
+ !
+ frac_sno_eff => clm_interface_data%th%frac_sno_eff_col , & ! fraction of ground covered by snow (0 to 1)
+ frac_h2osfc => clm_interface_data%th%frac_h2osfc_col , & ! fraction of ground covered by surface water (0 to 1)
+ forc_pbot => clm_interface_data%th%forc_pbot_grc , & ! atmospheric pressure (Pa)
+ !
+ forc_pco2 => clm_interface_data%bgc%forc_pco2_grc , & ! partial pressure co2 (Pa)
+ hr_vr => clm_interface_data%bgc%hr_vr_col , &
+ f_co2_soil_vr => clm_interface_data%bgc%f_co2_soil_vr_col , &
+ f_n2o_soil_vr => clm_interface_data%bgc%f_n2o_soil_vr_col , &
+ f_n2_soil_vr => clm_interface_data%bgc%f_n2_soil_vr_col , &
+ f_ngas_decomp_vr => clm_interface_data%bgc%f_ngas_decomp_vr_col , &
+ f_ngas_nitri_vr => clm_interface_data%bgc%f_ngas_nitri_vr_col , &
+ f_ngas_denit_vr => clm_interface_data%bgc%f_ngas_denit_vr_col &
+ )
+! ------------------------------------------------------------------------
+ dtime = get_step_size()
+ nstep = get_nstep()
+
+ ! get the current time-step state variables of aq. phase of interested species
+ call VecGetArrayReadF90(clm_pf_idata%gco2_vr_clms, gco2_vr_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%gn2_vr_clms, gn2_vr_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%gn2o_vr_clms, gn2o_vr_clms_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ call VecGetArrayF90(clm_pf_idata%gco2_vr_clmp, gco2_vr_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+
+ call VecGetArrayReadF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ if(clm_pf_idata%ispec_hrimm>0) then
+ call VecGetArrayReadF90(clm_pf_idata%acctothr_vr_clms, acchr_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecGetArrayReadF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ ! env. variables to properties of gases
+ if (pf_tmode) then
+ call VecGetArrayReadF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soilt'
+ else
+ call VecGetArrayReadF90(clm_pf_idata%soilt_clmp, soilt_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! CLM evolved 'soilt' - for CLM, MPI vecs and Seq. vecs should be same
+ end if
+
+ if (pf_frzmode) then
+ call VecGetArrayReadF90(clm_pf_idata%soilisat_clms, soilisat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil ice saturation'
+ end if
+
+ if (pf_hmode) then
+ call VecGetArrayReadF90(clm_pf_idata%soillsat_clms, soillsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil liq. saturation'
+ call VecGetArrayReadF90(clm_pf_idata%press_clms, soilpress_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil liq. saturation'
+ else
+ call VecGetArrayReadF90(clm_pf_idata%soillsat_clmp, soillsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)! CLM evolved 'soilt liq. saturation'
+ call VecGetArrayReadF90(clm_pf_idata%press_clmp, soilpress_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)! CLM evolved 'soilt liq. saturation'
+ endif
+ call VecGetArrayReadF90(clm_pf_idata%effporosity_clms, soilpor_clm_loc, ierr) ! PF evolved 'soil porosity'
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! find the toppest air barrier layer
+ lair_barrier(:) = -1 ! (-1: no barrier, 0: ground snow/ice/water-layer barrier, >=1: barrier in soil column)
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ ! find the toppest air barrier layer for the current column at first
+
+ if((frac_sno_eff(c)+ frac_h2osfc(c))>=0.95_r8) then
+ lair_barrier(c) = 0
+ endif
+
+ do j = 1, clm_pf_idata%nzclm_mapped
+
+ cellcount = gcount*clm_pf_idata%nzclm_mapped+j
+
+ wfps = 0._r8
+ if (lair_barrier(c) >= 0) exit
+
+ if (pf_frzmode) then
+ wfps =soillsat_clm_loc(cellcount) &
+ + soilisat_clm_loc(cellcount)
+ else
+ wfps =soillsat_clm_loc(cellcount) ! note: 'lsat' from PF has been adjusted by 'isat' reduced porosity
+ endif
+ if (wfps > 0.95_r8) then ! 95% total saturation as a critical-point for air-flow into deep soil
+ lair_barrier(c) = j
+ endif
+ enddo
+
+
+ ! gas exchanges btw atm. and non-barrierred soil layer
+ ! only operating on soil column one by one, which then back to CLM-CN
+
+ total_p = forc_pbot(g)
+
+ do j = 1, nlevdecomp_full
+
+ if(j <= clm_pf_idata%nzclm_mapped) then
+ cellcount = gcount*clm_pf_idata%nzclm_mapped+j
+
+ tc = soilt_clm_loc(cellcount) ! soil layer tc (oC)
+ tk = tc+tfrz
+
+ ! total_p is soil air pressure (soil water pressure if not less than atm. pressure)
+ total_p = max(total_p, soilpress_clm_loc(cellcount))
+
+ ! the following is for adjusting air space in soil (seems not right ?? -- off)
+ !air_vol = (1.0_r8 - soillsat_clm_loc(cellcount)) * &
+ ! soilpor_clm_loc(cellcount) ! m3 air/m3 soil
+ !air_vol = max(air_vol, 0.01d0) ! min. 0.01 to avoid math. issue
+
+ air_vol = 1.0_r8 ! atm used if not commented out
+ air_molar = total_p*air_vol/rgas/tk ! moles of air in a cell
+
+ ! gas fluxes from immobile PFLOTRAN evolving CO2imm, N2Oimm and N2imm, which are cumulative
+ ! CO2 -
+ cgas = gco2_vr_clms_loc(cellcount) ! mol/m3 soil (evolving in PF, but not yet transport)
+ co2_p = forc_pco2(g) ! assuming atm. pco2 (pa) as directly equilibrated with soil CO2(g)
+ cgas_p = co2_p/forc_pbot(g) * air_molar
+
+ f_co2_soil_vr(c,j) = cgas-cgas_p
+ cgas = cgas - f_co2_soil_vr(c,j)
+ if (j <= lair_barrier(c) .or. lair_barrier(c) < 0) then ! above barrier OR no-barrier(-1)
+ gco2_vr_clmp_loc(cellcount) = cgas_p ! this refreshed-air will pass back to PF
+ else
+ gco2_vr_clmp_loc(cellcount) = cgas ! currently don't have air transport (TODO)
+ endif
+
+ f_co2_soil_vr(c,j) = f_co2_soil_vr(c,j)*clm_pf_idata%C_molecular_weight ! moleCO2/m3 --> gC/m3 soil
+ f_co2_soil_vr(c,j) = f_co2_soil_vr(c,j)/dtime ! gC/m3/s
+
+ ! N2
+ cgas = gn2_vr_clms_loc(cellcount) ! mol/m3 soil (evolving in PF, but not yet transport)
+ n2_p = 0.78084_r8 ! assuming atm. pn2 as directly equilibrated with soil n2(g)
+ cgas_p = n2_p * air_molar ! moleN2/m3
+
+ f_n2_soil_vr(c,j) = cgas-cgas_p
+ cgas = cgas - f_n2_soil_vr(c,j)
+ if (j <= lair_barrier(c) .or. lair_barrier(c) < 0) then ! above barrier OR no-barrier(-1)
+ gn2_vr_clmp_loc(cellcount) = cgas_p ! this refreshed-air will pass back to PF
+ else
+ gn2_vr_clmp_loc(cellcount) = cgas ! currently don't have air transport (TODO)
+ endif
+
+ f_n2_soil_vr(c,j) = f_n2_soil_vr(c,j)*clm_pf_idata%N_molecular_weight*2._r8 ! mole-N2/m3 --> g-N/m3 soil
+ f_n2_soil_vr(c,j) = f_n2_soil_vr(c,j)/dtime ! gN/m3/s
+
+ ! N2O
+ cgas = gn2o_vr_clms_loc(cellcount)
+ n2o_p = 310e-9_r8 ! assuming general atm. pN2O (310ppbv in 1990) as directly equilibrated with soil N2(aq)
+ cgas_p = n2o_p * air_molar ! moleN2O/m3
+
+ f_n2o_soil_vr(c,j) = cgas-cgas_p
+ cgas = cgas - f_n2o_soil_vr(c,j)
+ if (j <= lair_barrier(c) .or. lair_barrier(c) < 0) then ! above barrier OR no-barrier(-1)
+ gn2o_vr_clmp_loc(cellcount) = cgas_p ! this refreshed-air will pass back to PF
+ else
+ gn2o_vr_clmp_loc(cellcount) = cgas ! currently don't have air transport (TODO)
+ endif
+
+ f_n2o_soil_vr(c,j) = f_n2o_soil_vr(c,j)*clm_pf_idata%N_molecular_weight*2._r8 ! mole-N2O/m3 --> g-N/m3 soil
+ f_n2o_soil_vr(c,j) = f_n2o_soil_vr(c,j)/dtime ! gN/m3/s
+
+ ! tracking HR from SOM-C reaction network
+ hr_vr(c,j) = (acchr_vr_clm_loc(cellcount) &
+ * clm_pf_idata%C_molecular_weight)/dtime
+
+ ! tracking gaseous N production from N reaction network
+ f_ngas_decomp_vr(c,j)= (accngasmin_vr_clm_loc (cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+
+ f_ngas_nitri_vr(c,j) = (accngasnitr_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+
+ f_ngas_denit_vr(c,j) = (accngasdeni_vr_clm_loc(cellcount) &
+ * clm_pf_idata%N_molecular_weight)/dtime
+
+ else ! just in case 'clm_pf_idata%nzclm_mapped0) then
+ call VecRestoreArrayReadF90(clm_pf_idata%acctothr_vr_clms, acchr_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecRestoreArrayReadF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ endif
+
+ call VecRestoreArrayReadF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ if (pf_tmode) then
+ call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ else
+ call VecRestoreArrayReadF90(clm_pf_idata%soilt_clmp, soilt_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! for CLM, MPI vecs and Seq. vecs should be same
+ end if
+ if (pf_frzmode) then
+ call VecRestoreArrayReadF90(clm_pf_idata%soilisat_clms, soilisat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ end if
+
+ if (pf_hmode) then
+ call VecRestoreArrayReadF90(clm_pf_idata%soillsat_clms, soillsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil liq. saturation'
+ call VecRestoreArrayReadF90(clm_pf_idata%press_clms, soilpress_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil liq. saturation'
+ else
+ call VecRestoreArrayReadF90(clm_pf_idata%soillsat_clmp, soillsat_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)! CLM evolved 'soil liq. saturation'
+ call VecRestoreArrayReadF90(clm_pf_idata%press_clmp, soilpress_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)! CLM evolved 'soil liq. saturation'
+ endif
+ call VecRestoreArrayReadF90(clm_pf_idata%effporosity_clms, soilpor_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ ! need to reset the PF's internal gas concentration (CLM ==> PF)
+ call pflotranModelUpdateAqGasesfromCLM(pflotran_m)
+
+ end associate
+ end subroutine update_bgc_gaslosses_pf2clm
+
+ !-----------------------------------------------------------------------------
+ !
+ ! !ROUTINE: update_bgc_bcflux_pf2clm()
+ !
+ ! !INTERFACE:
+ !
+ ! This is to estimate pflotran bgc boundary aq. transport fluxes
+ ! for (1) diagnostic purpose and (2) mass-balance error checking for whole domain ONLY.
+ ! i.e. it's NOT for mass state updating,
+ ! because PFLOTRAN had already updated state variables.
+ !
+ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter)
+
+ use ColumnType , only : col_pp
+ use clm_time_manager , only : get_step_size
+ use clm_varpar , only : nlevdecomp_full
+
+ !
+ implicit none
+
+ type(bounds_type), intent(in) :: bounds ! bounds of current process
+ type(clumpfilter), intent(in) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+
+ character(len=256) :: subname = "get_pf_bgc_bcfluxes"
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ integer :: fc, c, g, j
+ integer :: gcount, cellcount
+ real(r8) :: dtime ! land model time step (sec)
+ !
+ ! actual aqeuous N mass flow rate(moleN/m2/sec) at the top (runoff)/bottom (leaching) of 3-D subsurface domain
+ ! (+ in, - out)
+ PetscScalar, pointer :: f_nh4_subsurf_clm_loc(:)
+ PetscScalar, pointer :: f_nh4_subbase_clm_loc(:)
+ PetscScalar, pointer :: f_no3_subsurf_clm_loc(:)
+ PetscScalar, pointer :: f_no3_subbase_clm_loc(:)
+
+ PetscErrorCode :: ierr
+
+
+!------------------------------------------------------------------------------------
+ associate ( &
+ cgridcell => col_pp%gridcell , & ! gridcell index of column
+ dz => col_pp%dz , & ! soil layer thickness depth (m)
+ !
+ no3_net_transport_vr => clm_interface_data%bgc%no3_net_transport_vr_col , & ! output: [c,j] (gN/m3/s)
+ nh4_net_transport_vr => clm_interface_data%bgc%nh4_net_transport_vr_col & ! output: [c,j] (gN/m3/s)
+ )
+! ------------------------------------------------------------------------
+ dtime = get_step_size()
+
+ call VecGetArrayReadF90(clm_pf_idata%f_nh4_subsurf_clms, f_nh4_subsurf_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%f_no3_subsurf_clms, f_no3_subsurf_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%f_nh4_subbase_clms, f_nh4_subbase_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecGetArrayReadF90(clm_pf_idata%f_no3_subbase_clms, f_no3_subbase_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ no3_net_transport_vr(:,:) = 0._r8
+ nh4_net_transport_vr(:,:) = 0._r8
+
+ ! operating via 'filters'
+ gcount = -1
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ g = cgridcell(c)
+
+#ifdef COLUMN_MODE
+ if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering)
+ gcount = gcount + 1 ! 0-based: cumulatively by not-skipped column
+#else
+ gcount = g - bounds%begg ! 0-based
+ if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering
+#endif
+
+ ! add actual BC mass fluxes ( in gN/m2/s) from PFLOTRAN
+ no3_net_transport_vr(c,clm_pf_idata%nzclm_mapped) = &
+ no3_net_transport_vr(c,clm_pf_idata%nzclm_mapped) - &
+ f_no3_subbase_clm_loc(gcount) * & !( - is out in PF)
+ clm_pf_idata%N_molecular_weight
+
+ nh4_net_transport_vr(c,clm_pf_idata%nzclm_mapped) = &
+ nh4_net_transport_vr(c,clm_pf_idata%nzclm_mapped) - &
+ f_nh4_subbase_clm_loc(gcount) * &
+ clm_pf_idata%N_molecular_weight
+
+ no3_net_transport_vr(c,1) = no3_net_transport_vr(c,1) - &
+ f_no3_subsurf_clm_loc(gcount) * &
+ clm_pf_idata%N_molecular_weight
+ nh4_net_transport_vr(c,1) = nh4_net_transport_vr(c,1) - &
+ f_nh4_subsurf_clm_loc(gcount) * &
+ clm_pf_idata%N_molecular_weight
+
+ ! (TODO) not yet considering lateral transport (although data structure is here)
+
+ enddo ! do fc = 1,filters(ifilter)%num_soilc
+
+ call VecRestoreArrayReadF90(clm_pf_idata%f_nh4_subsurf_clms, f_nh4_subsurf_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%f_no3_subsurf_clms, f_no3_subsurf_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%f_nh4_subbase_clms, f_nh4_subbase_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+ call VecRestoreArrayReadF90(clm_pf_idata%f_no3_subbase_clms, f_no3_subbase_clm_loc, ierr)
+ call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)
+
+ end associate
+ end subroutine update_bgc_bcflux_pf2clm
+
+ !-----------------------------------------------------------------------------
+ !BOP
+ !
+ ! !SUBROUTINE: clm_pf_checkerr(ierr)
+ !
+ ! !INTERFACE:
+ subroutine clm_pf_checkerr(ierr, subname, filename, line)
+ !
+ ! !DESCRIPTION:
+ ! When using PETSc functions, it usually throws an error code for checking.
+ ! BUT it won't show where the error occurs in the first place, therefore it's hardly useful.
+ !
+ ! !USES:
+ use clm_varctl , only : iulog
+ use spmdMod , only : iam
+
+ implicit none
+
+#include "petsc/finclude/petscsys.h"
+#include "petsc/finclude/petscvec.h"
+#include "petsc/finclude/petscvec.h90"
+
+ ! !ARGUMENTS:
+ character(len=*), intent(IN) :: subname ! subroutine name called this
+ character(len=*), intent(IN) :: filename ! filename called this
+ integer, intent(IN) :: line ! line number triggered this
+ PetscErrorCode, intent(IN) :: ierr ! petsc error code
+
+ !EOP
+ !-----------------------------------------------------------------------
+
+ if (ierr /= 0) then
+ write (iulog,*) 'PETSc ERROR: Subroutine - ' // &
+ trim(subname), ' @Rank -', iam
+ write (iulog,*) 'PETSc ERROR: File - ' // &
+ trim(filename), ' @Line -', line
+ end if
+
+ CHKERRQ(ierr)
+
+ end subroutine clm_pf_checkerr
+
+!--------------------------------------------------------------------------------------
+ subroutine clm_pf_BeginCBalance(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ ! On the radiation time step, calculate the beginning carbon balance for mass
+ ! conservation checks.
+
+ use clm_varpar , only : ndecomp_pools, nlevdecomp,nlevdecomp_full
+ use clm_varcon , only : dzsoi_decomp
+ !
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(inout) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+ !
+ ! !LOCAL VARIABLES:
+ integer :: c,j,l ! indices
+ integer :: fc ! soil filter indices
+
+ !-----------------------------------------------------------------------
+
+ associate( &
+ decomp_cpools_vr => clm_interface_data%bgc%decomp_cpools_vr_col , &
+ soil_begcb => clm_interface_data%bgc%soil_begcb_col & ! Output: [real(r8) (:)] carbon mass, beginning of time step (gC/m**2)
+ )
+ ! calculate beginning column-level soil carbon balance, for mass conservation check
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ soil_begcb(c) = 0._r8
+ do j = 1, nlevdecomp_full
+ do l = 1, ndecomp_pools
+ soil_begcb(c) = soil_begcb(c) + decomp_cpools_vr(c,j,l)*dzsoi_decomp(j)
+ end do
+ end do
+ end do
+
+ end associate
+
+ end subroutine clm_pf_BeginCBalance
+
+!--------------------------------------------------------------------------------------
+
+ subroutine clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ ! On the radiation time step, calculate the beginning carbon balance for mass
+ ! conservation checks.
+
+ use clm_varpar , only : ndecomp_pools, nlevdecomp, nlevdecomp_full
+ use clm_varcon , only : dzsoi_decomp
+ !
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(inout) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+ !
+ ! !LOCAL VARIABLES:
+ integer :: c,j,l ! indices
+ integer :: fc ! soil filter indices
+ integer :: nlev
+
+ !-----------------------------------------------------------------------
+
+ associate( &
+ decomp_npools_vr => clm_interface_data%bgc%decomp_npools_vr_col , &
+ smin_no3_vr => clm_interface_data%bgc%smin_no3_vr_col , &
+ smin_nh4_vr => clm_interface_data%bgc%smin_nh4_vr_col , &
+ smin_nh4sorb_vr => clm_interface_data%bgc%smin_nh4sorb_vr_col , &
+ soil_begnb => clm_interface_data%bgc%soil_begnb_col , & ! Output: [real(r8) (:)] carbon mass, beginning of time step (gC/m**2)
+ soil_begnb_org => clm_interface_data%bgc%soil_begnb_org_col , & !
+ soil_begnb_min => clm_interface_data%bgc%soil_begnb_min_col & !
+ )
+ ! calculate beginning column-level soil carbon balance, for mass conservation check
+ nlev = nlevdecomp_full
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ soil_begnb(c) = 0._r8
+ soil_begnb_org(c) = 0._r8
+ soil_begnb_min(c) = 0._r8
+
+ do j = 1, nlev
+ !do NOT directly use sminn_vr(c,j), it does NOT always equal to (no3+nh4+nh4sorb) herein
+ soil_begnb_min(c) = soil_begnb_min(c) + smin_no3_vr(c,j)*dzsoi_decomp(j) &
+ + smin_nh4_vr(c,j)*dzsoi_decomp(j) &
+ + smin_nh4sorb_vr(c,j)*dzsoi_decomp(j)
+ do l = 1, ndecomp_pools
+ soil_begnb_org(c) = soil_begnb_org(c) &
+ + decomp_npools_vr(c,j,l)*dzsoi_decomp(j)
+ end do
+ end do !j = 1, nlevdecomp
+
+ soil_begnb(c) = soil_begnb_org(c) + soil_begnb_min(c)
+ end do
+ end associate
+ end subroutine clm_pf_BeginNBalance
+!--------------------------------------------------------------------------------------
+
+ subroutine clm_pf_CBalanceCheck(clm_interface_data,bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ ! On the radiation time step, perform carbon mass conservation check for column and pft
+ !
+ ! !USES:
+ use clm_time_manager, only : get_step_size, get_nstep
+ use clm_varctl , only : iulog, use_ed
+ use clm_varpar , only : ndecomp_pools, nlevdecomp, nlevdecomp_full
+ use clm_varcon , only : dzsoi_decomp
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(inout) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+ !
+ ! !LOCAL VARIABLES:
+ integer :: c,j,l ! indices
+ integer :: fc ! lake filter indices
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: err_index ! indices
+ logical :: err_found ! error flag
+ ! balance check varialbes:
+ real(r8) :: pf_cinputs(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_coutputs(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_cdelta(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_errcb(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_cbeg(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_cend(1:filters(ifilter)%num_soilc)
+ !-----------------------------------------------------------------------
+
+ associate( &
+ externalc => clm_interface_data%bgc%externalc_to_decomp_cpools_col , & ! Input: [real(r8) (:) ] (gC/m2) total column carbon, incl veg and cpool
+ decomp_cpools_delta_vr => clm_interface_data%bgc%decomp_cpools_sourcesink_col , &
+ hr_vr => clm_interface_data%bgc%hr_vr_col , &
+ soil_begcb => clm_interface_data%bgc%soil_begcb_col & ! Output: [real(r8) (:) ] carbon mass, beginning of time step (gC/m**2)
+ )
+
+ ! ------------------------------------------------------------------------
+ dtime = real( get_step_size(), r8 )
+ ! pflotran mass blance check-Carbon
+ err_found = .false.
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ pf_cbeg(fc) = soil_begcb(c)
+ pf_cend(fc) = 0._r8
+ pf_errcb(fc) = 0._r8
+
+ pf_cinputs(fc) = 0._r8
+ pf_coutputs(fc) = 0._r8
+ pf_cdelta(fc) = 0._r8
+
+ do j = 1, nlevdecomp_full
+ pf_coutputs(fc) = pf_coutputs(fc) + hr_vr(c,j)*dzsoi_decomp(j)
+ do l = 1, ndecomp_pools
+ pf_cinputs(fc) = pf_cinputs(fc) + externalc(c,j,l)*dzsoi_decomp(j)
+ pf_cdelta(fc) = pf_cdelta(fc) + decomp_cpools_delta_vr(c,j,l)*dzsoi_decomp(j)
+ end do
+ end do
+
+ pf_cend(fc) = pf_cbeg(fc) + pf_cdelta(fc)
+ pf_errcb(fc) = (pf_cinputs(fc) - pf_coutputs(fc))*dtime - pf_cdelta(fc)
+
+ ! check for significant errors
+ if (abs(pf_errcb(fc)) > 1e-8_r8) then
+ err_found = .true.
+ err_index = fc
+ end if
+ end do
+
+ if (.not. use_ed) then
+ if (err_found) then
+ fc = err_index
+ write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:beg "
+ write(iulog,'(A35,I15,A10,I20)')"Carbon Balance Error in Column = ",filters(ifilter)%soilc(fc), " @ nstep=",get_nstep()
+ write(iulog,'(10A15)')"errcb", "C_in-out", "Cdelta","Cinputs","Coutputs","Cbeg","Cend"
+ write(iulog,'(10E15.6)')pf_errcb(fc), (pf_cinputs(fc) - pf_coutputs(fc))*dtime, pf_cdelta(fc), &
+ pf_cinputs(fc)*dtime,pf_coutputs(fc)*dtime,pf_cbeg(fc),pf_cend(fc)
+ write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:end "
+ end if
+ end if !(.not. use_ed)
+ end associate
+ end subroutine clm_pf_CBalanceCheck
+!--------------------------------------------------------------------------------------
+
+ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter)
+ !
+ ! !DESCRIPTION:
+ ! On the radiation time step, perform carbon mass conservation check for column and pft
+ !
+ ! !USES:
+ use clm_time_manager, only : get_step_size,get_nstep
+ use clm_varctl , only : iulog, use_ed
+ use clm_varpar , only : ndecomp_pools, nlevdecomp, nlevdecomp_full
+ use clm_varcon , only : dzsoi_decomp
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds ! bounds of current process
+ type(clumpfilter) , intent(inout) :: filters(:) ! filters on current process
+ integer , intent(in) :: ifilter ! which filter to be operated
+ type(clm_interface_data_type), intent(inout) :: clm_interface_data
+ !
+ ! !LOCAL VARIABLES:
+ integer :: nlev
+ integer :: c,j,l ! indices
+ integer :: fc ! lake filter indices
+ real(r8) :: dtime ! land model time step (sec)
+ integer :: err_index ! indices
+ logical :: err_found ! error flag
+
+ real(r8) :: pf_ninputs(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_noutputs(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_ndelta(1:filters(ifilter)%num_soilc) ! _ndelta: difference in pool sizes between end & beginning
+ real(r8) :: pf_errnb(1:filters(ifilter)%num_soilc) ! _errnb: mass balance error;
+ real(r8) :: pf_noutputs_gas(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_noutputs_veg(1:filters(ifilter)%num_soilc) ! _gas:nitrogen gases; _veg:plant uptake of NO3/NH4
+ real(r8) :: pf_noutputs_nit(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_noutputs_denit(1:filters(ifilter)%num_soilc) ! _gas = _nit + _denit
+ real(r8) :: pf_ninputs_org(1:filters(ifilter)%num_soilc) ! _org:organic; _min:mineral nitrogen
+ real(r8) :: pf_ninputs_min(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_ndelta_org(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_ndelta_min(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_nbeg(1:filters(ifilter)%num_soilc) ! _nbeg: Nitrogen mass at the beginning of time-step
+ real(r8) :: pf_nbeg_org(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_nbeg_min(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_nend(1:filters(ifilter)%num_soilc) ! _end: Nitrogen mass at the end of time-step
+ real(r8) :: pf_nend_org(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_nend_min(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_nend_no3(1:filters(ifilter)%num_soilc) ! 3 mineral N pools at the end of time-step
+ real(r8) :: pf_nend_nh4(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_nend_nh4sorb(1:filters(ifilter)%num_soilc)
+ real(r8) :: plant_ndemand(1:filters(ifilter)%num_soilc)
+ real(r8) :: potential_immob(1:filters(ifilter)%num_soilc)
+ real(r8) :: actual_immob(1:filters(ifilter)%num_soilc)
+ real(r8) :: gross_nmin(1:filters(ifilter)%num_soilc) ! _immob: N immobilization; _nmin: N mineralization
+ real(r8) :: pf_ngas_dec(1:filters(ifilter)%num_soilc) ! _ngas_dec: N gas from decomposition-mineralization
+ real(r8) :: pf_ngas_min(1:filters(ifilter)%num_soilc) ! _ngas_min: N gas from nitrification & denitrification
+ real(r8) :: pf_errnb_org(1:filters(ifilter)%num_soilc)
+ real(r8) :: pf_errnb_min(1:filters(ifilter)%num_soilc)
+
+ real(r8) :: pf_errnb_org_vr (1:filters(ifilter)%num_soilc, 1:nlevdecomp_full)
+ real(r8) :: pf_ndelta_org_vr (1:filters(ifilter)%num_soilc, 1:nlevdecomp_full)
+ real(r8) :: pf_ninputs_org_vr(1:filters(ifilter)%num_soilc, 1:nlevdecomp_full)
+ !-----------------------------------------------------------------------
+
+ associate( &
+ externaln_to_decomp_npools => clm_interface_data%bgc%externaln_to_decomp_npools_col, & ! Input: [real(r8) (:) ] (gC/m2) total column carbon, incl veg and cpool
+ externaln_to_no3_vr => clm_interface_data%bgc%externaln_to_no3_col , &
+ externaln_to_nh4_vr => clm_interface_data%bgc%externaln_to_nh4_col , &
+ decomp_npools_delta_vr => clm_interface_data%bgc%decomp_npools_sourcesink_col , &
+ decomp_npools_vr => clm_interface_data%bgc%decomp_npools_vr_col , &
+ smin_no3_vr => clm_interface_data%bgc%smin_no3_vr_col , &
+ smin_nh4_vr => clm_interface_data%bgc%smin_nh4_vr_col , &
+ smin_nh4sorb_vr => clm_interface_data%bgc%smin_nh4sorb_vr_col , &
+ f_ngas_decomp_vr => clm_interface_data%bgc%f_ngas_decomp_vr_col , &
+ f_ngas_nitri_vr => clm_interface_data%bgc%f_ngas_nitri_vr_col , &
+ f_ngas_denit_vr => clm_interface_data%bgc%f_ngas_denit_vr_col , &
+ sminn_to_plant_vr => clm_interface_data%bgc%sminn_to_plant_vr_col , &
+
+ plant_ndemand_vr => clm_interface_data%bgc%plant_ndemand_vr_col , &
+ potential_immob_vr => clm_interface_data%bgc%potential_immob_vr_col , &
+ actual_immob_vr => clm_interface_data%bgc%actual_immob_vr_col , &
+ gross_nmin_vr => clm_interface_data%bgc%gross_nmin_vr_col , &
+
+ soil_begnb => clm_interface_data%bgc%soil_begnb_col , & ! Output: [real(r8) (:) ] carbon mass, beginning of time step (gC/m**2)
+ soil_begnb_org => clm_interface_data%bgc%soil_begnb_org_col , & !
+ soil_begnb_min => clm_interface_data%bgc%soil_begnb_min_col & !
+ )
+
+ ! ------------------------------------------------------------------------
+ dtime = real( get_step_size(), r8 )
+ nlev = nlevdecomp_full
+ ! pflotran mass blance check-Carbon
+ err_found = .false.
+ do fc = 1,filters(ifilter)%num_soilc
+ c = filters(ifilter)%soilc(fc)
+ pf_nbeg_org(fc) = soil_begnb_org(c)
+ pf_nbeg_min(fc) = soil_begnb_min(c)
+ pf_nbeg(fc) = soil_begnb(c)
+
+ pf_nend_org(fc) = 0._r8
+ pf_nend_min(fc) = 0._r8
+ pf_nend_no3(fc) = 0._r8
+ pf_nend_nh4(fc) = 0._r8
+ pf_nend_nh4sorb(fc) = 0._r8
+ pf_nend(fc) = 0._r8
+
+ pf_ninputs_org(fc) = 0._r8
+ pf_ninputs_min(fc) = 0._r8
+ pf_ninputs(fc) = 0._r8
+
+ pf_noutputs_nit(fc) = 0._r8
+ pf_noutputs_denit(fc) = 0._r8
+ pf_noutputs_gas(fc) = 0._r8
+ pf_noutputs_veg(fc) = 0._r8
+ pf_noutputs(fc) = 0._r8
+
+ pf_ndelta_org(fc) = 0._r8
+ pf_ndelta_min(fc) = 0._r8
+ pf_ndelta(fc) = 0._r8
+
+ plant_ndemand(fc) = 0._r8
+ potential_immob(fc) = 0._r8
+ actual_immob(fc) = 0._r8
+ gross_nmin(fc) = 0._r8
+
+ pf_ngas_dec(fc) = 0._r8
+ pf_ngas_min(fc) = 0._r8
+ pf_errnb_org(fc) = 0._r8
+ pf_errnb_min(fc) = 0._r8
+
+ do j = 1, nlev
+ ! sminn_vr(c,j) has been calculated above
+ pf_nend_no3(fc) = pf_nend_no3(fc) + smin_no3_vr(c,j)*dzsoi_decomp(j)
+ pf_nend_nh4(fc) = pf_nend_nh4(fc) + smin_nh4_vr(c,j)*dzsoi_decomp(j)
+ pf_nend_nh4sorb(fc) = pf_nend_nh4sorb(fc) + smin_nh4sorb_vr(c,j)*dzsoi_decomp(j)
+
+ pf_ninputs_min(fc) = pf_ninputs_min(fc) + externaln_to_nh4_vr(c,j)*dzsoi_decomp(j) &
+ + externaln_to_no3_vr(c,j)*dzsoi_decomp(j)
+
+ pf_noutputs_nit(fc) = pf_noutputs_nit(fc) + f_ngas_decomp_vr(c,j)*dzsoi_decomp(j) &
+ + f_ngas_nitri_vr(c,j)*dzsoi_decomp(j)
+ pf_noutputs_denit(fc) = pf_noutputs_denit(fc) + f_ngas_denit_vr(c,j)*dzsoi_decomp(j)
+ pf_noutputs_veg(fc) = pf_noutputs_veg(fc) + sminn_to_plant_vr(c,j)*dzsoi_decomp(j)
+
+ pf_ngas_dec(fc) = pf_ngas_dec(fc) + f_ngas_decomp_vr(c,j)*dzsoi_decomp(j)
+ pf_ngas_min(fc) = pf_ngas_min(fc) + f_ngas_denit_vr(c,j)*dzsoi_decomp(j) &
+ + f_ngas_nitri_vr(c,j)*dzsoi_decomp(j)
+ do l = 1, ndecomp_pools
+ pf_ndelta_org(fc) = pf_ndelta_org(fc) + decomp_npools_delta_vr(c,j,l)*dzsoi_decomp(j)
+ pf_ninputs_org(fc) = pf_ninputs_org(fc) + externaln_to_decomp_npools(c,j,l)*dzsoi_decomp(j)
+ end do
+
+ plant_ndemand(fc) = plant_ndemand(fc) + plant_ndemand_vr(c,j)*dzsoi_decomp(j)
+ potential_immob(fc) = potential_immob(fc) + potential_immob_vr(c,j)*dzsoi_decomp(j)
+ actual_immob(fc) = actual_immob(fc) + actual_immob_vr(c,j)*dzsoi_decomp(j)
+ gross_nmin(fc) = gross_nmin(fc) + gross_nmin_vr(c,j)*dzsoi_decomp(j)
+ end do !j = 1, nlevdecomp
+
+ pf_nend_org(fc) = pf_nbeg_org(fc) + pf_ndelta_org(fc) !pf_ndelta_org has been calculated
+ pf_nend_min(fc) = pf_nend_no3(fc) + pf_nend_nh4(fc) + pf_nend_nh4sorb(fc)
+ pf_nend(fc) = pf_nend_org(fc) + pf_nend_min(fc)
+ pf_ndelta_min(fc) = pf_nend_min(fc) - pf_nbeg_min(fc)
+ pf_ndelta(fc) = pf_nend(fc) - pf_nbeg(fc) !pf_ndelta_org + pf_ndelta_min
+ pf_ninputs(fc) = pf_ninputs_org(fc) + pf_ninputs_min(fc)
+ pf_noutputs_gas(fc) = pf_noutputs_nit(fc) + pf_noutputs_denit(fc)
+ pf_noutputs(fc) = pf_noutputs_gas(fc) + pf_noutputs_veg(fc)
+ pf_errnb(fc) = (pf_ninputs(fc) - pf_noutputs(fc))*dtime - pf_ndelta(fc)
+
+ pf_errnb_org(fc) = (pf_ninputs_org(fc) &
+ - gross_nmin(fc) + actual_immob(fc))*dtime &
+ - pf_ndelta_org(fc)
+ pf_errnb_min(fc) = (pf_ninputs_min(fc) - pf_ngas_min(fc) - pf_ngas_dec(fc) &
+ + gross_nmin(fc) - actual_immob(fc) - pf_noutputs_veg(fc))*dtime &
+ - pf_ndelta_min(fc)
+ ! check for significant errors
+ if (abs(pf_errnb(fc)) > 1e-8_r8) then
+ err_found = .true.
+ err_index = fc
+ end if
+
+ ! check SON balance at each layer,
+ pf_errnb_org_vr(fc,:) = 0._r8
+ pf_ndelta_org_vr(fc,:) = 0._r8
+ pf_ninputs_org_vr(fc,:) = 0._r8
+ do j = 1, nlev
+ do l = 1, ndecomp_pools
+ pf_ndelta_org_vr(fc,j) = pf_ndelta_org_vr(fc,j) + decomp_npools_delta_vr(c,j,l)
+ pf_ninputs_org_vr(fc,j) = pf_ninputs_org_vr(fc,j) + externaln_to_decomp_npools(c,j,l)
+ end do
+ pf_errnb_org_vr(fc,j) = (pf_ninputs_org_vr(fc,j) &
+ - gross_nmin_vr(c,j) + actual_immob_vr(c,j))*dtime &
+ - pf_ndelta_org_vr(fc,j)
+ pf_errnb_org_vr(fc,j) = pf_errnb_org_vr(fc,j)*dzsoi_decomp(j)
+ end do
+ end do
+
+ if (.not. use_ed) then
+ if (err_found) then
+ fc = err_index
+ write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:beg "
+ write(iulog,'(A35,I15,A10,I20)')"Nitrogen Balance Error in Column = ",filters(ifilter)%soilc(fc), " @ nstep = ",get_nstep()
+ write(iulog,'(10A15)') "errnb", "N_in-out", "Ndelta", &
+ "Ninputs","Noutputs", "Nbeg","Nend"
+ write(iulog,'(10E15.6)')pf_errnb(fc), (pf_ninputs(fc) - pf_noutputs(fc))*dtime, pf_ndelta(fc), &
+ pf_ninputs(fc)*dtime,pf_noutputs(fc)*dtime,pf_nbeg(fc),pf_nend(fc)
+ write(iulog,*)
+ write(iulog,'(10A15)') "errnb_org","Ndelta_org","Nbeg_org","Nend_org", &
+ "gross_nmin", "actual_immob", "pot_immob"
+ write(iulog,'(10E15.6)')pf_errnb_org(fc),pf_ndelta_org(fc),pf_nbeg_org(fc),pf_nend_org(fc), &
+ gross_nmin(fc)*dtime,actual_immob(fc)*dtime,potential_immob(fc)*dtime
+ write(iulog,*)
+ write(iulog,'(10A15)') "errnb_min","Ndelta_min","Nbeg_min","Nend_min", &
+ "Nend_no3","Nend_nh4", "Nend_nh4sorb"
+ write(iulog,'(10E15.6)')pf_errnb_min(fc), pf_ndelta_min(fc),pf_nbeg_min(fc),pf_nend_min(fc), &
+ pf_nend_no3(fc),pf_nend_nh4(fc),pf_nend_nh4sorb(fc)
+ write(iulog,*)
+ write(iulog,'(10A15)') "Ninputs_org","Ninputs_min", &
+ "Noutputs_nit","Noutputs_denit", &
+ "Noutputs_gas","Noutputs_veg", &
+ "plant_Ndemand","Ngas_dec","Ngas_min"
+ write(iulog,'(10E15.6)')pf_ninputs_org(fc)*dtime,pf_ninputs_min(fc)*dtime, &
+ pf_noutputs_nit(fc)*dtime,pf_noutputs_denit(fc)*dtime, &
+ pf_noutputs_gas(fc)*dtime,pf_noutputs_veg(fc)*dtime, &
+ plant_ndemand(fc)*dtime,pf_ngas_dec(fc)*dtime,pf_ngas_min(fc)*dtime
+! ! close output currently
+! write(iulog,*)
+! write(iulog,'(A10,20A15)') "Layer","errbn_org","ndelta_org","ninputs","gross_nmin","actual_immob"
+! do j = 1, nlev
+! write(iulog,'(I10,15E15.6)')j,pf_errnb_org_vr(fc,j), &
+! pf_ndelta_org_vr(fc,j)*dzsoi_decomp(j), &
+! pf_ninputs_org_vr(fc,j)*dtime*dzsoi_decomp(j), &
+! f_ngas_decomp_vr(c,j)*dtime*dzsoi_decomp(j), &
+! gross_nmin_vr(c,j)*dtime*dzsoi_decomp(j), &
+! actual_immob_vr(c,j)*dtime*dzsoi_decomp(j)
+
+! end do
+ write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:end "
+ end if
+ end if !(.not. use_ed)
+ end associate
+ end subroutine clm_pf_NBalanceCheck
+!--------------------------------------------------------------------------------------
+
+
+ !-----------------------------------------------------------------------------
+
+#endif
+!
+! Private interface subroutines, requiring explicit coupling between CLM and PFLOTRAN
+! (END)
+!************************************************************************************!
+
+
+end module clm_interface_pflotranMod
+
diff --git a/components/clm/src/main/clm_interface_thType.F90 b/components/clm/src/main/clm_interface_thType.F90
new file mode 100644
index 000000000000..6b76a3f01c7a
--- /dev/null
+++ b/components/clm/src/main/clm_interface_thType.F90
@@ -0,0 +1,169 @@
+module clm_interface_thType
+
+!=================================================================================================
+! ALM Thermal(T)-Hydrology (H) Interface: Data Type (Variables)
+! created: 8/25/2015
+! updated: 9/16/2016, 2/2/2017, June-2017
+!=================================================================================================
+ ! USES:
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
+
+ implicit none
+
+ private
+
+ type, public :: clm_interface_th_datatype
+
+ ! soilstate_vars:
+ real(r8), pointer :: soilpsi_col (:,:) ! col soil water potential in each soil layer (MPa) (CN)
+
+ ! waterstate_vars:
+ real(r8), pointer :: frac_sno_eff_col (:) ! col fraction of ground covered by snow (0 to 1)
+ real(r8), pointer :: frac_h2osfc_col (:) ! col fractional area with surface water greater than zero
+ real(r8), pointer :: h2osoi_vol_col (:,:) ! col volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3] (nlevgrnd)
+ real(r8), pointer :: h2osoi_liq_col (:,:) ! col liquid water (kg/m2) (new) (-nlevsno+1:nlevgrnd)
+ real(r8), pointer :: h2osoi_ice_col (:,:) ! col ice lens (kg/m2) (new) (-nlevsno+1:nlevgrnd)
+
+ ! temperature_vars:
+ real(r8), pointer :: t_soisno_col (:,:) ! col soil temperature (Kelvin) (-nlevsno+1:nlevgrnd)
+ real(r8), pointer :: t_grnd_col (:) ! col ground(-air interface averaged) temperature (Kelvin)
+ real(r8), pointer :: t_h2osfc_col (:) ! col surface-water temperature [Kelvin]
+ real(r8), pointer :: t_nearsurf_col (:) ! col mixed air/veg. temperature near ground surface (for coupling with PFLOTRAN as BC)
+
+ ! canopystate_vars
+ integer , pointer :: alt_indx_col (:) ! col current depth of thaw
+
+
+ ! waterflux_vars:
+ real(r8), pointer :: qflx_top_soil_col (:) ! col net water input into soil from top (mm/s)
+ real(r8), pointer :: qflx_subl_snow_col (:) ! col sublimation rate from snow pack (mm H2O /s) [+]
+ real(r8), pointer :: qflx_evap_soil_col (:) ! col soil surface evaporation (mm H2O/s) (+ = to atm)
+ real(r8), pointer :: qflx_evap_snow_col (:) ! col snow surface evaporation (mm H2O/s) (+ = to atm)
+ real(r8), pointer :: qflx_evap_h2osfc_col (:) ! col evaporation flux from surface water (mm H2O /s) [+ to atm] ! note: the energy unit of orginal definition incorrect
+ real(r8), pointer :: qflx_tran_veg_col (:) ! col vegetation transpiration (mm H2O/s) (+ = to atm)
+ real(r8), pointer :: qflx_rootsoil_col (:,:) ! col p-aggregated vertically-resolved vegetation/soil water exchange (m H2O/s) (+ = to atm)
+
+ real(r8), pointer :: qflx_infl_col (:) ! col infiltration (mm H2O/s)
+ real(r8), pointer :: qflx_surf_col (:) ! col surface runoff (mm H2O/s)
+ real(r8), pointer :: qflx_drain_col (:) ! col sub-surface runoff (mm H2O/s)
+ real(r8), pointer :: qflx_drain_vr_col (:,:) ! col liquid water losted as drainage (mm H2O/s)
+
+ ! energyflux_vars:
+ real(r8), pointer :: htvp_col (:) ! latent heat of vapor of water (or sublimation) [j/kg]
+ real(r8), pointer :: eflx_bot_col (:) ! col heat flux from beneath the soil or ice column (W/m**2)
+ real(r8), pointer :: eflx_soil_grnd_col (:) ! col soil heat flux (W/m**2) [+ = into soil]
+ real(r8), pointer :: eflx_fgr0_snow_col (:) ! col heat flux from snow bottom to first soil layer (W/m**2) [+ = into soil]
+ real(r8), pointer :: eflx_fgr0_h2osfc_col (:) ! col heat flux from surface water bottom to first soil layer (W/m**2) [+ = into soil]
+ real(r8), pointer :: eflx_fgr0_soil_col (:) ! col heat flux from near-surface air to first soil layer (W/m**2) [+ = into soil]
+ real(r8), pointer :: eflx_rnet_soil_col (:) ! net radiation flux between soil layer 1 and above-air, excluding SH and LE (i.e. radiation form only ) (W/m2) [+ = into soil]
+
+ ! soilhydrology_vars:
+ real(r8), pointer :: frost_table_col (:) ! col frost table depth
+ real(r8), pointer :: zwt_col (:) ! col water table depth
+ real(r8), pointer :: zwt_perched_col (:) ! col perched water table depth
+ real(r8), pointer :: qcharge_col (:) ! col aquifer recharge rate (mm/s)
+
+ ! atm2lnd:
+ real(r8), pointer :: forc_pbot_grc (:) ! grid atm pressure (Pa)
+
+ contains
+ procedure , public :: Init
+ procedure , private :: InitAllocate
+ end type clm_interface_th_datatype
+!-------------------------------------------------------------------------------------------------
+
+
+contains
+
+!-------------------------------------------------------------------------------------------------
+ subroutine Init(this, bounds)
+ use decompMod , only : bounds_type
+ class(clm_interface_th_datatype) :: this
+ type(bounds_type), intent(in) :: bounds
+
+ call this%InitAllocate (bounds)
+ end subroutine Init
+!-------------------------------------------------------------------------------------------------
+
+!-------------------------------------------------------------------------------------------------
+
+ subroutine InitAllocate(this, bounds)
+ ! USES
+ use clm_varpar , only : nlevsno, nlevgrnd
+ use clm_varcon , only : spval
+ use decompMod , only : bounds_type
+
+ ! ARGUMENTS:
+ real(r8) :: ival = 0.0_r8 ! initial value
+ class(clm_interface_th_datatype) :: this
+ type(bounds_type), intent(in) :: bounds
+
+ ! LOCAL VARIABLES:
+ integer :: begg, endg
+ integer :: begc, endc
+ integer :: begp, endp
+ !------------------------------------------------------------------------
+ begg = bounds%begg; endg= bounds%endg
+ begc = bounds%begc; endc= bounds%endc
+ begp = bounds%begp; endp= bounds%endp
+
+ !soilstate_vars:
+ allocate(this%soilpsi_col (begc:endc, 1:nlevgrnd)) ; this%soilpsi_col (:,:) = nan
+
+ ! waterstate_vars:
+ allocate(this%frac_sno_eff_col (begc:endc)) ; this%frac_sno_eff_col (:) = nan
+ allocate(this%frac_h2osfc_col (begc:endc)) ; this%frac_h2osfc_col (:) = nan
+ allocate(this%h2osoi_liq_col (begc:endc,-nlevsno+1:nlevgrnd)) ; this%h2osoi_liq_col (:,:) = nan
+ allocate(this%h2osoi_ice_col (begc:endc,-nlevsno+1:nlevgrnd)) ; this%h2osoi_ice_col (:,:) = nan
+ allocate(this%h2osoi_vol_col (begc:endc, 1:nlevgrnd)) ; this%h2osoi_vol_col (:,:) = nan
+
+ ! temperature_vars:
+ allocate(this%t_soisno_col (begc:endc,-nlevsno+1:nlevgrnd)) ; this%t_soisno_col (:,:) = nan
+ allocate(this%t_grnd_col (begc:endc)) ; this%t_grnd_col (:) = nan
+ allocate(this%t_h2osfc_col (begc:endc)) ; this%t_h2osfc_col (:) = nan
+ allocate(this%t_nearsurf_col (begc:endc)) ; this%t_nearsurf_col (:) = nan
+
+ ! canopystate_vars:
+ allocate(this%alt_indx_col (begc:endc)) ; this%alt_indx_col (:) = huge(1)
+
+ !------------------------------------------------------------------------------------------
+ ! pflotran variables: BEGIN
+ !------------------------------------------------------------------------------------------
+ ! waterflux_vars:
+ allocate(this%qflx_top_soil_col (begc:endc)) ; this%qflx_top_soil_col (:) = ival
+ allocate(this%qflx_evap_h2osfc_col (begc:endc)) ; this%qflx_evap_h2osfc_col (:) = ival
+ allocate(this%qflx_evap_soil_col (begc:endc)) ; this%qflx_evap_soil_col (:) = ival
+ allocate(this%qflx_evap_snow_col (begc:endc)) ; this%qflx_evap_snow_col (:) = ival
+ allocate(this%qflx_subl_snow_col (begc:endc)) ; this%qflx_subl_snow_col (:) = ival
+ allocate(this%qflx_tran_veg_col (begc:endc)) ; this%qflx_tran_veg_col (:) = ival
+ allocate(this%qflx_rootsoil_col (begc:endc,1:nlevgrnd)) ; this%qflx_rootsoil_col (:,:) = ival
+ allocate(this%qflx_infl_col (begc:endc)) ; this%qflx_infl_col (:) = ival
+ allocate(this%qflx_surf_col (begc:endc)) ; this%qflx_surf_col (:) = ival
+ allocate(this%qflx_drain_col (begc:endc)) ; this%qflx_drain_col (:) = ival
+ allocate(this%qflx_drain_vr_col (begc:endc,1:nlevgrnd)) ; this%qflx_drain_vr_col (:,:) = ival
+
+
+ ! energyflux_vars:
+ allocate( this%htvp_col (begc:endc)) ; this%htvp_col (:) = ival
+ allocate( this%eflx_bot_col (begc:endc)) ; this%eflx_bot_col (:) = ival
+ allocate( this%eflx_soil_grnd_col (begc:endc)) ; this%eflx_soil_grnd_col (:) = ival
+ allocate( this%eflx_fgr0_soil_col (begc:endc)) ; this%eflx_fgr0_soil_col (:) = ival
+ allocate( this%eflx_fgr0_snow_col (begc:endc)) ; this%eflx_fgr0_snow_col (:) = ival
+ allocate( this%eflx_fgr0_h2osfc_col (begc:endc)) ; this%eflx_fgr0_h2osfc_col (:) = ival
+ allocate( this%eflx_rnet_soil_col (begc:endc)) ; this%eflx_rnet_soil_col (:) = ival
+
+ ! atm2lnd:
+ allocate(this%forc_pbot_grc (begg:endg)) ; this%forc_pbot_grc (:) = ival
+
+ ! soilhydrology_vars:
+ allocate( this%frost_table_col (begc:endc)) ; this%frost_table_col (:) = ival
+ allocate( this%zwt_col (begc:endc)) ; this%zwt_col (:) = ival
+ allocate( this%zwt_perched_col (begc:endc)) ; this%zwt_perched_col (:) = ival
+ allocate( this%qcharge_col (begc:endc)) ; this%qcharge_col (:) = ival
+
+ end subroutine InitAllocate
+!-------------------------------------------------------------------------------------------------
+
+end module clm_interface_thType
diff --git a/components/clm/src/main/clm_pflotran_interfaceMod.F90 b/components/clm/src/main/clm_pflotran_interfaceMod.F90
deleted file mode 100644
index 0912c6c9dcc0..000000000000
--- a/components/clm/src/main/clm_pflotran_interfaceMod.F90
+++ /dev/null
@@ -1,3657 +0,0 @@
-module clm_pflotran_interfaceMod
-!#define FLEXIBLE_POOLS
-!----------------------------------------------------------------------------------------------
-! CLM-PFLOTRAN soil bgc coupling interface
-! authors: Fengming YUAN1, Gautam Bishit1,2, and Guoping Tang1
-!
-! 1.Climate Change Science Institute & Environmental Science Division
-! Oak Ridge National Laboratory
-!
-! 2.Lawrence Berkley National Laboratory
-!
-! date: 2012 - 2015
-! modified (based on clm_bgc_interface): 8/28/2015, wgs
-!----------------------------------------------------------------------------------------------
-
-#include "shr_assert.h"
-
- !-----------------------------------------------------------------------
- !BOP
- !
- ! !MODULE: clm_pflotran_interfaceMod
- !
- ! !DESCRIPTION:
- ! Performs
- !
- ! !USES:
-
- ! clm g/l/c/p constants
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use shr_kind_mod , only : r8 => shr_kind_r8
- use GridcellType , only : grc_pp
- use LandunitType , only : lun_pp
- use ColumnType , only : col_pp
- use VegetationType , only : veg_pp
-
- use decompMod , only : bounds_type
-
- ! (dummy) variable definitions
- !! (wgs,8/28/2015): variables below are replaced by clm_bgc_data
-
-! use atm2lndType , only : atm2lnd_type
-! use SoilStateType , only : soilstate_type
-! use WaterStateType , only : waterstate_type
-! use WaterFluxType , only : waterflux_type
-! use SoilHydrologyType , only : soilhydrology_type
-! use TemperatureType , only : temperature_type
-! use EnergyFluxType , only : energyflux_type
-! use SoilWaterRetentionCurveMod, only : soil_water_retention_curve_type
-!
-! use CNStateType , only : cnstate_type
-! use CNCarbonFluxType , only : carbonflux_type
-! use CNCarbonStateType , only : carbonstate_type
-! use CNNitrogenFluxType , only : nitrogenflux_type
-! use CNNitrogenStateType , only : nitrogenstate_type
-!
-! use ch4Mod , only : ch4_type
-!
-! use PhotosynthesisType , only : photosyns_type
-! use cropType , only : crop_type
-! use CanopyStateType , only : canopystate_type
-! use PhosphorusStateType , only : phosphorusstate_type
-! use PhosphorusFluxType , only : phosphorusflux_type
-
-
- ! PFLOTRAN thc module switchs for coupling with CLM45-CN
- use clm_varctl , only : use_pflotran, pf_tmode, pf_hmode, pf_cmode
- use clm_varctl , only : pf_surfaceflow, pf_frzmode
- use clm_varctl , only : initth_pf2clm
-
- ! most used constants in this module
- use clm_varpar , only : nlevsoi, nlevgrnd, nlevdecomp, nlevdecomp_full
- use clm_varpar , only : ndecomp_pools
- use clm_varpar , only : max_patch_per_col
- use clm_varcon , only : denh2o, denice, tfrz, dzsoi_decomp
- use landunit_varcon , only : istsoil, istcrop
-
- ! misc.
- use abortutils , only : endrun
-
-! use clm_bgc_interfaceMod
- use clm_bgc_interface_data, only : clm_bgc_interface_data_type
-
-
-#ifdef CLM_PFLOTRAN
- use clm_pflotran_interface_data
- use pflotran_clm_main_module
- use pflotran_clm_setmapping_module
-#endif
-
- ! !PUBLIC TYPES:
- implicit none
-
- save
-
- private ! By default everything is private
-
-#ifdef CLM_PFLOTRAN
- type(pflotran_model_type), pointer, public :: pflotran_m
-#endif
- !
- character(len=256), private:: pflotran_prefix = ''
- character(len=32), private :: restart_stamp = ''
-
- real(r8), parameter :: rgas = 8.3144621d0 ! m3 Pa K-1 mol-1
-
- ! !PUBLIC MEMBER FUNCTIONS:
- public :: clm_pf_readnl
-
- ! wrappers around '#ifdef CLM_PFLOTRAN .... #endif' block statements to maintain sane runtime behavior
- ! when pflotran is not available.
- public :: clm_pf_interface_init
- public :: clm_pf_set_restart_stamp
- public :: clm_pf_run
- public :: clm_pf_write_restart
- public :: clm_pf_finalize
-
-
-#ifdef CLM_PFLOTRAN
- ! private work functions that truely require '#ifdef CLM_PFLOTRAN .... #endif'
- private :: interface_init
- private :: pflotran_run_onestep
- private :: pflotran_write_checkpoint
- private :: pflotran_finalize
- private :: get_clm_soil_properties
- private :: get_clm_soil_th
- private :: get_clm_iceadj_porosity
- private :: get_clm_bcwflx
- private :: get_clm_bceflx
- private :: get_clm_bgc_conc
- private :: get_clm_bgc_rate
- private :: update_soil_temperature_pf2clm
- private :: update_soil_moisture_pf2clm
- private :: update_soil_bgc_pf2clm
- private :: update_bgc_gaslosses_pf2clm
-! private :: update_bcflow_pf2clm !!comment out currently for bgc-only
-
-#endif
-
-contains
-
-!-----------------------------------------------------------------------
-!
-! public interface functions allowing runtime behavior regardless of
-! whether pflotran is compiled in.
-!
-!-----------------------------------------------------------------------
-
- !-----------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: clm_pf_readnl
- !
- ! !INTERFACE:
- subroutine clm_pf_readnl( NLFilename )
- !
- ! !DESCRIPTION:
- ! Read namelist for clm-pflotran interface
- !
- ! !USES:
- use clm_varctl , only : iulog
- use spmdMod , only : masterproc, mpicom
- use fileutils , only : getavu, relavu, opnfil
- use clm_nlUtilsMod, only : find_nlgroup_name
- use shr_nl_mod , only : shr_nl_find_group_name
- use shr_mpi_mod , only : shr_mpi_bcast
-
- implicit none
-
- ! !ARGUMENTS:
- character(len=*), intent(IN) :: NLFilename ! Namelist filename
- ! !LOCAL VARIABLES:
- integer :: ierr ! error code
- integer :: unitn ! unit for namelist file
- character(len=32) :: subname = 'clm_pf_readnl' ! subroutine name
- !EOP
- !-----------------------------------------------------------------------
- namelist / clm_pflotran_inparm / pflotran_prefix
-
- ! ----------------------------------------------------------------------
- ! Read namelist from standard namelist file.
- ! ----------------------------------------------------------------------
-
- if ( masterproc )then
-
- unitn = getavu()
- write(iulog,*) 'Read in clm-pflotran namelist'
- call opnfil (NLFilename, unitn, 'F')
- call shr_nl_find_group_name(unitn, 'clm_pflotran_inparm', status=ierr)
- if (ierr == 0) then
- read(unitn, clm_pflotran_inparm, iostat=ierr)
- if (ierr /= 0) then
- call endrun(msg=subname //':: ERROR: reading clm_pflotran_inparm namelist.'//&
- errMsg(__FILE__, __LINE__))
- end if
- end if
- call relavu( unitn )
- write(iulog, '(/, A)') " clm-pflotran namelist:"
- write(iulog, '(A, " : ", A,/)') " pflotran_prefix", trim(pflotran_prefix)
- end if
-
- ! Broadcast namelist variables read in
- call shr_mpi_bcast(pflotran_prefix, mpicom)
-
- end subroutine clm_pf_readnl
-
- !-----------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: clm_pf_set_restart_stamp
- !
- ! !INTERFACE:
- subroutine clm_pf_set_restart_stamp(clm_restart_filename)
- !
- ! !DESCRIPTION: Set the pflotran restart date stamp. Note we do NOT
- ! restart here, that gets handled by pflotran's internal
- ! initialization during interface_init_clm_pf()
- !
- ! !USES:
- ! !ARGUMENTS:
- character(len=256), intent(in) :: clm_restart_filename
- ! !LOCAL VARIABLES:
- integer :: name_length, start_pos, end_pos
- character(len=32) :: clm_stamp
- !EOP
- !-----------------------------------------------------------------------
-
- ! clm restart file name is of the form:
- ! ${CASE_NAME}.clm2.r.YYYY-MM-DD-SSSSS.nc
- ! we need to extract the: YYYY-MM-DD-SSSSS
- write(*, '("clm-pf : clm restart file name : ", A/)') trim(clm_restart_filename)
- name_length = len(trim(clm_restart_filename))
- start_pos = name_length - 18
- end_pos = name_length - 3
- clm_stamp = clm_restart_filename(start_pos : end_pos)
- write(*, '("clm-pf : clm date stamp : ", A/)') trim(clm_stamp)
- restart_stamp = clm_stamp
-
- end subroutine clm_pf_set_restart_stamp
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: pflotran_not_available
- !
- ! !INTERFACE:
- subroutine pflotran_not_available(subname)
- !
- ! !DESCRIPTION:
- ! Print an error message and abort.
- !
- ! !USES:
-
- ! !ARGUMENTS:
- implicit none
- character(len=*), intent(in) :: subname
- ! !LOCAL VARIABLES:
- !EOP
- !-----------------------------------------------------------------------
- call endrun(trim(subname) // ": ERROR: CLM-PFLOTRAN interface has not been compiled " // &
- "into this version of CLM.")
- end subroutine pflotran_not_available
-
-
-!******************************************************************************************!
-!
-! public interface function wrappers
-!
-!------------------------------------------------------------------------------------------!
-
- !-----------------------------------------------------------------------------
- subroutine clm_pf_interface_init(bounds)
-
- implicit none
-
- type(bounds_type), intent(in) :: bounds ! bounds
-
- character(len=256) :: subname = "clm_pf_interface_init()"
-
-#ifdef CLM_PFLOTRAN
- call interface_init(bounds)
-#else
- call pflotran_not_available(subname)
-#endif
- end subroutine clm_pf_interface_init
-
- !--------------------------------------------------------------------------------------------
-
- subroutine clm_pf_run(clm_bgc_data,bounds, &
- num_soilc, filter_soilc)
-
- implicit none
-
- ! !ARGUMENTS:
- type(bounds_type) , intent(in) :: bounds
- integer , intent(in) :: num_soilc ! number of soil columns in filter
- integer , intent(in) :: filter_soilc(:) ! filter for soil columns
-! integer , intent(in) :: num_soilp ! number of soil patches in filter
-! integer , intent(in) :: filter_soilp(:) ! filter for soil patches
-! type(atm2lnd_type) , intent(in) :: atm2lnd_vars
-! type(waterstate_type) , intent(inout) :: waterstate_vars
-! type(waterflux_type) , intent(inout) :: waterflux_vars
-! type(soilstate_type) , intent(inout) :: soilstate_vars
-! type(temperature_type) , intent(inout) :: temperature_vars
-! type(soilhydrology_type) , intent(inout) :: soilhydrology_vars
-! type(energyflux_type) , intent(inout) :: energyflux_vars
-! class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve
-!
-! type(cnstate_type) , intent(inout) :: cnstate_vars
-! type(carbonflux_type) , intent(inout) :: carbonflux_vars
-! type(carbonstate_type) , intent(inout) :: carbonstate_vars
-! type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
-! type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
-! type(ch4_type) , intent(inout) :: ch4_vars
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
-
- !-----------------------------------------------------------------------
-
- character(len=256) :: subname = "clm_pf_run"
-
-#ifdef CLM_PFLOTRAN
- call pflotran_run_onestep(clm_bgc_data,bounds, &
- num_soilc, filter_soilc)
-#else
- call pflotran_not_available(subname)
-#endif
- end subroutine clm_pf_run
-
- !-----------------------------------------------------------------------------
- subroutine clm_pf_write_restart(date_stamp)
-
- implicit none
- character(len=*), intent(in) :: date_stamp
-
- character(len=32) :: subname = "clm_pf_write_restart"
-
-#ifdef CLM_PFLOTRAN
- call pflotran_write_checkpoint(date_stamp)
-#else
- call pflotran_not_available(subname)
-#endif
- end subroutine clm_pf_write_restart
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !ROUTINE: clm_pf_finalize
- !
- ! !INTERFACE:
- subroutine clm_pf_finalize()
-
- implicit none
- character(len=256) :: subname = "clm_pf_finalize"
-
-#ifdef CLM_PFLOTRAN
- call pflotran_finalize()
-#else
- call pflotran_not_available(subname)
-#endif
- end subroutine clm_pf_finalize
-
-
-
-
-#ifdef CLM_PFLOTRAN
-
-!************************************************************************************!
-! The following is private and requires explicit coupling between CLM and PFLOTRAN
-!
-!------------------------------------------------------------------------------------!
-!
-
- !-----------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: interface_init
- !
- ! !INTERFACE:
- subroutine interface_init(bounds)
- !
- ! !DESCRIPTION:
- ! initialize the pflotran iterface
- !
- ! !USES:
- use clm_varctl , only : iulog
- use decompMod , only : get_proc_global, ldecomp
- use spmdMod , only : mpicom, masterproc
- use domainMod , only : ldomain
-
- use CNDecompCascadeConType , only : decomp_cascade_con
-
- use abortutils , only : endrun
-
- use clm_time_manager, only : nsstep, nestep
-
- ! pflotran
- use Option_module!, only : printErrMsg
- use Simulation_Base_class, only : simulation_base_type
- use Simulation_Subsurface_class, only : subsurface_simulation_type
- use Realization_class, only : realization_type
- use PFLOTRAN_Constants_module
- !
- ! !ARGUMENTS:
-
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-#include "finclude/petscviewer.h"
-
- !
- ! !REVISION HISTORY:
- ! Created by Gautam Bisht
- ! Revised by Fengming Yuan, CCSI-ORNL
- !
- !EOP
- !
- ! LOCAL VARAIBLES:
-
- type(bounds_type), intent(in) :: bounds ! bounds
-
- integer :: numg ! total number of gridcells across all processors
- integer :: numl ! total number of landunits across all processors
- integer :: numc ! total number of columns across all processors
- integer :: nump ! total number of pfts across all processors
- integer :: g,l,c,j ! indices
- integer :: gcount, cellcount
-
- integer, pointer :: clm_cell_ids_nindex(:)
- integer, pointer :: clm_2dtop_cell_ids_nindex(:)
- integer, pointer :: clm_2dbot_cell_ids_nindex(:)
- integer :: clm_cell_npts
- integer :: clm_2dtop_npts
- integer :: clm_2dbot_npts
-
- !type(pflotran_model_type), pointer:: pflotran_m
- class(realization_type), pointer :: realization
- type(option_type), pointer :: option
- PetscErrorCode :: ierr
-
- character(len= 32) :: subname = 'interface_init' ! subroutine name
-
- associate( &
- ! Assign local pointers to derived subtypes components (gridcell-level)
- latdeg => grc_pp%latdeg , & ! [real(r8) (:)] latitude (degree)
- londeg => grc_pp%londeg , & ! [real(r8) (:)] longitude (degree)
- area => grc_pp%area , & ! [real(r8) (:)] total land area per gridcell (km^2)
- gindex => grc_pp%gindex , & ! [real(r8) (:)] longitude (degree)
- ! Assign local pointers to derived subtypes components (landunit-level)
- ltype => lun_pp%itype , & ! [integer (:)] landunit type index
- ! Assign local pointer to derived subtypes components (column-level)
- cgridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
- clandunit => col_pp%landunit , & ! [integer (:)] landunit index of column
- cwtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell
- ctype => col_pp%itype , & ! [integer (:)] column type index
- topo => col_pp%glc_topo , & ! surface elevation (m)
- micro_sigma=> col_pp%micro_sigma, & ! microtopography pdf sigma (m)
- slope => col_pp%topo_slope , & ! gridcell topographic slope
- topo_std => col_pp%topo_std & ! gridcell elevation standard deviation
- )
-
- !------------------------------------------------------------------------
-
- do c = bounds%begc, bounds%endc
- l = col_pp%landunit(c)
- if (.not.(ltype(l)==istsoil .or. ltype(l)==istcrop) .and. col_pp%active(c)) then
- write (iulog,*) 'WARNING: Land Unit type of active Columns of non-soil/crop type found within the domain'
- write (iulog,*) 'CLM-CN -- PFLOTRAN does not support this land unit presently'
- write (iulog,*) 'So, DEactive the column: ', c
-
- col_pp%active(c) = .false.
-
- endif
-
- enddo ! do c = bounds%begc, bounds%endc
-
- if (masterproc) then
- write(iulog,*) '%%-----------------------------------------------------%%'
- write(iulog,*) '%% clm_pf_interface_init %%'
- write(iulog,*) '%%-----------------------------------------------------%%'
- write(iulog,*) ' '
- endif
-
-
- ! Determine necessary indices
- call get_proc_global(numg, numl, numc, nump)
-
- !------------------------------------------------------------------------
- allocate(pflotran_m)
-
- ! Create PFLOTRAN model
- call pflotranModelCreate(mpicom, pflotran_prefix, pflotran_m)
- option => pflotran_m%option
-
- call pflotranModelSetupMappingfiles(pflotran_m)
-
- ! initialize pflotran model
- call pflotranModelStepperRunInit(pflotran_m)
-
- ! PFLOTRAN ck file NOT works well when coupling with CLM.
- ! So it's off now and restart PF from CLM.
- !restart_stamp = ""
- !call pflotranModelSetupRestart(pflotran_m, restart_stamp)
- initth_pf2clm = .false.
- !if (restart_stamp .ne. "") then
- ! initth_pf2clm = .true.
- !endif
-
- ! Initialize PETSc vector for data transfer between CLM and PFLOTRAN
- call CLMPFLOTRANIDataInit()
-
- clm_pf_idata%nzclm_mapped = nlevsoi ! the soil layer no. mapped btw CLM and PF for data-passing
-
- select type (simulation => pflotran_m%simulation)
- class is (subsurface_simulation_type)
- realization => simulation%realization
- class default
- pflotran_m%option%io_buffer = "This version of clm-pflotran only works with subsurface simulations."
- write(*, '(/A/)') pflotran_m%option%io_buffer
- call printErrMsg(pflotran_m%option)
- end select
-
- if (pflotran_m%option%iflowmode == TH_MODE .or. pflotran_m%option%iflowmode == Richards_MODE) then
- pflotran_m%option%io_buffer = "This version of clm-pflotran Richards_mode or TH_mode has NOT yet well tested."
- write(*, '(/A/)') pflotran_m%option%io_buffer
- call printErrMsg(pflotran_m%option)
- endif
-
- if(pflotran_m%option%nsurfflowdof > 0) then
- pflotran_m%option%io_buffer = "This version of clm-pflotran DOES NOT work with PF Surface simulation."
- write(*, '(/A/)') pflotran_m%option%io_buffer
- call printErrMsg(pflotran_m%option)
- endif
- pf_surfaceflow = .false.
-
- !------------------------------------------------
-
- ! Compute number of cells in CLM domain.
- clm_cell_npts = (bounds%endg - bounds%begg + 1)*clm_pf_idata%nzclm_mapped
- clm_2dtop_npts = (bounds%endg - bounds%begg + 1)
- clm_2dbot_npts = (bounds%endg - bounds%begg + 1)
- allocate(clm_cell_ids_nindex( 1:clm_cell_npts))
- allocate(clm_2dtop_cell_ids_nindex(1:clm_2dtop_npts))
- allocate(clm_2dbot_cell_ids_nindex(1:clm_2dbot_npts))
-
- ! Save cell IDs of CLM grid
- cellcount = 0
- do g = bounds%begg, bounds%endg
- gcount = g - bounds%begg + 1
-
- do j = 1, clm_pf_idata%nzclm_mapped
- cellcount = cellcount + 1
- !clm_cell_ids_nindex(cellcount) = (ldecomp%gdc2glo(g)-1)*nlevsoi + j - 1
- ! maintain CLM each processor's grids to match up with PF (this appears saving a lot of data communications)
- clm_cell_ids_nindex(cellcount) = (g-1)*clm_pf_idata%nzclm_mapped + j - 1
- enddo
-
- clm_2dtop_cell_ids_nindex(gcount) = (g-1)*clm_pf_idata%nzclm_mapped
-
- clm_2dbot_cell_ids_nindex(gcount) = g*clm_pf_idata%nzclm_mapped-1
- enddo
-
- ! CLM: 3-D Subsurface domain (local and ghosted cells)
- clm_pf_idata%nlclm_sub = clm_cell_npts
- clm_pf_idata%ngclm_sub = clm_cell_npts
-
- ! CLM: Surface/Bottom cells of subsurface domain (local and ghosted cells)
- clm_pf_idata%nlclm_2dtop = (bounds%endg - bounds%begg + 1)
- clm_pf_idata%ngclm_2dtop = (bounds%endg - bounds%begg + 1)
-
- ! CLM: bottom face of subsurface domain
- clm_pf_idata%nlclm_2dbot = (bounds%endg - bounds%begg + 1)
- clm_pf_idata%ngclm_2dbot = (bounds%endg - bounds%begg + 1)
-
- ! PFLOTRAN: 3-D Subsurface domain (local and ghosted cells)
- clm_pf_idata%nlpf_sub = realization%patch%grid%nlmax
- clm_pf_idata%ngpf_sub = realization%patch%grid%ngmax
-
- ! PFLOTRAN: surface of subsurface domain (local and ghosted cells)
- !if (pflotran_m%option%iflowmode == RICHARDS_MODE) then
- ! clm_pf_idata%nlpf_2dtop = pflotranModelNSurfCells3DDomain(pflotran_m) ! this will be overwritten in Mapping below
- ! clm_pf_idata%ngpf_2dtop = pflotranModelNSurfCells3DDomain(pflotran_m)
- !endif
-
- ! For CLM/PF: ground surface NOT defined, so need to set the following to zero.
- clm_pf_idata%nlclm_srf = 0
- clm_pf_idata%ngclm_srf = 0
- clm_pf_idata%nlpf_srf = 0
- clm_pf_idata%ngpf_srf = 0
-
- ! Initialize maps for transferring data between CLM and PFLOTRAN.
- call pflotranModelInitMapping(pflotran_m, clm_cell_ids_nindex, &
- clm_cell_npts, CLM_SUB_TO_PF_SUB)
- call pflotranModelInitMapping(pflotran_m, clm_cell_ids_nindex, &
- clm_cell_npts, PF_SUB_TO_CLM_SUB)
-
- !
- if (pflotran_m%option%iflowmode == RICHARDS_MODE .or. &
- pflotran_m%option%iflowmode == TH_MODE) then
- call pflotranModelInitMapping(pflotran_m, clm_2dtop_cell_ids_nindex, &
- clm_2dtop_npts, CLM_2DTOP_TO_PF_2DTOP)
- call pflotranModelInitMapping(pflotran_m, clm_2dtop_cell_ids_nindex, &
- clm_2dtop_npts, PF_2DTOP_TO_CLM_2DTOP)
-
- call pflotranModelInitMapping(pflotran_m, clm_2dbot_cell_ids_nindex, &
- clm_2dbot_npts, CLM_2DBOT_TO_PF_2DBOT)
- call pflotranModelInitMapping(pflotran_m, clm_2dbot_cell_ids_nindex, &
- clm_2dbot_npts, PF_2DBOT_TO_CLM_2DBOT)
- endif
-
- ! the CLM-CN/BGC decomposing pool size
- clm_pf_idata%ndecomp_pools = ndecomp_pools
-
- ! Allocate vectors for data transfer between CLM and PFLOTRAN.
- call CLMPFLOTRANIDataCreateVec(MPI_COMM_WORLD)
-
- ! the CLM-CN/BGC decomposing pool if varying cn ratios, and names.
- clm_pf_idata%floating_cn_ratio = decomp_cascade_con%floating_cn_ratio_decomp_pools(1:ndecomp_pools)
- clm_pf_idata%decomp_pool_name = decomp_cascade_con%decomp_pool_name_history(1:ndecomp_pools)
-
- ! if BGC is on
- if(pflotran_m%option%ntrandof > 0) then
- call pflotranModelGetRTspecies(pflotran_m)
- endif
-
- ! Get pflotran top surface area
- call pflotranModelGetTopFaceArea(pflotran_m)
-
- deallocate(clm_cell_ids_nindex)
- deallocate(clm_2dtop_cell_ids_nindex)
- deallocate(clm_2dbot_cell_ids_nindex)
-
-!-------------------------------------------------------------------------------------
- ! coupled module controls betweeen PFLOTRAN and CLM45 (F.-M. Yuan, Aug. 2013)
- if(pflotran_m%option%iflowmode==RICHARDS_MODE) then
- pf_hmode = .true.
- pf_tmode = .false.
- pf_frzmode = .false.
-
- elseif(pflotran_m%option%iflowmode==TH_MODE) then
- pf_hmode = .true.
- pf_tmode = .true.
- if (pflotran_m%option%use_th_freezing) then
- pf_frzmode = .true.
- else
- pf_frzmode = .false.
- endif
-
- endif
-
- if(pflotran_m%option%ntrandof.gt.0) then
- pf_cmode = .true. ! initialized as '.false.' in clm initialization
- endif
-
-!-------------------------------------------------------------------------------------
-
- end associate
- end subroutine interface_init
-
- !-----------------------------------------------------------------------------
- !
- ! !SUBROUTINE: pflotran_run_onestep
- !
- ! !INTERFACE:
-
- subroutine pflotran_run_onestep(clm_bgc_data,bounds, &
- num_soilc, filter_soilc)
- !
- ! !DESCRIPTION:
- !
- ! F.-M. YUAN: based on Gautam's 'step_th_clm_pf',
- ! 'chemistry' (PF_CMODE) added (Sept. 6, 2013)
- !
- ! !USES:
-
-
-! use clm_pflotran_interface_data
- use PFLOTRAN_Constants_module
-
- use clm_time_manager , only : get_step_size, get_nstep, nsstep, nestep, &
- is_first_step, is_first_restart_step
-
- !use clm_varctl , only : use_century_decomp
- !use CNDecompCascadeCNMod , only : decomp_rate_constants_cn
- !use CNDecompCascadeBGCMod, only : decomp_rate_constants_bgc
-
- implicit none
-
- type(bounds_type) , intent(in) :: bounds
- integer, intent(in) :: num_soilc ! number of soil columns in filter
- integer, intent(in) :: filter_soilc(:) ! filter for soil columns
-! integer, intent(in) :: num_soilp ! number of soil pfts in filter
-! integer, intent(in) :: filter_soilp(:) ! filter for soil pfts
-
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
-
- !LOCAL VARIABLES:
- real(r8) :: dtime ! land model time step (sec)
- integer :: nstep ! time step number
- integer :: total_clmstep ! total clm time step number
- logical :: ispfprint= .TRUE. ! let PF printout or not
- logical :: isinitpf = .FALSE. ! (re-)initialize PF from CLM or not
-
-#ifdef CLM_PF_DEBUG
- real(r8) :: t0, t1, t2, t3
-#endif
-
- !-----------------------------------------------------------------------
-
- nstep = get_nstep() - nsstep
- dtime = get_step_size()
-
- if (is_first_step() .or. is_first_restart_step()) then
- isinitpf = .TRUE.
- else
- isinitpf = .FALSE.
- endif
-
-#ifdef CLM_PF_DEBUG
-if(nstep>=48*210 .and. nstep<=48*211) then
- call cpu_time(t0)
- if(pflotran_m%option%myrank .eq. pflotran_m%option%io_rank) then
- write(pflotran_m%option%myrank+200,*) '------------------------------------------------------- '
- write(pflotran_m%option%myrank+200,*) '------- checking CLM-PFLOTRAN timing - nstep = ', nstep
- write(pflotran_m%option%myrank+200,*) 'CPU_time @check-point 0: ', t0
- endif
-endif
-#endif
-
-
- ! (0)
- if (isinitpf) then
- total_clmstep = nestep - nsstep
- ispfprint = .true. ! turn-on or shut-off PF's *.h5 output
- call pflotranModelUpdateFinalWaypoint(pflotran_m, total_clmstep*dtime, ispfprint)
-
- ! Set CLM soil properties onto PFLOTRAN grid
-
- call get_clm_soil_properties(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- call pflotranModelSetSoilProp(pflotran_m)
-
- ! if initializing soil 'TH' states from CLM to pflotran
- if (.not.initth_pf2clm) then
- call get_clm_soil_th(clm_bgc_data,initth_pf2clm, initth_pf2clm, &
- bounds, num_soilc, filter_soilc)
-
- if (pf_hmode) then
- ! directly pass TH to internal PF vec (field%, work%)
- call pflotranModelSetInternalTHStatesfromCLM(pflotran_m)
- else
- ! pass TH to global_auxvar
- call pflotranModelUpdateTHfromCLM(pflotran_m, pf_hmode, pf_tmode)
- end if
-
- ! if initializaing CLM's H states from pflotran (only H mode now)
- else
- call pflotranModelGetSaturationFromPF(pflotran_m) ! hydrological states
- call update_soil_moisture_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- end if
-
- ! the following is for some specific PF's hydrological parameters useful to constrain H source/sink or BC
- if (pf_hmode) then
- call pflotranModelGetSoilPropFromPF(pflotran_m)
- end if
-
- endif !!if (isinitpf)
-
- ! (1) passing TH states from CLM to PF, if not H/TH mode NOT on in PF, every CLM time-step
-
- ! if PF T/H mode not available, have to pass those from CLM to global variable in PF to drive BGC/H
- if ((.not.pf_tmode .or. .not.pf_hmode) .and. (.not.isinitpf)) then
- call get_clm_soil_th(clm_bgc_data,pf_tmode, pf_hmode, &
- bounds, num_soilc, filter_soilc)
-
- call pflotranModelUpdateTHfromCLM(pflotran_m, pf_hmode, pf_tmode)
- endif
-
- ! ice-len adjusted porostiy
- if (.not.pf_frzmode) then
- call get_clm_iceadj_porosity(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- call pflotranModelResetSoilPorosityFromCLM(pflotran_m)
- endif
-
- ! (2) pass CLM water fluxes to CLM-PFLOTRAN interface
- if (pf_hmode) then !if coupled 'H' mode between CLM45 and PFLOTRAN
- call get_clm_bcwflx(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- ! pass flux 'vecs' from CLM to pflotran
- call pflotranModelUpdateHSourceSink(pflotran_m) ! H SrcSink
- call pflotranModelSetSoilHbcsFromCLM(pflotran_m) ! H BC
- end if
-
- ! (3) CLM thermal BC to PFLOTRAN
- if (pf_tmode) then
- call get_clm_bceflx(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- call pflotranModelUpdateSubsurfTCond(pflotran_m) ! SrcSink and T bc
- end if
-
- ! (4)
- if (pf_cmode) then
- ! (4a) for checking CLM's T/H response functions (TODO - also for passing decomposition rate to PF if needed)
- !if (use_century_decomp) then
- ! call decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc)
- !else
- ! call decomp_rate_constants_cn(bounds, num_soilc, filter_soilc)
- !end if
-
- ! (4b) reset PFLOTRAN bgc state variables from CLM-CN, every CLM time-step
-! if (isinitpf) then ! NOTE: if only initialize ONCE, uncomment this 'if...endif' block
-
- call get_clm_bgc_conc(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- call pflotranModelSetBgcConcFromCLM(pflotran_m)
-
- if ( (.not.pf_hmode .or. .not.pf_frzmode)) then
- ! this is needed, because at step 0, PF's interface data is empty
- !which causes Aq. conc. adjustment balance issue
- call pflotranModelGetSaturationFromPF(pflotran_m)
- endif
-! endif ! NOTE: if only initialize ONCE, uncomment this 'if...endif' block
-
- ! MUST reset PFLOTRAN soil aq. bgc state variables due to liq. water volume change
- ! when NOT coupled with PF Hydrology or NOT in freezing-mode (porosity will be forced to vary from CLM)
- if (.not.pf_hmode .or. .not.pf_frzmode) then
- call pflotranModelUpdateAqConcFromCLM(pflotran_m)
- endif
-
- ! (4c) bgc rate (source/sink) from CLM to PFLOTRAN
- call get_clm_bgc_rate(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- call pflotranModelSetBgcRatesFromCLM(pflotran_m)
-!write(*,*)">>>DEBUG | pflotranModelSetBgcRatesFromCLM"
- endif
-
-#ifdef CLM_PF_DEBUG
-if(nstep>=48*210 .and. nstep<=48*211) then
- call cpu_time(t1)
- if(pflotran_m%option%myrank .eq. pflotran_m%option%io_rank) then
- write(pflotran_m%option%myrank+200,*) 'CPU_time elapsed @check-point 1 - 0: ', t1-t0
- endif
-endif
-#endif
-
-write(*,*)">>>DEBUG | pflotranModelStepperRunTillPauseTime: BEG...PFLOTRAN"
- ! (5) the main callings of PFLOTRAN
- call pflotranModelStepperRunTillPauseTime( pflotran_m, (nstep+1.0d0)*dtime, dtime, .false. )
-
-write(*,*)">>>DEBUG | pflotranModelStepperRunTillPauseTime: END...CONTINUE..."
-
-#ifdef CLM_PF_DEBUG
-if(nstep>=48*210 .and. nstep<=48*211) then
- call cpu_time(t2)
- if(pflotran_m%option%myrank .eq. pflotran_m%option%io_rank) then
- write(pflotran_m%option%myrank+200,*) 'CPU_time elapsed @check-point 2 - 1: ', t2-t1
- endif
-endif
-#endif
-
- ! (6) update CLM variables from PFLOTRAN
- if (pf_hmode) then
- call pflotranModelGetSaturationFromPF(pflotran_m) ! hydrological states
-
- call update_soil_moisture_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- endif
-
- if (pf_tmode) then
- call pflotranModelGetTemperatureFromPF(pflotran_m) ! thermal states
-
- call update_soil_temperature_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- endif
-
- ! bgc variables
- if (pf_cmode) then
- call pflotranModelGetBgcVariablesFromPF(pflotran_m)
-
- call update_soil_bgc_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- ! need to save the current time-step PF porosity/liq. saturation for bgc species mass conservation
- ! if CLM forced changing them into PF at NEXT timestep
- if (.not.pf_hmode .or. .not.pf_frzmode) then
- call pflotranModelGetSaturationFromPF(pflotran_m)
- endif
- endif
-
- ! the actual infiltration/runoff/drainage and solute flux with BC, if defined,
- ! are retrieving from PFLOTRAN using 'update_bcflow_pf2clm' subroutine
- ! TODO: comment out 'update_bcflow_pf2clm' currently
-! if (pf_hmode) then
-! call pflotranModelGetBCMassBalanceDeltaFromPF(pflotran_m )
-
-! call update_bcflow_pf2clm( &
-! bounds, num_soilc, filter_soilc, &
-! atm2lnd_vars, &
-! temperature_vars, energyflux_vars, &
-! waterstate_vars, waterflux_vars)
-
-! !(TODO) bgc BC flows (e.g. runoff/leaching)
-! endif
-
-
-#ifdef CLM_PF_DEBUG
-if(nstep>=48*210 .and. nstep<=48*211) then
- call cpu_time(t3)
- if(pflotran_m%option%myrank .eq. pflotran_m%option%io_rank) then
- write(pflotran_m%option%myrank+200,*) 'CPU_time elapsed @check-point 3 - 2: ', t3-t2
- write(pflotran_m%option%myrank+200,*) 'CPU_time elapsed @check-point 3 - 0: ', t3-t0
- write(pflotran_m%option%myrank+200,*) '------------------------------------------------------- '
- endif
-endif
-#endif
-
- end subroutine pflotran_run_onestep
-
- !-----------------------------------------------------------------------
- !BOP
- !
- ! !ROUTINE: write_checkpoint
- !
- ! !INTERFACE:
- subroutine pflotran_write_checkpoint(date_stamp)
- !
- ! !DESCRIPTION:
- ! Trigger a pflotran checkpoint file to be written
- !
- ! !USES:
- ! !ARGUMENTS:
- character(len=32), intent(in) :: date_stamp ! file name date stamp
-
- ! !LOCAL VARIABLES:
-
- !EOP
- !-----------------------------------------------------------------------
-
- ! temporarily OFF - it's not working well for BGC
- ! So, now must initializing PF variables from CLM each start/restart.
-
- !call pflotranModelStepperCheckpoint(pflotran_m, date_stamp)
-
- end subroutine pflotran_write_checkpoint
-
- !-----------------------------------------------------------------------------
- !
- ! !IROUTINE: pflotran_finalize
- !
- ! !INTERFACE:
- subroutine pflotran_finalize()
- !
- ! !DESCRIPTION:
- !
- ! finalizing pflotran runs and destroying objects
- !
- ! !USES:
-
- implicit none
-
- !-----------------------------------------------------------------------
-
- if (use_pflotran) then
- call pflotranModelDestroy(pflotran_m)
- endif
-
- end subroutine pflotran_finalize
-
-
- ! ============================= GET CLM initial/src-sink/BC to PFLOTRAN ==================================
-
- !-----------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: get_clm_soil_properties
- !
- ! !INTERFACE:
- subroutine get_clm_soil_properties(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- !
- ! !DESCRIPTION:
- ! get soil column physical properties to PFLOTRAN
- !
- ! !USES:
-
- ! pflotran
- !
- ! !ARGUMENTS:
-
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-#include "finclude/petscviewer.h"
-
- !
- ! !REVISION HISTORY:
- ! Created by Gautam Bisht
- ! Revised by Fengming Yuan, CCSI-ORNL
- !
- !EOP
- !
- ! LOCAL VARAIBLES:
-
- type(bounds_type) , intent(in) :: bounds ! bounds
- integer , intent(in) :: num_soilc ! number of column soil points in column filter
- integer , intent(in) :: filter_soilc(:) ! column filter for soil points
-! type(soilstate_type) , intent(in) :: soilstate_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
- integer :: fc, g, l, c, j ! indices
- integer :: gcount, cellcount
-
- character(len= 32) :: subname = 'get_clm_soil_properties' ! subroutine name
-
-
- PetscScalar, pointer :: hksat_x_clm_loc(:) ! hydraulic conductivity in x-dir at saturation (mm H2O /s)
- PetscScalar, pointer :: hksat_y_clm_loc(:) ! hydraulic conductivity in y-dir at saturation (mm H2O /s)
- PetscScalar, pointer :: hksat_z_clm_loc(:) ! hydraulic conductivity in z-dir at saturation (mm H2O /s)
- PetscScalar, pointer :: watsat_clm_loc(:) ! minimum soil suction (mm)
- PetscScalar, pointer :: sucsat_clm_loc(:) ! volumetric soil water at saturation (porosity)
- PetscScalar, pointer :: bsw_clm_loc(:) ! Clapp and Hornberger "b"
- PetscScalar, pointer :: watfc_clm_loc(:)
- PetscScalar, pointer :: bulkdensity_dry_clm_loc(:)
- PetscScalar, pointer :: zsoi_clm_loc(:)
-
- PetscErrorCode :: ierr
-
- associate( &
- ! Assign local pointer to derived subtypes components (column-level)
- clandunit => col_pp%landunit , & ! [integer (:)] landunit index of column
- cgridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
- wtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell
- cactive => col_pp%active , & ! [logical (:)] column active or not
- z => clm_bgc_data%z , & ! [real(r8) (:,:)] layer depth (m)
- dz => clm_bgc_data%dz , & ! [real(r8) (:,:)] layer thickness depth (m)
- zi => col_pp%zi , & ! [real(r8) (:,:)] interface level below a "z" level (m)
- !
- bd => clm_bgc_data%bd_col , & !
- bsw => clm_bgc_data%bsw_col , & ! [real(r8) (:,:)] Clapp and Hornberger "b" (nlevgrnd)
- hksat => clm_bgc_data%hksat_col , & ! [real(r8) (:,:)] hydraulic conductivity at saturation (mm H2O /s) (nlevgrnd)
- sucsat => clm_bgc_data%sucsat_col , & ! [real(r8) (:,:)] minimum soil suction (mm) (nlevgrnd)
- watsat => clm_bgc_data%watsat_col , & ! [real(r8) (:,:)] volumetric soil water at saturation (porosity) (nlevgrnd)
- watfc => clm_bgc_data%watfc_col & ! [real(r8) (:,:)] volumetric soil water at saturation (porosity) (nlevgrnd)
- )
-
-!-------------------------------------------------------------------------------------
-
- call VecGetArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayF90(clm_pf_idata%zsoi_clmp, zsoi_clm_loc, ierr)
- CHKERRQ(ierr)
-
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- if ( wtgcell(c) <= 0._r8 .or. (.not.cactive(c)) ) cycle ! don't assign data to PF for inactive cell
-
- ! Set gridcell and landunit indices
- g = cgridcell(c)
- l = clandunit(c)
- gcount = g - bounds%begg
-
- do j = 1,nlevsoi
- cellcount = gcount*clm_pf_idata%nzclm_mapped + j
-
- if (j <= clm_pf_idata%nzclm_mapped) then
- hksat_x_clm_loc(cellcount) = hksat_x_clm_loc(cellcount) &
- + hksat(c,j)*wtgcell(c)
- hksat_y_clm_loc(cellcount) = hksat_y_clm_loc(cellcount) &
- + hksat(c,j)*wtgcell(c)
- hksat_z_clm_loc(cellcount) = hksat_z_clm_loc(cellcount) &
- + hksat(c,j)*wtgcell(c)
- sucsat_clm_loc(cellcount) = sucsat_clm_loc(cellcount) &
- + sucsat(c,j)*wtgcell(c)
- watsat_clm_loc(cellcount) = watsat_clm_loc(cellcount) &
- + watsat(c,j)*wtgcell(c)
- bsw_clm_loc(cellcount) = bsw_clm_loc(cellcount) &
- + bsw(c,j)*wtgcell(c)
- watfc_clm_loc(cellcount) = watfc_clm_loc(cellcount) &
- + watfc(c,j)*wtgcell(c)
- bulkdensity_dry_clm_loc(cellcount) = bulkdensity_dry_clm_loc(cellcount) &
- + bd(c,j)*wtgcell(c)
-
- zsoi_clm_loc(cellcount) = z(c, j) ! make sure this is right for multiple columns' situation
-
- else
- ! may need to further checking here
- endif
-
- enddo
-
- enddo ! do c = 1, numsoilc
-
-!write(*,'(A40,10E14.6)')">>>DEBUG | hksat_x=",(hksat_x_clm_loc(1:10))
-!write(*,'(A40,10E14.6)')">>>DEBUG | hksat_y=",(hksat_y_clm_loc(1:10))
-!write(*,'(A40,10E14.6)')">>>DEBUG | hksat_z=",(hksat_z_clm_loc(1:10))
-!write(*,'(A40,10E14.6)')">>>DEBUG | sucsat=",(sucsat_clm_loc(1:10))
-!write(*,'(A40,10E14.6)')">>>DEBUG | watsat=",(watsat_clm_loc(1:10))
-!write(*,'(A40,10E14.6)')">>>DEBUG | watfc=",(watfc_clm_loc(1:10))
-!write(*,'(A40,10E14.6)')">>>DEBUG | bulkdensity=",(bulkdensity_dry_clm_loc(1:10))
-
- call VecRestoreArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr)
- CHKERRQ(ierr)
-
- call VecRestoreArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%zsoi_clmp, zsoi_clm_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine get_clm_soil_properties
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !ROUTINE: get_clm_soil_th
- !
- ! !INTERFACE:
- subroutine get_clm_soil_th(clm_bgc_data,pftmode, pfhmode, &
- bounds, num_soilc, filter_soilc)
-
- !
- ! !DESCRIPTION:
- ! update soil temperature/saturation from CLM to PFLOTRAN for driving PF's BGC
- ! if either NOT available inside PFLOTRAN
- !
- ! !USES:
- use clm_time_manager , only : get_nstep
- use shr_const_mod , only : SHR_CONST_G
-
- use PFLOTRAN_Constants_module
-
- ! !ARGUMENTS:
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
- logical , intent(in) :: pftmode, pfhmode
- type(bounds_type) , intent(in) :: bounds ! bounds
- integer , intent(in) :: num_soilc ! number of column soil points in column filter
- integer , intent(in) :: filter_soilc(:) ! column filter for soil points
-! type(atm2lnd_type) , intent(in) :: atm2lnd_vars
-! type(soilstate_type) , intent(in) :: soilstate_vars
-! type(waterstate_type) , intent(in) :: waterstate_vars
-! type(temperature_type) , intent(in) :: temperature_vars
-! class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
- ! !LOCAL VARIABLES:
- integer :: fc, c, g, j, gcount, cellcount ! indices
- real(r8) :: sattmp, psitmp, itheta
- real(r8) :: watmin(num_soilc, nlevsoi)
- real(r8) :: sucmin(num_soilc, nlevsoi)
-
- PetscScalar, pointer :: soilpress_clmp_loc(:)
- PetscScalar, pointer :: soilpsi_clmp_loc(:)
- PetscScalar, pointer :: soillsat_clmp_loc(:)
- PetscScalar, pointer :: soilisat_clmp_loc(:)
- PetscScalar, pointer :: soilt_clmp_loc(:)
- PetscErrorCode :: ierr
-
- !EOP
- !-----------------------------------------------------------------------
- associate ( &
- gridcell => col_pp%gridcell , & ! column's gridcell
- wtgcell => col_pp%wtgcell , & ! column's weight relative to gridcell
- cactive => col_pp%active , & ! [logical (:)] column active or not
- dz => clm_bgc_data%dz , & ! layer thickness depth (m)
-! zi => clm_bgc_data%zi , & ! interface depth (m)
- !
- sucsat => clm_bgc_data%sucsat_col , & ! minimum soil suction (mm) (nlevgrnd)
- bsw => clm_bgc_data%bsw_col , & ! Clapp and Hornberger "b"
- watsat => clm_bgc_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd)
- soilpsi => clm_bgc_data%soilpsi_col , & ! soil water matric potential in each soil layer (MPa)
- !
- h2osoi_liq => clm_bgc_data%h2osoi_liq_col , & ! liquid water (kg/m2)
- h2osoi_ice => clm_bgc_data%h2osoi_ice_col , & ! ice lens (kg/m2)
- !
- t_soisno => clm_bgc_data%t_soisno_col & ! snow-soil temperature (Kelvin)
-! !
-! forc_pbot => atm2lnd_vars%forc_pbot_not_downscaled_grc & ! atmospheric pressure (Pa)
- )
-
- !--------------------------------------------------------------------------------------
-
- call VecGetArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- watmin(:,:) = 0.01_r8
- sucmin(:,:) = 1.e8_r8
-
- soilisat_clmp_loc(:) = 0._r8
- soillsat_clmp_loc(:) = 0._r8
- soilpsi_clmp_loc(:) = 0._r8
- soilpress_clmp_loc(:)= clm_pf_idata%pressure_reference
- soilt_clmp_loc(:) = 0._r8
-
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( wtgcell(c) <= 0._r8 .or. (.not.cactive(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = gridcell(c)
- gcount = g - bounds%begg
- do j = 1, nlevsoi
- cellcount = gcount*clm_pf_idata%nzclm_mapped + j
-
- if (j<=clm_pf_idata%nzclm_mapped) then
- ! this adjusting should be done first, if PF-freezing-mode off, so that the following calculation can be done correctly
- itheta = 0._r8
- if(.not.pf_frzmode) then
- itheta = h2osoi_ice(c,j) / (dz(c,j) * denice)
- itheta = min(itheta, watsat(c,j)-watmin(c,j)/(dz(c,j)*denh2o))
- soilisat_clmp_loc(cellcount) = soilisat_clmp_loc(cellcount) + itheta/watsat(c,j)*wtgcell(c)
- endif
-
- if (.not.pfhmode) then
- ! porosity will be ice-adjusted for PF, if PF freezing-mode is off,
- ! so need to adjust 'psi' so that 'saturation' in PF is correct
- sattmp = h2osoi_liq(c,j) / ((watsat(c,j)-itheta)*dz(c,j)*denh2o)
- sattmp = min(max(sattmp, watmin(c,j)/watsat(c,j)),1._r8)
- soillsat_clmp_loc(cellcount) = soillsat_clmp_loc(cellcount) + sattmp*wtgcell(c)
-
- ! soil matric potential by Clapp-Hornburger method (this is the default used by CLM)
- ! but, this value IS different from what CLM used (not ice-content adjusted)
- ! So that in PF, if not ice-adjusted, the PSI is very small (negative) which implies possible water movement
- psitmp = sucsat(c,j) * (-SHR_CONST_G) * (sattmp**(-bsw(c,j))) ! -Pa
- psitmp = min(max(psitmp,-sucmin(c,j)/SHR_CONST_G),0._r8)
- soilpsi_clmp_loc(cellcount) = soilpsi_clmp_loc(cellcount) + psitmp*wtgcell(c)
- soilpress_clmp_loc(cellcount) = soilpress_clmp_loc(cellcount) + psitmp*wtgcell(c)
-
- endif
-
- if (.not.pftmode) then
- soilt_clmp_loc(cellcount) = soilt_clmp_loc(cellcount) + (t_soisno(c,j)-tfrz)*wtgcell(c)
- endif
-
- endif
-
- enddo
- enddo
-
-!-----------------------------------------------------------------------------
-!write(*,'(A30,12E14.6)')">>>DEBUG | soillsat=", soillsat_clmp_loc(1:10)
-!write(*,'(A30,12E14.6)')">>>DEBUG | gsoilpsi[Pa]=", soilpsi_clmp_loc(1:10)
-!write(*,'(A30,12E14.6)')">>>DEBUG | soilt[oC]=", soilt_clmp_loc(1:10)
-!-----------------------------------------------------------------------------
-
- call VecRestoreArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine get_clm_soil_th
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !ROUTINE: get_clm_iceadj_porosity
- !
- ! !INTERFACE:
- subroutine get_clm_iceadj_porosity(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- !
- ! !DESCRIPTION:
- ! update soil effective porosity from CLM to PFLOTRAN if PF freezing mode is off
- !
- ! !USES:
-
- use PFLOTRAN_Constants_module
- use clm_varctl , only : pf_frzmode
-
- ! !ARGUMENTS:
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- type(bounds_type) , intent(in) :: bounds ! bounds
- integer , intent(in) :: num_soilc ! number of column soil points in column filter
- integer , intent(in) :: filter_soilc(:) ! column filter for soil points
-! type(soilstate_type) , intent(in) :: soilstate_vars
-! type(waterstate_type) , intent(in) :: waterstate_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
- ! !LOCAL VARIABLES:
- integer :: fc, c, g, j, gcount, cellcount ! indices
- real(r8) :: itheta
-
- PetscScalar, pointer :: adjporosity_clmp_loc(:) !
- PetscScalar, pointer :: soilisat_clmp_loc(:) !
- PetscErrorCode :: ierr
-
- !EOP
- !-----------------------------------------------------------------------
- associate ( &
- gridcell => col_pp%gridcell , & ! column's gridcell
- wtgcell => col_pp%wtgcell , & ! column's weight relative to gridcell
- cactive => col_pp%active , & ! column's active or not
- dz => col_pp%dz , & ! layer thickness depth (m)
- watsat => clm_bgc_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd)
- h2osoi_ice => clm_bgc_data%h2osoi_ice_col & ! ice lens (kg/m2)
- )
-
- ! if 'pf_tmode' is NOT using freezing option, the phase-change of soil water done in 'SoilTemperatureMod.F90' in 'bgp2'
- ! must be included to adjust porosity (effective porosity) in pflotran
- ! This is doing prior to the real liquid water source/sink, because 'h2osoi_liq' will be updated during those calls after 'bgp2'.
- if (.not. pf_frzmode) then
-
- ! re-calculate the effective porosity (CLM ice-len adjusted), which should be pass to pflotran
- call VecGetArrayF90(clm_pf_idata%effporosity_clmp, adjporosity_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- adjporosity_clmp_loc(:) = 0._r8
- soilisat_clmp_loc(:) = 0._r8
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( wtgcell(c) <= 0._r8 .or. (.not.cactive(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = gridcell(c)
- gcount = g - bounds%begg
- do j = 1, nlevsoi
- cellcount = gcount*clm_pf_idata%nzclm_mapped + j
-
- if (j<=clm_pf_idata%nzclm_mapped) then
- itheta = h2osoi_ice(c,j) / (dz(c,j) * denice)
- itheta = min(itheta, 0.99_r8*watsat(c,j))
- adjporosity_clmp_loc(cellcount) = adjporosity_clmp_loc(cellcount) &
- + (watsat(c,j) - itheta) * wtgcell(c)
- soilisat_clmp_loc(cellcount) = soilisat_clmp_loc(cellcount) &
- + itheta * wtgcell(c)
- endif
- end do
- end do
- call VecRestoreArrayF90(clm_pf_idata%effporosity_clmp, adjporosity_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- end if
-
- end associate
- end subroutine get_clm_iceadj_porosity
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: get_clm_bcwflx
- !
- ! !INTERFACE:
- subroutine get_clm_bcwflx(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- !
- ! !DESCRIPTION:
- !
- ! F.-M. YUAN: the water fluxes in CLM4.5 are separately calculated in a few subroutines
- ! in 'SoilHydrologyMod.F90'. When coupled with pflotran, it's hard to get those together
- ! like GB does in 'step_th_clm_pf' subroutine. So, this subroutine is a collective call of
- ! that and others in 'Hydrology2Mod.F90' so that pflotran can be called out of 'hydrology2'.
- !
- ! !USES:
-
- use shr_const_mod , only : SHR_CONST_G
- use clm_time_manager, only : get_step_size, get_nstep
-
- ! !ARGUMENTS:
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- type(bounds_type) , intent(in) :: bounds
- integer, intent(in) :: num_soilc ! number of column non-lake points in column filter
- integer, intent(in) :: filter_soilc(:) ! column filter for non-lake points
-
-! type(atm2lnd_type) , intent(in) :: clm_a2l
-! type(soilstate_type) , intent(in) :: soils_vars
-! type(temperature_type) , intent(in) :: ces_vars
-! type(energyflux_type) , intent(in) :: cef_vars
-! type(waterstate_type) , intent(in) :: cws_vars
-! type(waterflux_type) , intent(in) :: cwf_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
- ! !LOCAL VARIABLES:
- integer :: fc, g, c, j, p ! do loop indices
- integer :: gcount ! gridcell index (0-based)
- integer :: pftindex ! pft index
- real(r8) :: dtime ! land model time step (sec)
- integer :: nstep ! time step number
- real(r8) :: area
- integer :: cellcount ! 3-D cell index (1-based)
-
- real(r8) :: rootfr_col(bounds%begc:bounds%endc, nlevsoi)
- real(r8) :: rootfr_sum(bounds%begc:bounds%endc) ! accumulator for rootr weighting
- real(r8) :: qflx_evap_col(bounds%begc:bounds%endc) ! soil surface evaporation (mmH2O/s)
- real(r8) :: qflx_tran_col(bounds%begc:bounds%endc) ! veg. transpiration (mmH2O/s)
-
- real(r8) :: qflx, qflx_sink, qflx_source, soilvwc
- real(r8) :: dsoilliq1 = 0._r8, dsoilliq2 = 0._r8, dsoilliq3 = 0._r8
-
- real(r8) :: qflx_ground, kbot
- real(r8) :: reference_pressure, ponding_pressure ! Pa
- real(r8) :: pondmax(bounds%begc:bounds%endc) ! mm H2O: max. ponding depth for column
- real(r8) :: sr = 0.10_r8
- real(r8) :: tempreal
-
- ! for PF --> CLM (seq.)
- PetscScalar, pointer :: press_clms_loc(:) !
- PetscScalar, pointer :: soillsat_clms_loc(:) !
- PetscScalar, pointer :: porosity_clms_loc(:) !
- PetscScalar, pointer :: sr_pcwmax_clms_loc(:) !
-
- PetscScalar, pointer :: area_clms_loc(:) !
-
- ! for CLM (mpi) --> PF
- PetscScalar, pointer :: zsoi_clmp_loc(:) !
- PetscScalar, pointer :: qflx_clmp_loc(:) ! source/sink term for plant Transpiration: unit in mass rate (kgH2O/sec)
- PetscScalar, pointer :: press_top_clmp_loc(:) ! BC in pressure type: unit in Pa
- PetscScalar, pointer :: press_base_clmp_loc(:) !
- PetscScalar, pointer :: qflux_top_clmp_loc(:) ! BC in neumann flux type: unit in m/s
- PetscScalar, pointer :: qflux_base_clmp_loc(:) !
- PetscScalar, pointer :: press_maxponding_clmp_loc(:) !
- PetscErrorCode :: ierr
-
- !EOP
- !-----------------------------------------------------------------------
- associate ( &
- ltype => lun_pp%itype , & ! landunit type
- cgridcell => col_pp%gridcell , & ! column's gridcell
- clandunit => col_pp%landunit , & ! column's landunit
- zi => col_pp%zi , & ! Input: (:,:) soil layer interface depth (m)
- dz => col_pp%dz , & ! Input: (:,:) soil layer thickness (m)
- pfti => col_pp%pfti , &! beginning pft index for each column
- pwtgcell => veg_pp%wtgcell , &! weight relative to gridcell for each pft
- pwtcol => veg_pp%wtcol , &! weight relative to column for each pft
- !
- bsw => clm_bgc_data%bsw_col , &! Clapp and Hornberger "b" (nlevgrnd)
- hksat => clm_bgc_data%hksat_col , &! hydraulic conductivity at saturation (mm H2O /s) (nlevgrnd)
- watsat => clm_bgc_data%watsat_col , &! volumetric soil water at saturation (porosity) (nlevgrnd)
- sucsat => clm_bgc_data%sucsat_col , &! minimum soil suction (mm) (nlevgrnd)
- rootfr => clm_bgc_data%rootfr_col , &
-! rootfr_pft => soils_vars%rootfr_patch , & ! pft-level effective fraction of roots in each soil layer
-
- forc_pbot => clm_bgc_data%forc_pbot_not_downscaled_grc , & ! Input: [real(r8) (:)] atmospheric pressure (Pa)
- t_grnd => clm_bgc_data%t_grnd_col , & ! Input: [real(r8) (:)] ground surface temperature [K]
- htvp => clm_bgc_data%htvp_col , & ! Input: [real(r8) (:)] latent heat of vapor of water (or sublimation) [j/kg]
- !
- frac_sno => clm_bgc_data%frac_sno_eff_col , & ! Input: fraction of ground covered by snow (0 to 1)
- frac_h2osfc => clm_bgc_data%frac_h2osfc_col , & ! Input: fraction of ground covered by surface water (0 to 1)
- h2osoi_liq => clm_bgc_data%h2osoi_liq_col , & ! Input: liquid water (kg/m2)
- h2osoi_ice => clm_bgc_data%h2osoi_ice_col , & ! Input: ice lens (kg/m2)
- !
- qflx_top_soil => clm_bgc_data%qflx_top_soil_col , & ! Input: net water input into soil from top (mm/s)
- qflx_ev_h2osfc => clm_bgc_data%qflx_ev_h2osfc_col , & ! Input: column-level evaporation flux from h2osfc (W/m2) [+ to atm] : checking unit
- qflx_evap_soil => clm_bgc_data%qflx_evap_soi_col , & ! Input: column-level soil evaporation (mm H2O/s) (+ = to atm)
- qflx_subl_snow => clm_bgc_data%qflx_sub_snow_col , & ! Input: column-level evaporation flux from snow (mm H2O/s) [+ to atm]
-! qflx_tran_veg_pft => cwf_vars%qflx_tran_veg_patch & ! Input: pft-level vegetation transpiration (mm H2O/s) (+ = to atm)
- qflx_tran_veg => clm_bgc_data%qflx_tran_veg_col &
-
- )
-
-!----------------------------------------------------------------------------
- nstep = get_nstep()
- dtime = get_step_size()
-
- ! (1) soil surface evaporation: needs further checking here? -
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- if (ltype(clandunit(c)) == istsoil .or. ltype(clandunit(c))==istcrop) then
- ! not sure if using 'qflx_evap_soi' as a whole ground-surface better than individual surfaces, i.e. 'qflx_ev_snow/soi/h2osfc'
- ! all of those 4 variables are calculated in 'BareGroundFluxesMod', 'CanopyFluxesMod', and then adjusted in 'Biogeophysics2' after soil temperature call
- ! note that: all 4 variables could be negative (i.e., dew formation on ground)
- qflx_evap_col(c)=(1.0_r8 - frac_sno(c) - frac_h2osfc(c))*qflx_evap_soil(c) + &
- frac_h2osfc(c)*qflx_ev_h2osfc(c)/htvp(c)
- !frac_sno(c)*qflx_ev_snow(c) ! snow-covered area should be excluded (see SoilHydrologyMod:: infiltration)
- else
- ! for other types of landunits
- qflx_evap_col(c) = (1.0_r8 - frac_sno(c))*qflx_evap_soil(c)
- end if
-
- if (t_grnd(c) <= tfrz) qflx_evap_col(c) = max(0._r8, qflx_evap_col(c)) ! frozen ground, no dew contribution to subsurface infiltration
- end do
-
- ! (3) Compute the vegetation Transpiration (originally those are in 'SoilHydrologyMod.F90')
- do j = 1, nlevsoi
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- rootfr_col(c,j) = 0._r8
- end do
- end do
- rootfr_sum(:) = 0._r8
- qflx_tran_col(:) = 0._r8
-
-! do pftindex = 1, max_patch_per_col
-! do fc = 1, num_soilc
-! c = filter_soilc(fc)
-! if (pftindex <= col_pp%npfts(c)) then
-! p = pfti(c) + pftindex - 1
-!
-! if (pwtgcell(p)>0._r8) then
-! do j = 1,nlevsoi
-! rootfr_col(c,j) = rootfr_col(c,j) + &
-! rootfr_pft(p,j) * qflx_tran_veg_pft(p) * pwtcol(p)
-! rootfr_sum(c) = rootfr_sum(c) + qflx_tran_veg_pft(p) * pwtcol(p)
-! end do
-! end if
-!
-! qflx_tran_col(c) = qflx_tran_col(c) + qflx_tran_veg_pft(p) * pwtcol(p)
-! end if
-!
-! end do
-! end do
-! ! Compute the Transpiration sink vertical distribution
-! do j = 1, nlevsoi
-! do fc = 1, num_soilc
-! c = filter_soilc(fc)
-! if (rootfr_sum(c) /= 0._r8) then
-! rootfr_col(c,j) = rootfr_col(c,j)/rootfr_sum(c)
-! end if
-! end do
-! end do
-
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- qflx_tran_col(c) = qflx_tran_veg(c)
- do j = 1, nlevsoi
- rootfr_col(c,j) = rootfr(c,j)
- end do
-
- end do
-
-!----------------------------------------------------------------------------------------------------------
- ! (4) pass the clm_qflx to the vecs
- ! NOTE the following unit conversions:
- ! qflx_soil_top and qflx_tran_veg are in [mm/sec] from CLM;
- ! qflx_clm_loc is in [kgH2O/sec] as mass rate for pflotran (as input)
-
- ! previous time-step soil water pressure and saturation for adjusting qflx
- ! note that this is a temporary workaround - waiting for PF's solution
- call VecGetArrayF90(clm_pf_idata%press_clms, press_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%soillsat_clms, soillsat_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%effporosity_clms, porosity_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%sr_pcwmax_clms, sr_pcwmax_clms_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayF90(clm_pf_idata%zsoi_clmp, zsoi_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayF90(clm_pf_idata%qflux_clmp, qflx_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%press_subsurf_clmp, press_top_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%press_subbase_clmp, press_base_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%qflux_subsurf_clmp, qflux_top_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%qflux_subbase_clmp, qflux_base_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%press_maxponding_clmp, press_maxponding_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- ! Initialize flux variables and bcs
- do fc = 1, num_soilc
-
- c = filter_soilc(fc)
- g = cgridcell(c)
- gcount = g - bounds%begg
-
- do j = 1, nlevsoi
- cellcount = gcount*clm_pf_idata%nzclm_mapped + j
-
- if(j<=clm_pf_idata%nzclm_mapped) then
- qflx_clmp_loc(cellcount) = 0.0_r8
-
- if (j .eq. 1) then
- press_top_clmp_loc(gcount+1) = press_clms_loc(cellcount) ! same as the first top layer
- end if
-
- if (j .eq. clm_pf_idata%nzclm_mapped) then
- press_base_clmp_loc(gcount+1) = press_clms_loc(cellcount) ! same as the bottom layer
- end if
-
- endif
- end do
-
- end do
-
- pondmax(:) = 0._r8 ! this is temporarily set (not yet figure out how CLM get this value)
- do fc = 1, num_soilc
-
- c = filter_soilc(fc)
- g = cgridcell(c)
- gcount = g - bounds%begg
- area = area_clms_loc(gcount*clm_pf_idata%nzclm_mapped+1)
- reference_pressure = clm_pf_idata%pressure_reference
- ponding_pressure = pondmax(c)*SHR_CONST_G ! max. ponding water depth (mm) ==> pressure (Pa)
-
- press_maxponding_clmp_loc(gcount+1) = reference_pressure+ponding_pressure*col_pp%wtgcell(c)
-
- do j = 1, nlevsoi
- cellcount = gcount*clm_pf_idata%nzclm_mapped + j
-
- if(j<=clm_pf_idata%nzclm_mapped) then
- qflx = 0._r8
- ! top BC
- if (j .eq. 1) then
-
- ! net liq water input/output to soil column
- qflx_ground = qflx_top_soil(c) - qflx_evap_col(c) ! unit: mm/sec
-
- ! if net input potential, it's forming TOP BC of pressure type (water ponding potetial)
- ! both waterhead and flux calcuated here, but not applied in PFLOTRAN in the same time (upon BC type picked-up by PF)
- if ( qflx_ground .gt. 0._r8) then
- ! Newly ADDED mmH2O ==> pressure (Pa) as top BC (dirichlet) by forming a layer of surface water column
- ! AND, the actual infiltration/runoff are retrieving from PFLOTRAN using 'update_surflow_pf2clm' subroutine
- if (soillsat_clms_loc(cellcount) >= 1._r8) then
- ! water-head formed on saturated below-ground soil layer
- press_top_clmp_loc(gcount+1) = press_clms_loc(cellcount) + &
- qflx_ground*col_pp%wtgcell(c)*dtime*SHR_CONST_G
- else
- ! ground-water-head discontinued from below-ground (atm. pressure applied at both ends)
- press_top_clmp_loc(gcount+1) = press_top_clmp_loc(gcount+1) + &
- qflx_ground*col_pp%wtgcell(c)*dtime*SHR_CONST_G
- endif
-
- ! mmH2O/sec ==> mH2O/sec of potential infiltration (flux) rate as top BC (neumann)
- ! must be used together with 'seepage' as top BC in the meantime to removing upwarding water
- ! AND, the actual infiltration/runoff are retrieving from PFLOTRAN using 'update_bcflow_pf2clm' subroutine
- qflux_top_clmp_loc(gcount+1) = qflx_ground*1.e-3
-
- ! if net loss potential, it's as source/sink term of soil column
- else
- qflx = qflx + min(0._r8, qflx_ground) ! unit here: mmH2O/sec
- qflux_top_clmp_loc(gcount+1) = 0._r8
- end if
- end if
-
- ! adding plant root extraction of water (transpiration)
- qflx = qflx - qflx_tran_col(c)*rootfr_col(c,j) ! by this point: unit: mmH2O/sec for CLM column
-
- qflx = qflx * col_pp%wtgcell(c) ! from now on: per PF 3-D cells
- qflx = qflx * area * 1.e-3 *denh2o ! unit: mmH2O/sec ==> kgH2O/sec
-
- ! previous time-step soil water saturation for adjusting qflx to avoid too wet or too dry to cause PF math issue
- ! (this is a temporary workaround - waiting for PF's solution)
- soilvwc = soillsat_clms_loc(cellcount) * &
- porosity_clms_loc(cellcount) ! PF saturation ==> real vwc (using adjusted porosity???)
-
- ! checking if over-filled when sinking (excluding infiltration)
- qflx_sink = max(0._r8, qflx) ! sink (+) only (kgH2O/sec)
- dsoilliq1 = (0.99_r8*porosity_clms_loc(cellcount)-soilvwc) &
- * zsoi_clmp_loc(cellcount) &
- * area * denh2o /dtime ! mH2O ==> kgH2O/sec to be filled at most (1% for error)
- qflx_sink = min(qflx_sink, max(0._r8,dsoilliq1))
-
- ! checking if too dry to be ETed (or other sourced): lower than 'sr_pcwmax'
- qflx_source = min(0._r8, qflx) ! source (-) only (kgH2O/sec)
- sr = 1.001_r8*sr_pcwmax_clms_loc(cellcount) * & ! '1.001' will give 0.1% for holding error in the calculation
- watsat(c,j) ! PF saturation ==> 'real' vwc
- dsoilliq2 = (sr-soilvwc)*zsoi_clmp_loc(cellcount)*area*denh2o/dtime ! mH2O ==> kgH2O/sec to be extracted at most (-)
- qflx_source = max(qflx_source, min(0._r8,dsoilliq2))
-
- qflx_clmp_loc(cellcount) = qflx_clmp_loc(cellcount)+ (qflx_sink+qflx_source) ! source/sink unit: kg/sec
-
- ! bottom BC (neumman type): m/sec
- if (j .eq. clm_pf_idata%nzclm_mapped) then
- ! available water flux-out rate (-) adjusted by source(-)/sink(+) term
- dsoilliq3 = min(0._r8, dsoilliq2 - qflx_clmp_loc(cellcount)) &
- /area/denh2o ! kgH2O/sec ==> mH2O/sec
-
- ! free drainage at bottom
- tempreal = soilvwc/watsat(c,j) ! using 'real' saturation
- kbot = hksat(c,j)*(tempreal**(2._r8*bsw(c,j)+3._r8))*1.e-3 ! mmH2O/sec ==> mH2O/sec
- qflux_base_clmp_loc(gcount+1) = qflux_base_clmp_loc(gcount+1) &
- + max(dsoilliq3, -kbot * col_pp%wtgcell(c)) ! mH2O/sec
-
- end if
-
- endif !if(j<=clm_pf_idata%nzclm_mapped)
-
- end do ! do j=1,nlevsoi
-
- end do ! do c=1, num_soilc
-
- call VecRestoreArrayF90(clm_pf_idata%press_clms, press_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%soillsat_clms, soillsat_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%sr_pcwmax_clms, sr_pcwmax_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%effporosity_clms, porosity_clms_loc, ierr)
- CHKERRQ(ierr)
-
- call VecRestoreArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr)
- CHKERRQ(ierr)
-
- call VecRestoreArrayF90(clm_pf_idata%zsoi_clmp, zsoi_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- call VecRestoreArrayF90(clm_pf_idata%qflux_clmp, qflx_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%press_subsurf_clmp, press_top_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%press_subbase_clmp, press_base_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%qflux_subsurf_clmp, qflux_top_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%qflux_subbase_clmp, qflux_base_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%press_maxponding_clmp, press_maxponding_clmp_loc, ierr)
- CHKERRQ(ierr)
-
-!----------------------------------------------------------------------------------------------------------
-
- end associate
- end subroutine get_clm_bcwflx
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: get_clm_bceflx
- !
- ! !INTERFACE:
- subroutine get_clm_bceflx(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
- !
- ! !DESCRIPTION:
- !
- ! F.-M. YUAN: the boundary heat fluxes in CLM4.5 are extracted to drive pflotran TH mode.
- ! GB only defined ground-heaf-flux.
- ! So, this subroutine is a collective setting on either heat-flux (neumann type)
- ! or interface thermal state (temperature) (dirichlet type)
- ! at both ground and bottom interface (BC).
- !
- ! !USES:
-
- ! !ARGUMENTS:
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- type(bounds_type) , intent(in) :: bounds
- integer, intent(in) :: num_soilc ! number of column non-lake points in column filter
- integer, intent(in) :: filter_soilc(:) ! column filter for non-lake points
-
-! type(atm2lnd_type) , intent(in) :: clm_a2l
-! type(waterstate_type) , intent(in) :: cws_vars
-! type(temperature_type) , intent(in) :: ces_vars
-! type(energyflux_type) , intent(in) :: cef_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
- ! !LOCAL VARIABLES:
- integer :: fc, c, g, p, gcount ! do loop indices
- integer :: pftindex
-
- ! for CLM (mpi) --> PF
- PetscScalar, pointer :: gflux_subsurf_clmp_loc(:) ! BC in neumman type: unit W/m2
- PetscScalar, pointer :: gtemp_subsurf_clmp_loc(:) ! BC in dirichlet type: unit in degC
- PetscScalar, pointer :: gflux_subbase_clmp_loc(:) ! BC in neumman type: unit W/m2
- PetscScalar, pointer :: gtemp_subbase_clmp_loc(:) ! BC in dirichlet type: unit in degC
- PetscErrorCode :: ierr
-
- !EOP
- !-----------------------------------------------------------------------
- associate ( &
- cgridcell => col_pp%gridcell , &! column's gridcell
- clandunit => col_pp%landunit , &! column's landunit
- dz => col_pp%dz , &! layer thickness depth (m)
- pfti => col_pp%pfti , &! beginning pft index for each column
- pwtgcell => veg_pp%wtgcell , &! weight relative to gridcell for each pft
- pwtcol => veg_pp%wtcol , &! weight relative to column for each pft
- !
- frac_sno => clm_bgc_data%frac_sno_eff_col , & ! Input: fraction of ground covered by snow (0 to 1)
- frac_h2osfc => clm_bgc_data%frac_h2osfc_col , & ! Input: fraction of ground covered by surface water (0 to 1)
- !
- eflx_bot => clm_bgc_data%eflx_bot_col , &! heat flux from beneath column (W/m**2) [+ = upward]
-! eflx_gnet => cef_vars%eflx_gnet_patch , &! net ground heat flux into the surface (W/m**2) per patch
-! eflx_soil_grnd => cef_vars%eflx_soil_grnd_patch , &! soil heat flux (W/m**2) [+ = into soil]
- eflx_gnet => clm_bgc_data%eflx_gnet_col , &
- eflx_soil_grnd => clm_bgc_data%eflx_soil_grnd_col , &
- t_grnd => clm_bgc_data%t_grnd_col & ! ground surface temperature [K]
- )
-
- !----------------------------------------------------------------------------------------------------------
- ! (1) pass the clm_gflux/gtemp to the vec
-
- call VecGetArrayF90(clm_pf_idata%gflux_subsurf_clmp, gflux_subsurf_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gflux_subbase_clmp, gflux_subbase_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gtemp_subsurf_clmp, gtemp_subsurf_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gtemp_subbase_clmp, gtemp_subbase_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- gflux_subsurf_clmp_loc(:) = 0._r8
- gflux_subbase_clmp_loc(:) = 0._r8
- gtemp_subsurf_clmp_loc(:) = 0._r8
- gtemp_subbase_clmp_loc(:) = 0._r8
-
- ! CLM appears NO column-level ground-heat-flux variable, instead by 'patch'
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
- g = cgridcell(c)
- gcount = g - bounds%begg
-
- gflux_subsurf_clmp_loc(gcount+1) = gflux_subsurf_clmp_loc(gcount+1) &
- + eflx_soil_grnd(c)*1.d-3 * col_pp%wtgcell(c) ! 1.d-3: from W/m2 --> kJ/m2/s
-! do pftindex = 1, max_patch_per_col
-! if (pftindex <= col_pp%npfts(c)) then
-! p = pfti(c) + pftindex - 1
-! if (pwtgcell(p)>0._r8) then
-! gflux_subsurf_clmp_loc(gcount+1) = gflux_subsurf_clmp_loc(gcount+1) &
-! + eflx_soil_grnd(p)*1.d-3 * pwtcol(p) ! (TODO - checking) from W/m2 --> kJ/m2/s
-! end if
-! end if
-! end do
- end do
-
- ! CLM column-level variables available to PFLOTRAN
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = cgridcell(c)
- gcount = g - bounds%begg
-
- gflux_subbase_clmp_loc(gcount+1) = gflux_subbase_clmp_loc(gcount+1) &
- + eflx_bot(c)*1.d-3 * col_pp%wtgcell(c)
- gtemp_subsurf_clmp_loc(gcount+1) = gflux_subbase_clmp_loc(gcount+1) &
- + (t_grnd(c) - tfrz) * col_pp%wtgcell(c)
-
- gtemp_subbase_clmp_loc(gcount+1) = 0._r8 ! not yet get it from CLM (i.e.,dirichlet type not available)
-
- end do
-
- call VecRestoreArrayF90(clm_pf_idata%gflux_subsurf_clmp, gflux_subsurf_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%gflux_subbase_clmp, gflux_subbase_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%gtemp_subsurf_clmp, gtemp_subsurf_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%gtemp_subbase_clmp, gtemp_subbase_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine get_clm_bceflx
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !ROUTINE: get_clm_bgc_conc(bounds)
- !
- ! !INTERFACE:
-
- subroutine get_clm_bgc_conc(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-!! TODO: add phosphorus vars
-#ifndef FLEXIBLE_POOLS
- use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-#endif
-
- implicit none
-
- type(bounds_type) , intent(in) :: bounds
- integer , intent(in) :: num_soilc ! number of soil columns in filter
- integer , intent(in) :: filter_soilc(:) ! filter for soil columns
-
-! type(carbonstate_type) , intent(in) :: carbonstate_vars
-! type(nitrogenstate_type) , intent(in) :: nitrogenstate_vars
-! type(phosphorusstate_type) , intent(in) :: phosphorusstate_vars
-! type(ch4_type) , intent(in) :: ch4_vars
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
- character(len=256) :: subname = "get_clm_bgc_concentration"
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- ! Local variables
- integer :: g, fc, c, j, k
- integer :: gcount, cellcount
- real(r8) :: wtgcell, realc_gcell, realn_gcell
-
-#ifdef FLEXIBLE_POOLS
- integer :: vec_offset
- PetscScalar, pointer :: decomp_cpools_vr_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_npools_vr_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
-#else
- integer :: isom
- PetscScalar, pointer :: decomp_cpools_vr_lit1_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_lit2_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_lit3_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_cwd_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som1_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som2_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som3_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som4_clm_loc(:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_npools_vr_lit1_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_lit2_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_lit3_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_cwd_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_som1_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) n pools
- PetscScalar, pointer :: decomp_npools_vr_som2_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) n pools
- PetscScalar, pointer :: decomp_npools_vr_som3_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) n pools
- PetscScalar, pointer :: decomp_npools_vr_som4_clm_loc(:) ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) n pools
-#endif
-
- PetscScalar, pointer :: smin_no3_vr_clm_loc(:) ! (gN/m3) vertically-resolved soil mineral NO3
- PetscScalar, pointer :: smin_nh4_vr_clm_loc(:) ! (gN/m3) vertically-resolved soil mineral NH4
- PetscScalar, pointer :: smin_nh4sorb_vr_clm_loc(:) ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
-
- PetscErrorCode :: ierr
- !
- !------------------------------------------------------------------------------------------
- !
- associate ( &
- decomp_cpools_vr=> clm_bgc_data%decomp_cpools_vr_col , & ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- decomp_npools_vr=> clm_bgc_data%decomp_npools_vr_col , & ! (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- smin_no3_vr => clm_bgc_data%smin_no3_vr_col , & ! (gN/m3) vertically-resolved soil mineral NO3
- smin_nh4_vr => clm_bgc_data%smin_nh4_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4
- smin_nh4sorb_vr => clm_bgc_data%smin_nh4sorb_vr_col , & ! (gN/m3) vertically-resolved soil mineral NH4 absorbed
-
- decomp_ppools_vr=> clm_bgc_data%decomp_ppools_vr_col , & ! [real(r8) (:,:,:) ! col (gP/m3) vertically-resolved decomposing (litter, cwd, soil) P pools
- solutionp_vr => clm_bgc_data%solutionp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil solution P
- labilep_vr => clm_bgc_data%labilep_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil labile mineral P
- secondp_vr => clm_bgc_data%secondp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil secondary mineralP
- occlp_vr => clm_bgc_data%occlp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil occluded mineral P
- primp_vr => clm_bgc_data%primp_vr_col , & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil primary mineral P
- sminp_vr => clm_bgc_data%sminp_vr_col & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil mineral P = solutionp + labilep + secondp
- )
-
-#ifdef FLEXIBLE_POOLS
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-#else
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_lit1_clmp, decomp_cpools_vr_lit1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_lit2_clmp, decomp_cpools_vr_lit2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_lit3_clmp, decomp_cpools_vr_lit3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_cwd_clmp, decomp_cpools_vr_cwd_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_som1_clmp, decomp_cpools_vr_som1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_som2_clmp, decomp_cpools_vr_som2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_som3_clmp, decomp_cpools_vr_som3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_som4_clmp, decomp_cpools_vr_som4_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_lit1_clmp, decomp_npools_vr_lit1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_lit2_clmp, decomp_npools_vr_lit2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_lit3_clmp, decomp_npools_vr_lit3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_cwd_clmp, decomp_npools_vr_cwd_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_som1_clmp, decomp_npools_vr_som1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_som2_clmp, decomp_npools_vr_som2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_som3_clmp, decomp_npools_vr_som3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_som4_clmp, decomp_npools_vr_som4_clm_loc, ierr)
- CHKERRQ(ierr)
-#endif
-
- call VecGetArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-
-#ifdef FLEXIBLE_POOLS
- decomp_cpools_vr_clm_loc(:) = 0._r8
- decomp_npools_vr_clm_loc(:) = 0._r8
-#else
- decomp_cpools_vr_lit1_clm_loc(:) = 0._r8
- decomp_cpools_vr_lit2_clm_loc(:) = 0._r8
- decomp_cpools_vr_lit3_clm_loc(:) = 0._r8
- decomp_cpools_vr_cwd_clm_loc(:) = 0._r8
- decomp_cpools_vr_som1_clm_loc(:) = 0._r8
- decomp_cpools_vr_som2_clm_loc(:) = 0._r8
- decomp_cpools_vr_som3_clm_loc(:) = 0._r8
- decomp_cpools_vr_som4_clm_loc(:) = 0._r8
- decomp_npools_vr_lit1_clm_loc(:) = 0._r8
- decomp_npools_vr_lit2_clm_loc(:) = 0._r8
- decomp_npools_vr_lit3_clm_loc(:) = 0._r8
- decomp_npools_vr_cwd_clm_loc(:) = 0._r8
- decomp_npools_vr_som1_clm_loc(:) = 0._r8
- decomp_npools_vr_som2_clm_loc(:) = 0._r8
- decomp_npools_vr_som3_clm_loc(:) = 0._r8
- decomp_npools_vr_som4_clm_loc(:) = 0._r8
-#endif
-
- smin_no3_vr_clm_loc(:) = 0._r8
- smin_nh4_vr_clm_loc(:) = 0._r8
- smin_nh4sorb_vr_clm_loc(:) = 0._r8
-
- do fc = 1, num_soilc ! will need to extend to multiple columns?
- c = filter_soilc(fc)
-
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data to PF for inactive cell
-
- g = col_pp%gridcell(c)
- wtgcell = col_pp%wtgcell(c)
-
- gcount = g - bounds%begg
- do j = 1, nlevdecomp
-
- ! note: all clm-pf soil layers are 'nzclm_mapped' for both TH/BGC,
- ! but in CLM, TH is within nlevsoi, bgc within 'nlevdecomp'
-
- cellcount = gcount*clm_pf_idata%nzclm_mapped+j
-
- if(j <= clm_pf_idata%nzclm_mapped) then
-
- do k = 1, ndecomp_pools
- realc_gcell = decomp_cpools_vr(c,j,k) &
- /clm_pf_idata%C_molecular_weight * wtgcell
- realn_gcell = decomp_npools_vr(c,j,k) &
- /clm_pf_idata%N_molecular_weight * wtgcell
-
-#ifdef FLEXIBLE_POOLS
- vec_offset = (k-1)*clm_pf_idata%ngclm_sub ! decomp_pool vec: 'cell' first, then 'species'
-
- decomp_cpools_vr_clm_loc(vec_offset+cellcount) = realc_gcell &
- + decomp_cpools_vr_clm_loc(vec_offset+cellcount)
- decomp_npools_vr_clm_loc(vec_offset+cellcount) = realn_gcell &
- + decomp_npools_vr_clm_loc(vec_offset+cellcount)
-
-#else
- if (k==i_met_lit) then
- decomp_cpools_vr_lit1_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_lit1_clm_loc(cellcount)
- decomp_npools_vr_lit1_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_lit1_clm_loc(cellcount)
-
- elseif (k==i_cel_lit) then
- decomp_cpools_vr_lit2_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_lit2_clm_loc(cellcount)
- decomp_npools_vr_lit2_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_lit2_clm_loc(cellcount)
-
- elseif (k==i_lig_lit) then
- decomp_cpools_vr_lit3_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_lit3_clm_loc(cellcount)
- decomp_npools_vr_lit3_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_lit3_clm_loc(cellcount)
-
- elseif (k==i_cwd) then
- decomp_cpools_vr_cwd_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_cwd_clm_loc(cellcount)
- decomp_npools_vr_cwd_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_cwd_clm_loc(cellcount)
-
- else
- isom = k-i_cwd
- if (isom==1 .and. isom<=ndecomp_pools) then
- decomp_cpools_vr_som1_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_som1_clm_loc(cellcount)
- decomp_npools_vr_som1_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_som1_clm_loc(cellcount)
-
- elseif (isom==2 .and. isom<=ndecomp_pools) then
- decomp_cpools_vr_som2_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_som2_clm_loc(cellcount)
- decomp_npools_vr_som2_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_som2_clm_loc(cellcount)
-
- elseif (isom==3 .and. isom<=ndecomp_pools) then
- decomp_cpools_vr_som3_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_som3_clm_loc(cellcount)
- decomp_npools_vr_som3_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_som3_clm_loc(cellcount)
-
- elseif (isom==4 .and. isom<=ndecomp_pools) then ! if using 'century' type, will end here
- decomp_cpools_vr_som4_clm_loc(cellcount) = realc_gcell &
- + decomp_cpools_vr_som4_clm_loc(cellcount)
- decomp_npools_vr_som4_clm_loc(cellcount) = realn_gcell &
- + decomp_npools_vr_som4_clm_loc(cellcount)
- end if
-
- end if
-#endif
-
- enddo ! do k=1, ndecomp_pools
-
- realn_gcell = smin_no3_vr(c,j)/clm_pf_idata%N_molecular_weight * wtgcell
- smin_no3_vr_clm_loc(cellcount) = realn_gcell &
- + smin_no3_vr_clm_loc(cellcount)
-
- realn_gcell = smin_nh4_vr(c,j)/clm_pf_idata%N_molecular_weight * wtgcell
- smin_nh4_vr_clm_loc(cellcount) = realn_gcell &
- + smin_nh4_vr_clm_loc(cellcount)
-
- realn_gcell = smin_nh4sorb_vr(c,j)/clm_pf_idata%N_molecular_weight * wtgcell
- smin_nh4sorb_vr_clm_loc(cellcount) = realn_gcell &
- + smin_nh4sorb_vr_clm_loc(cellcount)
-
- endif
-
- enddo ! do j = 1, nlevdecomp
-
- enddo ! do c = begc, endc
-
-#ifdef FLEXIBLE_POOLS
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-#else
-!-----------------------------------------------------------------------------
-!write(*,'(A,50(1h-))')">>>DEBUG | get_clm_bgc_conc,lev=1 for C & N"
-!write(*,'(12A14)')"lit1","lit2","lit3","cwd","som1","som2","som3","som4","no3","nh4","nh4sorb"
-!write(*,'(12E14.6)')decomp_cpools_vr(1,1,1:8)
-!write(*,'(12E14.6)')decomp_npools_vr(1,1,1:8),smin_no3_vr(1,1),smin_nh4_vr(1,1),smin_nh4sorb_vr(1,1)
-!-----------------------------------------------------------------------------
-
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_lit1_clmp, decomp_cpools_vr_lit1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_lit2_clmp, decomp_cpools_vr_lit2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_lit3_clmp, decomp_cpools_vr_lit3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_cwd_clmp, decomp_cpools_vr_cwd_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_som1_clmp, decomp_cpools_vr_som1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_som2_clmp, decomp_cpools_vr_som2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_som3_clmp, decomp_cpools_vr_som3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_som4_clmp, decomp_cpools_vr_som4_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_lit1_clmp, decomp_npools_vr_lit1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_lit2_clmp, decomp_npools_vr_lit2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_lit3_clmp, decomp_npools_vr_lit3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_cwd_clmp, decomp_npools_vr_cwd_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_som1_clmp, decomp_npools_vr_som1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_som2_clmp, decomp_npools_vr_som2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_som3_clmp, decomp_npools_vr_som3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_som4_clmp, decomp_npools_vr_som4_clm_loc, ierr)
- CHKERRQ(ierr)
-#endif
- call VecRestoreArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine get_clm_bgc_conc
-
- !-----------------------------------------------------------------------------
- !
- ! !IROUTINE: get_clm_bgc_rate()
- !
- ! !INTERFACE:
- subroutine get_clm_bgc_rate(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-!! TODO: add phosphorus vars
- !
- ! !DESCRIPTION:
- !
- !
- ! !USES:
-
- use clm_time_manager, only : get_step_size, get_nstep
-#ifndef FLEXIBLE_POOLS
- use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-#endif
-
- ! !ARGUMENTS:
- implicit none
-
- type(bounds_type) , intent(in) :: bounds
- integer , intent(in) :: num_soilc ! number of soil columns in filter
- integer , intent(in) :: filter_soilc(:) ! filter for soil columns
-
- type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data
-
-! type(cnstate_type) , intent(in) :: cnstate_vars
-! type(carbonflux_type) , intent(in) :: carbonflux_vars
-! type(nitrogenflux_type) , intent(in) :: nitrogenflux_vars
-
- character(len=256) :: subname = "get_clm_bgc_rate"
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- ! !LOCAL VARIABLES:
- integer :: fc, c, g, j, k ! do loop indices
- integer :: gcount, cellcount
- real(r8) :: wtgcell, realc_gcell, realn_gcell
-
- real(r8) :: dtime ! land model time step (sec)
-
- ! ratios of NH4:NO3 in N deposition and fertilization (temporarily set here, will be as inputs)
-! real(r8) :: r_nh4_no3_dep(bounds%begc:bounds%endc)
-! real(r8) :: r_nh4_no3_fert(bounds%begc:bounds%endc)
-! real(r8) :: fnh4_dep, fnh4_fert
-
- ! C/N source/sink rates as inputs for pflotran: Units - moles/m3/s (note: do unit conversion here for input rates)
-#ifdef FLEXIBLE_POOLS
- integer :: vec_offset
- PetscScalar, pointer :: rate_decomp_c_clm_loc(:) !
- PetscScalar, pointer :: rate_decomp_n_clm_loc(:) !
-#else
- integer :: isom
- PetscScalar, pointer :: rate_lit1c_clm_loc(:) !
- PetscScalar, pointer :: rate_lit2c_clm_loc(:) !
- PetscScalar, pointer :: rate_lit3c_clm_loc(:) !
- PetscScalar, pointer :: rate_cwdc_clm_loc(:) !
- PetscScalar, pointer :: rate_som1c_clm_loc(:) !
- PetscScalar, pointer :: rate_som2c_clm_loc(:) !
- PetscScalar, pointer :: rate_som3c_clm_loc(:) !
- PetscScalar, pointer :: rate_som4c_clm_loc(:) !
- PetscScalar, pointer :: rate_lit1n_clm_loc(:) !
- PetscScalar, pointer :: rate_lit2n_clm_loc(:) !
- PetscScalar, pointer :: rate_lit3n_clm_loc(:) !
- PetscScalar, pointer :: rate_cwdn_clm_loc(:) !
- PetscScalar, pointer :: rate_som1n_clm_loc(:) !
- PetscScalar, pointer :: rate_som2n_clm_loc(:) !
- PetscScalar, pointer :: rate_som3n_clm_loc(:) !
- PetscScalar, pointer :: rate_som4n_clm_loc(:) !
-#endif
-
- PetscScalar, pointer :: rate_plantndemand_clm_loc(:) !
- PetscScalar, pointer :: rate_smin_no3_clm_loc(:) !
- PetscScalar, pointer :: rate_smin_nh4_clm_loc(:) !
-
- PetscErrorCode :: ierr
-
- !
- !---------------------------------------------------------------------------
- !
- associate ( &
- ! plant litering and removal + SOM/LIT vertical transport
- col_net_to_decomp_cpools_vr => clm_bgc_data%externalc_to_decomp_cpools_col , &
- col_net_to_decomp_npools_vr => clm_bgc_data%externaln_to_decomp_npools_col , &
- ! inorg. nitrogen source
-! ndep_to_sminn => nitrogenflux_vars%ndep_to_sminn_col , &
-! nfix_to_sminn => nitrogenflux_vars%nfix_to_sminn_col , &
-! fert_to_sminn => nitrogenflux_vars%fert_to_sminn_col , &
-! soyfixn_to_sminn => nitrogenflux_vars%soyfixn_to_sminn_col , &
-! supplement_to_sminn_vr => nitrogenflux_vars%supplement_to_sminn_vr_col , &
-! !
-! nfixation_prof => cnstate_vars%nfixation_prof_col , &
-! ndep_prof => cnstate_vars%ndep_prof_col , &
-! activeroot_prof => cnstate_vars%activeroot_prof_col , &
- ! inorg. nitrogen sink (if not going to be done in PF)
- no3_net_transport_vr => clm_bgc_data%no3_net_transport_vr_col , &
- ! inorg. nitrogen sink potential
- col_plant_ndemand_vr => clm_bgc_data%plant_ndemand_vr_col , &
-
- externaln_to_nh4_vr => clm_bgc_data%externaln_to_nh4_col , &
- externaln_to_no3_vr => clm_bgc_data%externaln_to_no3_col , &
-
- col_net_to_decomp_ppools_vr => clm_bgc_data%externalp_to_decomp_ppools_col , &
- externalp_to_primp_vr => clm_bgc_data%externalp_to_primp_col , &
- externalp_to_labilep_vr => clm_bgc_data%externalp_to_labilep_col , &
- externalp_to_solutionp => clm_bgc_data%externalp_to_solutionp_col , &
- sminp_net_transport_vr => clm_bgc_data%sminp_net_transport_vr_col , &
- col_plant_pdemand_vr => clm_bgc_data%plant_pdemand_vr_col &
- )
-
- dtime = get_step_size()
-
-#ifdef FLEXIBLE_POOLS
- call VecGetArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr)
- CHKERRQ(ierr)
-#else
- call VecGetArrayF90(clm_pf_idata%rate_lit1c_clmp, rate_lit1c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_lit2c_clmp, rate_lit2c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_lit3c_clmp, rate_lit3c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_cwdc_clmp, rate_cwdc_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som1c_clmp, rate_som1c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som2c_clmp, rate_som2c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som3c_clmp, rate_som3c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som4c_clmp, rate_som4c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_lit1n_clmp, rate_lit1n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_lit2n_clmp, rate_lit2n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_lit3n_clmp, rate_lit3n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_cwdn_clmp, rate_cwdn_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som1n_clmp, rate_som1n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som2n_clmp, rate_som2n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som3n_clmp, rate_som3n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_som4n_clmp, rate_som4n_clm_loc, ierr)
-#endif
-
- call VecGetArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr)
- CHKERRQ(ierr)
-
- ! Initialize to ZERO
-#ifdef FLEXIBLE_POOLS
- rate_decomp_c_clm_loc(:) = 0.0_r8
- rate_decomp_n_clm_loc(:) = 0.0_r8
-#else
- rate_lit1c_clm_loc(:) = 0.0_r8
- rate_lit2c_clm_loc(:) = 0.0_r8
- rate_lit3c_clm_loc(:) = 0.0_r8
- rate_cwdc_clm_loc (:) = 0.0_r8
- rate_som1c_clm_loc(:) = 0.0_r8
- rate_som2c_clm_loc(:) = 0.0_r8
- rate_som3c_clm_loc(:) = 0.0_r8
- rate_som4c_clm_loc(:) = 0.0_r8
- rate_lit1n_clm_loc(:) = 0.0_r8
- rate_lit2n_clm_loc(:) = 0.0_r8
- rate_lit3n_clm_loc(:) = 0.0_r8
- rate_cwdn_clm_loc (:) = 0.0_r8
- rate_som1n_clm_loc(:) = 0.0_r8
- rate_som2n_clm_loc(:) = 0.0_r8
- rate_som3n_clm_loc(:) = 0.0_r8
- rate_som4n_clm_loc(:) = 0.0_r8
-#endif
- rate_smin_no3_clm_loc(:) = 0.0_r8
- rate_smin_nh4_clm_loc(:) = 0.0_r8
- rate_plantndemand_clm_loc(:) = 0.0_r8
-
-! r_nh4_no3_dep(:) = 1.0_r8 ! temporarily assuming half of N dep is in NH4 and another half in NO3
-! r_nh4_no3_fert(:) = 1.0_r8 ! temporarily assiming half of N fertilization is in NH4 and another half in NO3
-
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = col_pp%gridcell(c)
- gcount = g - bounds%begg
- wtgcell = col_pp%wtgcell(c)
-
- do j = 1, nlevdecomp
- cellcount = gcount*clm_pf_idata%nzclm_mapped+j
-
- ! note: all clm-pf soil layers are 'clm_pf_idata%nzclm_mapped' for both TH/BGC,
- ! but in CLM, TH is within clm_pf_idata%nzclm_mapped, bgc within 'nlevdecomp'
- if(j <= clm_pf_idata%nzclm_mapped) then
-
- do k = 1, ndecomp_pools
- ! need more checking here: how to weight column data onto grid (F.-M. Yuan)
- realc_gcell = col_net_to_decomp_cpools_vr(c,j,k) &
- /clm_pf_idata%C_molecular_weight * wtgcell
- realn_gcell = col_net_to_decomp_npools_vr(c,j,k) &
- /clm_pf_idata%N_molecular_weight * wtgcell
-
-#ifdef FLEXIBLE_POOLS
- vec_offset = (k-1)*clm_pf_idata%ngclm_sub ! decomp_pool vec: 'cell' first, then 'species'
-
- rate_decomp_c_clm_loc(vec_offset+cellcount) = realc_gcell &
- + rate_decomp_c_clm_loc(vec_offset+cellcount)
- rate_decomp_n_clm_loc(vec_offset+cellcount) = realn_gcell &
- + rate_decomp_n_clm_loc(vec_offset+cellcount)
-#else
- if (k==i_met_lit) then
- rate_lit1c_clm_loc(cellcount) = realc_gcell &
- + rate_lit1c_clm_loc(cellcount)
- rate_lit1n_clm_loc(cellcount) = realn_gcell &
- + rate_lit1n_clm_loc(cellcount)
- else if(k==i_cel_lit) then
- rate_lit2c_clm_loc(cellcount) = realc_gcell &
- + rate_lit2c_clm_loc(cellcount)
- rate_lit2n_clm_loc(cellcount) = realn_gcell &
- + rate_lit2n_clm_loc(cellcount)
- else if(k==i_lig_lit) then
- rate_lit3c_clm_loc(cellcount) = realc_gcell &
- + rate_lit3c_clm_loc(cellcount)
- rate_lit3n_clm_loc(cellcount) = realn_gcell &
- + rate_lit3n_clm_loc(cellcount)
- else if(k==i_cwd) then
- rate_cwdc_clm_loc(cellcount) = realc_gcell &
- + rate_cwdc_clm_loc(cellcount)
- rate_cwdn_clm_loc(cellcount) = realn_gcell &
- + rate_cwdn_clm_loc(cellcount)
- !
- else
- isom = k-i_cwd
- if(isom==1 .and. isom<=ndecomp_pools) then
- rate_som1c_clm_loc(cellcount) = realc_gcell &
- + rate_som1c_clm_loc(cellcount)
- rate_som1n_clm_loc(cellcount) = realn_gcell &
- + rate_som1n_clm_loc(cellcount)
- else if(isom==2 .and. isom<=ndecomp_pools) then
- rate_som2c_clm_loc(cellcount) = realc_gcell &
- + rate_som2c_clm_loc(cellcount)
- rate_som2n_clm_loc(cellcount) = realn_gcell &
- + rate_som2n_clm_loc(cellcount)
- else if(isom==3 .and. isom<=ndecomp_pools) then
- rate_som3c_clm_loc(cellcount) = realc_gcell &
- + rate_som3c_clm_loc(cellcount)
- rate_som3n_clm_loc(cellcount) = realn_gcell &
- + rate_som3n_clm_loc(cellcount)
- else if(isom==4 .and. isom<=ndecomp_pools) then ! if using 'century' type, will end here
- rate_som4c_clm_loc(cellcount) = realc_gcell &
- + rate_som4c_clm_loc(cellcount)
- rate_som4n_clm_loc(cellcount) = realn_gcell &
- + rate_som4n_clm_loc(cellcount)
- end if
-
- endif
-#endif
- enddo ! do k=1, ndecomp_pools
-
-! fnh4_dep = max(0._r8, min(1.0_r8, 1._r8/(r_nh4_no3_dep(c)+1._r8)))
-! fnh4_fert = max(0._r8, min(1.0_r8, 1._r8/(r_nh4_no3_fert(c)+1._r8)))
-
-! realn_gcell = &
-! ( fnh4_dep*ndep_to_sminn(c) * ndep_prof(c, j) + &
-! fnh4_fert*fert_to_sminn(c) * ndep_prof(c, j) + &
-! fnh4_fert*supplement_to_sminn_vr(c,j) + &
-! nfix_to_sminn(c) * nfixation_prof(c, j) + &
-! soyfixn_to_sminn(c) * nfixation_prof(c, j) &
-! )/ clm_pf_idata%N_molecular_weight * wtgcell
-
- realn_gcell = externaln_to_nh4_vr(c,j)/ clm_pf_idata%N_molecular_weight * wtgcell
- rate_smin_nh4_clm_loc(cellcount) = realn_gcell + rate_smin_nh4_clm_loc(cellcount)
-
-! realn_gcell = &
-! ( (1._r8-fnh4_dep)*ndep_to_sminn(c) * ndep_prof(c, j) + &
-! (1._r8-fnh4_fert)*fert_to_sminn(c) * ndep_prof(c, j) + &
-! (1._r8-fnh4_fert)*supplement_to_sminn_vr(c,j) &
-! )/ clm_pf_idata%N_molecular_weight * wtgcell
-
- realn_gcell = externaln_to_no3_vr(c,j)/ clm_pf_idata%N_molecular_weight * wtgcell
- ! PF hydrological mode is OFF, then NO3 transport NOT to calculate in PF
- ! then it's done in CLM, so need to pass those to PF as source/sink term (RT mass transfer)
- if(.not.pf_hmode) then
- realn_gcell = realn_gcell - (no3_net_transport_vr(c,j) &
- )/ clm_pf_idata%N_molecular_weight * wtgcell
- endif
- rate_smin_no3_clm_loc(cellcount) = realn_gcell + rate_smin_no3_clm_loc(cellcount)
-
- ! plant N uptake rate here IS the N demand (potential uptake)
- realn_gcell = col_plant_ndemand_vr(c,j) &
- /clm_pf_idata%N_molecular_weight * wtgcell
- rate_plantndemand_clm_loc(cellcount) = rate_plantndemand_clm_loc(cellcount) + realn_gcell
-
-#ifdef CLM_PF_DEBUG
- write(pflotran_m%option%myrank+200,*) 'checking bgc-mass-rate - clm: ', &
- 'rank=',pflotran_m%option%myrank, 'column=',c, 'layer_id=',j, &
- 'rate_nh4_clm(layer_id)=',rate_smin_nh4_clm_loc(cellcount)
-#endif
-
- endif ! if (j<=clm_pf_idata%nzclm_mapped)
- enddo ! do j=1, nlevdecomp
- enddo ! do fc=1,numsoic
-
-#ifdef FLEXIBLE_POOLS
- call VecRestoreArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr)
- CHKERRQ(ierr)
-#else
-
-!-----------------------------------------------------------------------------
-!write(*,'(A,50(1h-))')">>>DEBUG | get_clm_bgc_rate,lev=1 for C & N"
-!write(*,'(12A14)')"lit1","lit2","lit3","cwd","som1","som2","som3","som4","no3","nh4","plantNdemand"
-!write(*,'(12E14.6)')col_net_to_decomp_cpools_vr(1,1,1:ndecomp_pools)
-!write(*,'(12E14.6)')col_net_to_decomp_npools_vr(1,1,1:ndecomp_pools),&
-! (rate_smin_no3_clm_loc(1))*clm_pf_idata%N_molecular_weight, &
-! (rate_smin_nh4_clm_loc(1))*clm_pf_idata%N_molecular_weight, &
-! (rate_plantndemand_clm_loc(1))*clm_pf_idata%N_molecular_weight
-!-----------------------------------------------------------------------------
-
- call VecRestoreArrayF90(clm_pf_idata%rate_lit1c_clmp, rate_lit1c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_lit2c_clmp, rate_lit2c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_lit3c_clmp, rate_lit3c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_cwdc_clmp, rate_cwdc_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som1c_clmp, rate_som1c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som2c_clmp, rate_som2c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som3c_clmp, rate_som3c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som4c_clmp, rate_som4c_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_lit1n_clmp, rate_lit1n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_lit2n_clmp, rate_lit2n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_lit3n_clmp, rate_lit3n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_cwdn_clmp, rate_cwdn_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som1n_clmp, rate_som1n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som2n_clmp, rate_som2n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som3n_clmp, rate_som3n_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_som4n_clmp, rate_som4n_clm_loc, ierr)
-#endif
-
- call VecRestoreArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine get_clm_bgc_rate
-
-
- ! =============================UPDATE PFLOTRAN evolving variables to CLM ==========================================
-
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: update_soil_moisture_pf2clm
- !
- ! !INTERFACE:
- subroutine update_soil_moisture_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- !
- ! !DESCRIPTION:
- !
- !
- ! !USES:
-
- ! !ARGUMENTS:
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- type(bounds_type), intent(in) :: bounds
- integer, intent(in) :: num_soilc ! number of column soil points in column filter
- integer, intent(in) :: filter_soilc(:) ! column filter for soil points
-! type(soilstate_type) , intent(in) :: soilstate_vars
-! type(waterstate_type), intent(inout) :: waterstate_vars
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
-
- ! !LOCAL VARIABLES:
- integer :: fc, c, j, g, gcount ! indices
-
- PetscScalar, pointer :: sat_ice_clm_loc(:)
- PetscScalar, pointer :: sat_clm_loc(:)
- PetscScalar, pointer :: watsat_clm_loc(:)
- PetscErrorCode :: ierr
-
- !EOP
- !-----------------------------------------------------------------------
- associate ( &
- gridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
- wtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell
- dz => col_pp%dz , & ! [real(r8) (:,:)] layer thickness depth (m)
- !
- h2osoi_liq_col => clm_bgc_data%h2osoi_liq_col , &
- h2osoi_ice_col => clm_bgc_data%h2osoi_ice_col , &
- h2osoi_vol_col => clm_bgc_data%h2osoi_vol_col , &
- watsat_col => clm_bgc_data%watsat_col &
- )
-
- call VecGetArrayF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%effporosity_clms, watsat_clm_loc, ierr)
- CHKERRQ(ierr)
- if (pf_frzmode) &
- call VecGetArrayF90(clm_pf_idata%soilisat_clms, sat_ice_clm_loc, ierr)
- CHKERRQ(ierr)
-
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = col_pp%gridcell(c)
- gcount = g - bounds%begg
- do j = 1, nlevsoi
-
- if (j<=clm_pf_idata%nzclm_mapped) then
- h2osoi_liq_col(c,j) = sat_clm_loc(gcount*nlevsoi + j) * &
- watsat_clm_loc(gcount*nlevsoi + j) * dz(c,j) * denh2o ! 'watsat_clm_loc' may be effective porosity
- if (pf_frzmode) then
- h2osoi_ice_col(c,j) = sat_ice_clm_loc(gcount*nlevsoi + j) * &
- watsat_clm_loc(gcount*nlevsoi + j) * dz(c,j) * denice
- end if
-
- else
- h2osoi_liq_col(c,j) = h2osoi_liq_col(c,clm_pf_idata%nzclm_mapped)
- if (pf_frzmode) then
- h2osoi_ice_col(c,j) = h2osoi_ice_col(c,clm_pf_idata%nzclm_mapped)
- end if
-
- end if
-
- h2osoi_vol_col(c,j) = h2osoi_liq_col(c,j) / dz(c,j) / denh2o + &
- h2osoi_ice_col(c,j) / dz(c,j) / denice
- h2osoi_vol_col(c,j) = min(h2osoi_vol_col(c,j), watsat_col(c,j))
-
- enddo
-
- enddo
-
- call VecRestoreArrayF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecRestoreArrayF90(clm_pf_idata%effporosity_clms, watsat_clm_loc, ierr)
- CHKERRQ(ierr)
- if (pf_frzmode) &
- call VecRestoreArrayF90(clm_pf_idata%soilisat_clms, sat_ice_clm_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine update_soil_moisture_pf2clm
-
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: update_soil_temperature_pf2clm
- !
- ! !INTERFACE:
- subroutine update_soil_temperature_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-
- !
- ! !DESCRIPTION:
- !
- !
- ! !USES:
-
- ! !ARGUMENTS:
- implicit none
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- type(bounds_type), intent(in) :: bounds
- integer, intent(in) :: num_soilc ! number of column soil points in column filter
- integer, intent(in) :: filter_soilc(:) ! column filter for soil points
-! type(soilstate_type) , intent(in) :: soilstate_vars
-! type(temperature_type), intent(inout):: temperature_vars
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
-
- ! !LOCAL VARIABLES:
- integer :: fc, c, j, g, gcount ! indices
-
- PetscScalar, pointer :: soilt_clms_loc(:)
- PetscErrorCode :: ierr
-
- !EOP
- !-----------------------------------------------------------------------
- associate ( &
- gridcell => col_pp%gridcell , & ! [integer (:)] gridcell index of column
- wtgcell => col_pp%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell
- dz => col_pp%dz , & ! [real(r8) (:,:)] layer thickness depth (m)
- !
- t_soisno => clm_bgc_data%t_soisno_col & ! snow-soil temperature (Kelvin)
- )
-
- call VecGetArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr)
- CHKERRQ(ierr)
-
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = col_pp%gridcell(c)
- gcount = g - bounds%begg
- do j = 1, nlevsoi
-
- if (j<=clm_pf_idata%nzclm_mapped) then
- t_soisno(c,j) = soilt_clms_loc(gcount*clm_pf_idata%nzclm_mapped+j) + tfrz
-
- else
- t_soisno(c,j) = t_soisno(c, clm_pf_idata%nzclm_mapped)
-
- end if
-
- enddo
-
- enddo
-
- call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr)
- CHKERRQ(ierr)
-
- end associate
- end subroutine update_soil_temperature_pf2clm
-
- !-----------------------------------------------------------------------------
- !
- ! !ROUTINE: update_soil_bgc_pf2clm()
- !
- ! !INTERFACE:
- !
- ! ! calculating BGC state variable changes over one time-step (rates)
- ! NOTE: Don't update the organic C/N state variables, which will be updated in those 'update' subroutines
- ! and the 'CNSoilLittVertTranspMod.F90' after 'update1'.
- !
- subroutine update_soil_bgc_pf2clm(clm_bgc_data, &
- bounds, num_soilc, filter_soilc)
-!! TODO: add phosphorus vars
- use CNDecompCascadeConType, only : decomp_cascade_con
- use clm_time_manager, only : get_step_size
-#ifndef FLEXIBLE_POOLS
- use clm_varpar, only : i_met_lit, i_cel_lit, i_lig_lit, i_cwd
-#endif
-
- implicit none
-
- type(bounds_type) , intent(in) :: bounds
- integer , intent(in) :: num_soilc ! number of soil columns in filter
- integer , intent(in) :: filter_soilc(:) ! filter for soil columns
-
-! type(atm2lnd_type) , intent(in) :: clm_a2l
-! type(waterstate_type) , intent(in) :: waterstate_vars
-! type(soilstate_type) , intent(in) :: soilstate_vars
-! type(cnstate_type) , intent(in) :: cnstate_vars
-! type(carbonstate_type) , intent(inout) :: carbonstate_vars
-! type(carbonflux_type) , intent(inout) :: carbonflux_vars
-! type(nitrogenstate_type) , intent(inout) :: nitrogenstate_vars
-! type(nitrogenflux_type) , intent(inout) :: nitrogenflux_vars
-! type(ch4_type) , intent(inout) :: ch4_vars
- type(clm_bgc_interface_data_type), intent(inout) :: clm_bgc_data
-
- character(len=256) :: subname = "update_soil_bgc_pf2clm"
-
-#include "finclude/petscsys.h"
-#include "finclude/petscvec.h"
-#include "finclude/petscvec.h90"
-
- integer :: fc,c,g,j,k
- integer :: gcount, cellcount
- real(r8) :: wtgcell
-
- real(r8) :: dtime ! land model time step (sec)
-
-#ifdef FLEXIBLE_POOLS
- integer :: vec_offset
- PetscScalar, pointer :: decomp_cpools_vr_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_npools_vr_clm_loc(:) ! (moleN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
-#else
- integer :: isom
- PetscScalar, pointer :: decomp_cpools_vr_lit1_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_lit2_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_lit3_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_cwd_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som1_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som2_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som3_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_cpools_vr_som4_clm_loc(:) ! (moleC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
- PetscScalar, pointer :: decomp_npools_vr_lit1_clm_loc(:) ! (moleN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_lit2_clm_loc(:) ! (moleN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_lit3_clm_loc(:) ! (moleN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
- PetscScalar, pointer :: decomp_npools_vr_cwd_clm_loc(:) ! (moleN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
-#endif
-
- PetscScalar, pointer :: smin_no3_vr_clm_loc(:) ! (moleN/m3) vertically-resolved soil mineral NO3
- PetscScalar, pointer :: smin_nh4_vr_clm_loc(:) ! (moleN/m3) vertically-resolved total soil mineral NH4
- PetscScalar, pointer :: smin_nh4sorb_vr_clm_loc(:) ! (moleN/m3) vertically-resolved absorbed soil mineral NH4
-
- ! 'accextrn_vr' - accumulative (root) extracted N, i.e., actual plant N uptake from each soil layer, within a CLM timestep
- PetscScalar, pointer :: accextrnh4_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil mineral N root-extraction (accumulated)
- PetscScalar, pointer :: accextrno3_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil mineral N root-extraction (accumulated)
-
- ! 'accnmin_vr' - accumulative gross N mineralization within a CLM timestep
- PetscScalar, pointer :: accnmin_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil N mineralization (accumulated)
-
- ! 'accnimm_vr' - accumulative N immobilization within a CLM timestep
- PetscScalar, pointer :: accnimmp_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil N potential immoblilization (accumulated)
- PetscScalar, pointer :: accnimm_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil N immoblilization (accumulated)
-
- PetscErrorCode :: ierr
-
-!------------------------------------------------------------------------------------
- !
- associate ( &
- initial_cn_ratio => clm_bgc_data%initial_cn_ratio , &
- decomp_cpools_vr => clm_bgc_data%decomp_cpools_vr_col , &
- decomp_npools_vr => clm_bgc_data%decomp_npools_vr_col , &
- sminn_vr => clm_bgc_data%sminn_vr_col , &
- smin_no3_vr => clm_bgc_data%smin_no3_vr_col , &
- smin_nh4_vr => clm_bgc_data%smin_nh4_vr_col , &
- smin_nh4sorb_vr => clm_bgc_data%smin_nh4sorb_vr_col , &
- decomp_cpools_delta_vr => clm_bgc_data%decomp_cpools_sourcesink_col , &
- decomp_npools_delta_vr => clm_bgc_data%decomp_npools_sourcesink_col , &
-
- sminn_to_plant_vr => clm_bgc_data%sminn_to_plant_vr_col , &
- smin_no3_to_plant_vr => clm_bgc_data%smin_no3_to_plant_vr_col , &
- smin_nh4_to_plant_vr => clm_bgc_data%smin_nh4_to_plant_vr_col , &
- potential_immob_vr => clm_bgc_data%potential_immob_vr_col , &
- actual_immob_vr => clm_bgc_data%actual_immob_vr_col , &
- gross_nmin_vr => clm_bgc_data%gross_nmin_vr_col &
- )
-! ------------------------------------------------------------------------
- dtime = get_step_size()
-
- ! soil C/N pool increments set to the previous timestep (i.e., not yet updated)
- decomp_cpools_delta_vr = 0._r8-decomp_cpools_vr
- decomp_npools_delta_vr = 0._r8-decomp_npools_vr
-
- ! clm-pf interface data updated
-#ifdef FLEXIBLE_POOLS
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_clms, decomp_cpools_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_clms, decomp_npools_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-#else
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_lit1_clms, decomp_cpools_vr_lit1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_lit2_clms, decomp_cpools_vr_lit2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_lit3_clms, decomp_cpools_vr_lit3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_cwd_clms, decomp_cpools_vr_cwd_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_som1_clms, decomp_cpools_vr_som1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_som2_clms, decomp_cpools_vr_som2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_som3_clms, decomp_cpools_vr_som3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_som4_clms, decomp_cpools_vr_som4_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_lit1_clms, decomp_npools_vr_lit1_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_lit2_clms, decomp_npools_vr_lit2_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_lit3_clms, decomp_npools_vr_lit3_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_cwd_clms, decomp_npools_vr_cwd_clm_loc, ierr)
- CHKERRQ(ierr)
-#endif
-
- call VecGetArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%accextrno3_vr_clms, accextrno3_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-
- ! soil C/N pool increments, and actual plant N uptake, gross N mineralization and immobilization
- do fc = 1,num_soilc
- ! only operating on soil column, which then back to CLM-CN
- ! (TODO) NOT YET do columna-level down-scaling from PF's grid-cell variables
-
- c = filter_soilc(fc)
- g = col_pp%gridcell(c)
- wtgcell = col_pp%wtgcell(c)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- gcount = g - bounds%begg
- do j = 1, nlevdecomp
-
- cellcount = gcount*clm_pf_idata%nzclm_mapped+j
- if(j <= clm_pf_idata%nzclm_mapped) then
-
- ! updates the 'decomp_pools' src/sink terms,
- ! which then used in 'CNSoilLittVertTranspMod.F90' to update the pools
- do k=1, ndecomp_pools
-#ifdef FLEXIBLE_POOLS
- vec_offset = (k-1)*clm_pf_idata%nlclm_sub ! decomp_pool vec: 'cell' first, then 'species'
-
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_clm_loc(vec_offset+cellcount) &
- * clm_pf_idata%C_molecular_weight
-
- if (clm_pf_idata%floating_cn_ratio(k)) then
- decomp_npools_delta_vr(c,j,k) = decomp_npools_delta_vr(c,j,k) &
- + decomp_npools_vr_clm_loc(vec_offset+cellcount) &
- * clm_pf_idata%N_molecular_weight
-
- else
- decomp_npools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- /initial_cn_ratio(k)
- endif
-
-#else
- if (k==i_met_lit) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_lit1_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- decomp_npools_delta_vr(c,j,k) = decomp_npools_delta_vr(c,j,k) &
- + decomp_npools_vr_lit1_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight
- else if (k==i_cel_lit) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_lit2_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- decomp_npools_delta_vr(c,j,k) = decomp_npools_delta_vr(c,j,k) &
- + decomp_npools_vr_lit2_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight
- else if (k==i_lig_lit) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_lit3_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- decomp_npools_delta_vr(c,j,k) = decomp_npools_delta_vr(c,j,k) &
- + decomp_npools_vr_lit3_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight
- else if (k==i_cwd) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_cwd_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- decomp_npools_delta_vr(c,j,k) = decomp_npools_delta_vr(c,j,k) &
- + decomp_npools_vr_cwd_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight
- !
- else
-
- isom = k-i_cwd
-
- if (isom==1 .and. isom<=ndecomp_pools) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_som1_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- elseif (isom==2 .and. isom<=ndecomp_pools) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_som2_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- elseif (isom==3 .and. isom<=ndecomp_pools) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_som3_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- elseif (isom==4 .and. isom<=ndecomp_pools) then
- decomp_cpools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- + decomp_cpools_vr_som4_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight
- end if
-
- if (isom>0) then
- decomp_npools_delta_vr(c,j,k) = decomp_cpools_delta_vr(c,j,k) &
- /initial_cn_ratio(k)
- end if
-
- endif
-
-#endif
- if (abs(decomp_cpools_delta_vr(c,j,k))<=1.d-20) decomp_cpools_delta_vr(c,j,k)=0._r8
- if (abs(decomp_npools_delta_vr(c,j,k))<=1.d-21) decomp_npools_delta_vr(c,j,k)=0._r8
-
- enddo
-
- ! directly update the 'smin' N pools (SO, must bypass the 'CNNStateUpdate1,2,3' relevant to soil N)
- smin_no3_vr(c,j) = &
- smin_no3_vr_clm_loc(cellcount)*clm_pf_idata%N_molecular_weight
-
- smin_nh4_vr(c,j) = &
- smin_nh4_vr_clm_loc(cellcount)*clm_pf_idata%N_molecular_weight
-
- smin_nh4sorb_vr(c,j) = &
- smin_nh4sorb_vr_clm_loc(cellcount)*clm_pf_idata%N_molecular_weight
-
- sminn_vr(c,j) = smin_no3_vr(c,j) + smin_nh4_vr(c,j) + smin_nh4sorb_vr(c,j)
-
- ! flows or changes (unit: g/m3/s)
- smin_nh4_to_plant_vr(c,j) = (accextrnh4_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
- smin_no3_to_plant_vr(c,j) = (accextrno3_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
- sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j)
-
- gross_nmin_vr(c,j) = (accnmin_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
-
- potential_immob_vr(c,j) = (accnimmp_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
- actual_immob_vr(c,j) = (accnimm_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
-
- else ! just in case 'clm_pf_idata%nzclm_mapped0: soil layer)
-
- ! gases from PFLOTRAN are timely accumulated, so gas fluxes are calculated here if over atm. partial pressure (no explicit transport available from PF now)
- PetscScalar, pointer :: gco2_vr_clms_loc(:) ! (M: molC/m3 bulk soil) vertically-resolved soil gas CO2 from PF's evolution
- PetscScalar, pointer :: gn2_vr_clms_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2 from PF's evolution
- PetscScalar, pointer :: gn2o_vr_clms_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2O from PF's evolution
- PetscScalar, pointer :: gco2_vr_clmp_loc(:) ! (M: molC/m3 bulk soil) vertically-resolved soil gas CO2 to reset PF's CO2g
- PetscScalar, pointer :: gn2_vr_clmp_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2 to reset PF's N2g
- PetscScalar, pointer :: gn2o_vr_clmp_loc(:) ! (M: molN/m3 bulk soil) vertically-resolved soil gas N2O to reset PF's N2Og
-
- ! 'acchr_vr' - accumulative CO2 proudction from decompositon (for tracking HR, not involving mass-balance)
- PetscScalar, pointer :: acchr_vr_clm_loc(:) ! (moleC/m3/timestep) vertically-resolved soil CO2 production (accumulated)
- ! 'accngasmin_vr' - accumulative N gas proudction from mineralization (for tracking, not involving mass-balance)
- PetscScalar, pointer :: accngasmin_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil gaseous N production (accumulated)
- ! 'accngasnitr_vr' - accumulative N gas proudction from nitrification (for tracking)
- PetscScalar, pointer :: accngasnitr_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil gaseous N production (accumulated)
- ! 'accngasdeni_vr' - accumulative N gas proudction from denitrification (for tracking)
- PetscScalar, pointer :: accngasdeni_vr_clm_loc(:) ! (moleN/m3/timestep) vertically-resolved soil gaseous N production (accumulated)
-
- !
- PetscScalar, pointer :: soillsat_clm_loc(:)
- PetscScalar, pointer :: soilisat_clm_loc(:)
- PetscScalar, pointer :: soilpor_clm_loc(:)
- PetscScalar, pointer :: soilt_clm_loc(:)
- PetscScalar, pointer :: soilpress_clm_loc(:)
- PetscErrorCode :: ierr
-
- real(r8), parameter :: rgas = 8.3144621 ! m3 Pa K-1 mol-1
-
-!------------------------------------------------------------------------------------
- associate ( &
- forc_pco2 => clm_bgc_data%forc_pco2_grc , & ! partial pressure co2 (Pa)
- forc_pch4 => clm_bgc_data%forc_pch4_grc , & ! partial pressure ch4 (Pa)
- forc_pbot => clm_bgc_data%forc_pbot_not_downscaled_grc , & ! atmospheric pressure (Pa)
- frac_sno => clm_bgc_data%frac_sno_eff_col , & ! fraction of ground covered by snow (0 to 1)
- frac_h2osfc => clm_bgc_data%frac_h2osfc_col , & ! fraction of ground covered by surface water (0 to 1)
- dz => clm_bgc_data%dz , & ! soil layer thickness depth (m)
- hr_vr => clm_bgc_data%hr_vr_col , &
- f_co2_soil_vr => clm_bgc_data%f_co2_soil_vr_col , &
- f_n2o_soil_vr => clm_bgc_data%f_n2o_soil_vr_col , &
- f_n2_soil_vr => clm_bgc_data%f_n2_soil_vr_col , &
- f_ngas_decomp_vr => clm_bgc_data%f_ngas_decomp_vr_col , &
- f_ngas_nitri_vr => clm_bgc_data%f_ngas_nitri_vr_col , &
- f_ngas_denit_vr => clm_bgc_data%f_ngas_denit_vr_col &
- )
-! ------------------------------------------------------------------------
- dtime = get_step_size()
- nstep = get_nstep()
-
- ! get the current time-step state variables of aq. phase of interested species
- call VecGetArrayF90(clm_pf_idata%gco2_vr_clms, gco2_vr_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gn2_vr_clms, gn2_vr_clms_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gn2o_vr_clms, gn2o_vr_clms_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayF90(clm_pf_idata%gco2_vr_clmp, gco2_vr_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr)
- CHKERRQ(ierr)
-
- call VecGetArrayF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr)
- CHKERRQ(ierr)
- call VecGetArrayF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr)
- CHKERRQ(ierr)
-
- ! env. variables to properties of gases
- if (pf_tmode) then
- call VecGetArrayF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr)
- CHKERRQ(ierr) ! PF evolved 'soilt'
- else
- call VecGetArrayF90(clm_pf_idata%soilt_clmp, soilt_clm_loc, ierr)
- CHKERRQ(ierr) ! CLM evolved 'soilt' - for CLM, MPI vecs and Seq. vecs should be same
- end if
-
- if (pf_frzmode) then
- call VecGetArrayF90(clm_pf_idata%soilisat_clms, soilisat_clm_loc, ierr)
- CHKERRQ(ierr) ! PF evolved 'soil ice saturation'
- end if
-
- if (pf_hmode) then
- call VecGetArrayF90(clm_pf_idata%soillsat_clms, soillsat_clm_loc, ierr)
- CHKERRQ(ierr) ! PF evolved 'soil liq. saturation'
- call VecGetArrayF90(clm_pf_idata%press_clms, soilpress_clm_loc, ierr)
- CHKERRQ(ierr) ! PF evolved 'soil liq. saturation'
- else
- call VecGetArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clm_loc, ierr)
- CHKERRQ(ierr)! CLM evolved 'soilt liq. saturation'
- call VecGetArrayF90(clm_pf_idata%press_clmp, soilpress_clm_loc, ierr)
- CHKERRQ(ierr)! CLM evolved 'soilt liq. saturation'
- endif
- call VecGetArrayF90(clm_pf_idata%effporosity_clms, soilpor_clm_loc, ierr) ! PF evolved 'soil porosity'
- CHKERRQ(ierr)
-
- ! find the toppest air barrier layer
- lair_barrier(:) = -1 ! (-1: no barrier, 0: ground snow/ice/water-layer barrier, >=1: barrier in soil column)
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = col_pp%gridcell(c)
- gcount = g - bounds%begg
-
- if((frac_sno(c)+ frac_h2osfc(c))>=0.90_r8) then
- lair_barrier(c) = 0
- endif
-
- do j = 1, clm_pf_idata%nzclm_mapped
-
- cellcount = gcount*clm_pf_idata%nzclm_mapped+j
-
- wfps = 0._r8
- if (lair_barrier(c) >= 0) exit
-
- if (pf_frzmode) then
- wfps =soillsat_clm_loc(cellcount) &
- + soilisat_clm_loc(cellcount)
- else
- wfps =soillsat_clm_loc(cellcount) ! note: 'lsat' from PF has been adjusted by 'isat' reduced porosity
- endif
- if (wfps > 0.95_r8) then ! 95% total saturation as a critical-point for air-flow into deep soil
- lair_barrier(c) = j
- endif
- enddo
- enddo
-
- !
- do fc = 1,num_soilc ! operating on soil column, which then back to CLM-CN
- c = filter_soilc(fc)
- if ( col_pp%wtgcell(c) <= 0._r8 .or. (.not.col_pp%active(c)) ) cycle ! don't assign data from PF for inactive cell
-
- g = col_pp%gridcell(c)
- gcount = g - bounds%begg
-
- total_p = forc_pbot(g)
-
- do j = 1, nlevdecomp
- cellcount = gcount*clm_pf_idata%nzclm_mapped+j
- if(j <= clm_pf_idata%nzclm_mapped) then
-
- tc = soilt_clm_loc(cellcount) ! soil layer tc (oC)
- tk = tc+tfrz
-
- ! total_p is soil air pressure (soil water pressure if not less than atm. pressure)
- total_p = max(total_p, soilpress_clm_loc(cellcount))
-
- ! the following is for adjusting air space in soil (seems not right ?? -- off)
- !air_vol = (1.0_r8 - soillsat_clm_loc(cellcount)) * &
- ! soilpor_clm_loc(cellcount) ! m3 air/m3 soil
- !air_vol = max(air_vol, 0.01d0) ! min. 0.01 to avoid math. issue
-
- air_vol = 1.0_r8 ! atm used if not commented out
- air_molar = total_p*air_vol/rgas/tk ! moles of air in a cell
-
- ! gas fluxes from immobile PFLOTRAN evolving CO2imm, N2Oimm and N2imm, which are cumulative
- ! CO2 -
- cgas = gco2_vr_clms_loc(cellcount) ! mol/m3 soil (evolving in PF, but not yet transport)
- co2_p = forc_pco2(g) ! assuming atm. pco2 (pa) as directly equilibrated with soil CO2(g)
- cgas_p = co2_p/forc_pbot(g) * air_molar
-
- f_co2_soil_vr(c,j) = cgas-cgas_p
- cgas = cgas - f_co2_soil_vr(c,j)
- if (j <= lair_barrier(c) .or. lair_barrier(c) < 0) then ! above barrier OR no-barrier(-1)
- gco2_vr_clmp_loc(cellcount) = cgas_p ! this refreshed-air will pass back to PF
- else
- gco2_vr_clmp_loc(cellcount) = cgas ! currently don't have air transport (TODO)
- endif
-
- f_co2_soil_vr(c,j) = f_co2_soil_vr(c,j)*clm_pf_idata%C_molecular_weight ! moleCO2/m3 --> gC/m3 soil
- f_co2_soil_vr(c,j) = f_co2_soil_vr(c,j)/dtime ! gC/m3/s
-
- ! N2
- cgas = gn2_vr_clms_loc(cellcount) ! mol/m3 soil (evolving in PF, but not yet transport)
- n2_p = 0.78084_r8 ! assuming atm. pn2 as directly equilibrated with soil n2(g)
- cgas_p = n2_p * air_molar ! moleN2/m3
-
- f_n2_soil_vr(c,j) = cgas-cgas_p
- cgas = cgas - f_n2_soil_vr(c,j)
- if (j <= lair_barrier(c) .or. lair_barrier(c) < 0) then ! above barrier OR no-barrier(-1)
- gn2_vr_clmp_loc(cellcount) = cgas_p ! this refreshed-air will pass back to PF
- else
- gn2_vr_clmp_loc(cellcount) = cgas ! currently don't have air transport (TODO)
- endif
-
- f_n2_soil_vr(c,j) = f_n2_soil_vr(c,j)*clm_pf_idata%N_molecular_weight*2._r8 ! mole-N2/m3 --> g-N/m3 soil
- f_n2_soil_vr(c,j) = f_n2_soil_vr(c,j)/dtime ! gN/m3/s
-
- ! N2O
- cgas = gn2o_vr_clms_loc(cellcount)
- n2o_p = 310e-9_r8 ! assuming general atm. pN2O (310ppbv in 1990) as directly equilibrated with soil N2(aq)
- cgas_p = n2o_p * air_molar ! moleN2O/m3
-
- f_n2o_soil_vr(c,j) = cgas-cgas_p
- cgas = cgas - f_n2o_soil_vr(c,j)
- if (j <= lair_barrier(c) .or. lair_barrier(c) < 0) then ! above barrier OR no-barrier(-1)
- gn2o_vr_clmp_loc(cellcount) = cgas_p ! this refreshed-air will pass back to PF
- else
- gn2o_vr_clmp_loc(cellcount) = cgas ! currently don't have air transport (TODO)
- endif
-
- f_n2o_soil_vr(c,j) = f_n2o_soil_vr(c,j)*clm_pf_idata%N_molecular_weight*2._r8 ! mole-N2O/m3 --> g-N/m3 soil
- f_n2o_soil_vr(c,j) = f_n2o_soil_vr(c,j)/dtime ! gN/m3/s
-
- ! tracking HR from SOM-C reaction network
- hr_vr(c,j) = (acchr_vr_clm_loc(cellcount) &
- * clm_pf_idata%C_molecular_weight)/dtime
-
- ! tracking gaseous N production from N reaction network
- f_ngas_decomp_vr(c,j)= (accngasmin_vr_clm_loc (cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
-
- f_ngas_nitri_vr(c,j) = (accngasnitr_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
-
- f_ngas_denit_vr(c,j) = (accngasdeni_vr_clm_loc(cellcount) &
- * clm_pf_idata%N_molecular_weight)/dtime
-
- else ! just in case 'clm_pf_idata%nzclm_mapped PF)
- call pflotranModelUpdateAqGasesfromCLM(pflotran_m)
-
- end associate
- end subroutine update_bgc_gaslosses_pf2clm
-
-
- !-----------------------------------------------------------------------------
- !BOP
- ! comment out this subroutine currently for bgc-only
- ! !IROUTINE: update_bcflow_pf2clm
- !
- ! !INTERFACE:
-! subroutine update_bcflow_pf2clm( &
-! bounds, num_soilc, filter_soilc, &
-! clm_a2l, ces_vars, cef_vars, cws_vars, cwf_vars)
-! !
-! ! !DESCRIPTION:
-! ! update qflx_surf, qflx_infl from PF's
-! ! 'mass_balance' retrieving from PFLOTRAN
-! !
-! ! !USES:
-! use clm_time_manager, only : get_step_size
-!
-! type(bounds_type), intent(in) :: bounds
-! integer, intent(in) :: num_soilc ! number of column soil points in column filter
-! integer, intent(in) :: filter_soilc(:) ! column filter for soil points
-!
-! type(atm2lnd_type) , intent(in) :: clm_a2l
-! type(temperature_type) , intent(in) :: ces_vars
-! type(energyflux_type) , intent(in) :: cef_vars
-! type(waterstate_type) , intent(in) :: cws_vars
-! type(waterflux_type) , intent(inout) :: cwf_vars
-!
-! ! !LOCAL VARIABLES:
-!#include "finclude/petscsys.h"
-!#include "finclude/petscvec.h"
-!#include "finclude/petscvec.h90"
-!
-! integer :: fc, c, g, gcount ! indices
-! real(r8) :: area ! top face area
-! real(r8) :: dtime ! land model time step (sec)
-! real(r8) :: dew
-! real(r8) :: qflx_evap(bounds%begc:bounds%endc) ! soil surface evaporation (mmH2O/s)
-!
-! PetscScalar, pointer :: area_clm_loc(:)
-! PetscScalar, pointer :: qinfl_subsurf_clm_loc(:) ! kgH2O/time-step
-! PetscScalar, pointer :: qsurf_subsurf_clm_loc(:) ! kgH2O/time-step
-! PetscScalar, pointer :: qflux_subbase_clm_loc(:) ! kgH2O/time-step
-! PetscErrorCode :: ierr
-!
-! character(len=32) :: subname = 'update_bcflow_pf2clm' ! subroutine name
-!
-! !-----------------------------------------------------------------------
-!
-! associate(&
-! clandunit => col_pp%landunit , & ! column's landunit
-! ltype => lun_pp%itype , & ! landunit type
-! zi => col_pp%zi , & ! Input: (:,:) soil layer interface depth (m)
-! dz => col_pp%dz , & ! Input: (:,:) soil layer thickness (m)
-! !
-! forc_pbot => clm_a2l%forc_pbot_not_downscaled_grc , & ! Input: [real(r8) (:)] atmospheric pressure (Pa)
-! t_grnd => ces_vars%t_grnd_col , & ! Input: [real(r8) (:)] ground surface temperature [K]
-! htvp => cef_vars%htvp_col , & ! Input: [real(r8) (:)] latent heat of vapor of water (or sublimation) [j/kg]
-! !
-! frac_sno => cws_vars%frac_sno_eff_col , & ! Input: fraction of ground covered by snow (0 to 1)
-! frac_h2osfc => cws_vars%frac_h2osfc_col , & ! Input: fraction of ground covered by surface water (0 to 1)
-! !
-! qflx_top_soil => cwf_vars%qflx_top_soil_col , & ! Input: [real(r8) (:)] net water input into soil from top (mm/s)
-! qflx_ev_h2osfc => cwf_vars%qflx_ev_h2osfc_col , & ! Input: column-level evaporation flux from h2osfc (W/m2) [+ to atm] : checking unit
-! qflx_evap_soil => cwf_vars%qflx_evap_soi_col , & ! Input: column-level soil evaporation (mm H2O/s) (+ = to atm)
-! qflx_subl_snow => cwf_vars%qflx_sub_snow_col , & ! Input: column-level evaporation flux from snow (mm H2O/s) [+ to atm]
-! qflx_surf => cwf_vars%qflx_surf_col , & ! Output: [real(r8) (:)] surface runoff (mm H2O /s)
-! qflx_infl => cwf_vars%qflx_infl_col , & ! Output: [real(r8) (:)] soil infiltration (mm H2O /s)
-! qflx_drain => cwf_vars%qflx_drain_col & ! Output: [real(r8) (:)] sub-surface runoff (drainage) (mm H2O /s)
-! )
-!
-! dtime = get_step_size()
-!
-! ! the following was actually duplicated from 'get_clm_bcwflx' to calculate total water evap from 'qflx_topsoil'
-! ! in order to get potential infiltration from CLM (not yet run-off)
-! do fc = 1, num_soilc
-! c = filter_soilc(fc)
-! if (ltype(clandunit(c)) == istsoil .or. ltype(clandunit(c))==istcrop) then
-! ! not sure if using 'qflx_evap_soi_col' as a whole ground-surface better than individual surfaces, i.e. 'qflx_ev_snow/soi/h2osfc'
-! ! all of those 4 variables are calculated in 'BareGroundFluxesMod', 'CanopyFluxesMod', and then adjusted in 'Biogeophysics2' after soil temperature call
-! ! note that: all 4 variables could be negative (i.e., dew formation on ground)
-! qflx_evap(c)=(1.0_r8 - frac_sno(c) - frac_h2osfc(c))*qflx_evap_soil(c) + &
-! frac_h2osfc(c)*qflx_ev_h2osfc(c)/htvp(c)
-! !frac_sno(c)*qflx_evap_snow(c) ! snow-covered area should be excluded (see SoilHydrologyMod:: infiltration)
-! else
-! ! for other types of landunits
-! qflx_evap(c) = (1.0_r8 - frac_sno(c))*qflx_evap_soil(c)
-! end if
-!
-! if (t_grnd(c) <= tfrz) qflx_evap(c) = max(0._r8, qflx_evap(c)) ! frozen ground, no dew contribution to subsurface infiltration
-! end do
-!
-!
-! ! from PF==>CLM
-! call VecGetArrayF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr)
-! CHKERRQ(ierr)
-!
-! call VecGetArrayF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr)
-! CHKERRQ(ierr)
-! call VecGetArrayF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr)
-! CHKERRQ(ierr)
-! call VecGetArrayF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr)
-! CHKERRQ(ierr)
-!
-! do fc = 1, num_soilc
-!
-! c = filter_soilc(fc)
-! g = col_pp%gridcell(c)
-! gcount = g - bounds%begg
-!
-! dew = 0._r8
-! if (t_grnd(c) > tfrz) then ! frozen ground, no dew contribution to subsurface infiltration
-! if (ltype(clandunit(c)) == istsoil .or. ltype(clandunit(c))==istcrop) then
-! dew = -min(0._r8, (1.0_r8 - frac_sno(c) - frac_h2osfc(c))*qflx_evap_soil(c) + &
-! frac_h2osfc(c)*qflx_ev_h2osfc(c)/htvp(c) )
-! else
-! dew = -min(0._r8, qflx_evap_soil(c))
-! end if
-! endif
-!
-! !'from PF: qinfl_subsurf_clm_loc: positive - in, negative - out
-! area = area_clm_loc(gcount*clm_pf_idata%nzclm_mapped+1)
-! qflx_infl(c) = qinfl_subsurf_clm_loc(gcount+1) &
-! /dtime/(area*denh2o*1.e-3) ! kgH2O/time-step ==> mmH2O/sec
-!
-! qflx_surf(c) = dew + max(0._r8, qflx_top_soil(c)-qflx_evap(c)) - qflx_infl(c)
-! qflx_surf(c) = max(0._r8, qflx_surf(c))
-!
-! !'from PF: qflux_subbase_clm_loc: positive - in, negative - out)
-! area = area_clm_loc((gcount+1)*clm_pf_idata%nzclm_mapped) ! note: this 'area_clm_loc' is in 3-D for all subsurface domain
-! qflx_drain(c) = -qflux_subbase_clm_loc(gcount+1) &
-! /dtime/(area*denh2o*1.e-3) ! kgH2O/time-step ==> mmH2O/sec (+ drainage, - upward-in)
-!
-! end do
-! call VecRestoreArrayF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr)
-! CHKERRQ(ierr)
-! call VecRestoreArrayF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr)
-! CHKERRQ(ierr)
-! call VecRestoreArrayF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr)
-! CHKERRQ(ierr)
-! call VecRestoreArrayF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr)
-! CHKERRQ(ierr)
-!
-! end associate
-! end subroutine update_bcflow_pf2clm
-
-#endif
-!----------------------------------------------------------------------------------------------
-! END of CLM-PFLOTRAN bgc coupling interface
-!----------------------------------------------------------------------------------------------
-
-end module clm_pflotran_interfaceMod
-
diff --git a/components/clm/src/main/clm_varctl.F90 b/components/clm/src/main/clm_varctl.F90
index 1aa34e2f3521..81d3e76b6250 100644
--- a/components/clm/src/main/clm_varctl.F90
+++ b/components/clm/src/main/clm_varctl.F90
@@ -337,16 +337,17 @@ module clm_varctl
!-----------------------------------------------------------------------
! bgc & pflotran interface
!
- logical, public :: use_bgc_interface = .false.
+ logical, public :: use_clm_interface = .false.
logical, public :: use_clm_bgc = .false.
logical, public :: use_pflotran = .false.
logical, public :: pf_surfaceflow = .false.
! the following switches will allow flexibility of coupling CLM with PFLOTRAN (which in fact runs in 3 modes individually or coupled)
+ logical, public :: pf_cmode = .false. ! switch for 'C' mode coupling (will be updated in interface)
logical, public :: pf_hmode = .false. ! switch for 'H' mode coupling (will be updated in interface)
logical, public :: pf_tmode = .false. ! switch for 'T' mode coupling (will be updated in interface)
logical, public :: pf_frzmode = .false. ! switch for 'freezing' mode availablity in PF-thmode (will be updated in interface)
- logical, public :: pf_cmode = .false. ! switch for 'C' mode coupling (will be updated in interface)
logical, public :: initth_pf2clm= .false. ! switch for initializing CLM TH states from pflotran
+ integer, public :: pf_clmnstep0 = 0 ! the CLM timestep of start/restart
! cpl_bypass
character(len=fname_len), public :: metdata_type = ' ' ! metdata type for CPL_BYPASS mode
diff --git a/components/clm/src/main/controlMod.F90 b/components/clm/src/main/controlMod.F90
index fb002e6555e4..201d55ca2748 100644
--- a/components/clm/src/main/controlMod.F90
+++ b/components/clm/src/main/controlMod.F90
@@ -108,7 +108,7 @@ subroutine control_init( )
use clm_time_manager , only : set_timemgr_init, get_timemgr_defaults
use fileutils , only : getavu, relavu
use shr_string_mod , only : shr_string_getParentDir
- use clm_pflotran_interfaceMod , only : clm_pf_readnl
+ use clm_interface_pflotranMod , only : clm_pf_readnl
use ALMBeTRNLMod , only : betr_readNL
!
implicit none
@@ -129,7 +129,7 @@ subroutine control_init( )
! Time step
namelist / clm_inparm/ &
- dtime
+ dtime
! CLM namelist settings
@@ -238,7 +238,7 @@ subroutine control_init( )
co2_file, aero_file
! bgc & pflotran interface
- namelist /clm_inparm/ use_bgc_interface, use_clm_bgc, use_pflotran
+ namelist /clm_inparm/ use_clm_interface, use_clm_bgc, use_pflotran
namelist /clm_inparm/ use_dynroot
@@ -402,20 +402,22 @@ subroutine control_init( )
end if
! ----------------------------------------------------------------------
- !! bgc & pflotran interface
- if(.not.use_bgc_interface) then
- use_clm_bgc = .true.
+ ! bgc & pflotran interface
+ if(.not.use_clm_interface) then
+ use_clm_bgc = .false.
use_pflotran = .false.
- end if
-
- if (use_clm_bgc) then
- use_pflotran = .false.
- end if
-
- if (use_pflotran) then
- use_clm_bgc = .false.
- !! enable 'use_nitrif_denitrif' to initilize Nh4 & NO3 pools, NOT to implement 'nitrif_denitrif'
- use_nitrif_denitrif = .true.
+ else
+ ! use_clm_interface
+ if (use_clm_bgc) then
+ use_pflotran = .false.
+ end if
+
+ if (use_pflotran) then
+ use_clm_bgc = .false.
+ ! enable 'use_nitrif_denitrif' to initilize Nh4 & NO3 pools,
+ ! but NOT to implement 'nitrif_denitrif'
+ use_nitrif_denitrif = .true.
+ end if
end if
endif ! end of if-masterproc if-block
@@ -736,7 +738,7 @@ subroutine control_spmd()
call mpi_bcast (domain_decomp_type, len(domain_decomp_type), MPI_CHARACTER, 0, mpicom, ier)
! bgc & pflotran interface
- call mpi_bcast (use_bgc_interface, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_clm_interface, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_clm_bgc, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_pflotran, 1, MPI_LOGICAL, 0, mpicom, ier)
diff --git a/components/clm/src/main/filterMod.F90 b/components/clm/src/main/filterMod.F90
index 859bd884196d..2b73636c3434 100644
--- a/components/clm/src/main/filterMod.F90
+++ b/components/clm/src/main/filterMod.F90
@@ -60,6 +60,9 @@ module filterMod
integer, pointer :: hydrologyc(:) ! hydrology filter (columns)
integer :: num_hydrologyc ! number of columns in hydrology filter
+ integer, pointer :: hydrononsoic(:) ! non-soil hydrology filter (columns)
+ integer :: num_hydrononsoic ! number of columns in non-soil hydrology filter
+
integer, pointer :: urbanl(:) ! urban filter (landunits)
integer :: num_urbanl ! number of landunits in urban filter
integer, pointer :: nourbanl(:) ! non-urban filter (landunits)
@@ -195,6 +198,7 @@ subroutine allocFiltersOneGroup(this_filter)
allocate(this_filter(nc)%natvegp(bounds%endp-bounds%begp+1))
allocate(this_filter(nc)%hydrologyc(bounds%endc-bounds%begc+1))
+ allocate(this_filter(nc)%hydrononsoic(bounds%endc-bounds%begc+1))
allocate(this_filter(nc)%urbanp(bounds%endp-bounds%begp+1))
allocate(this_filter(nc)%nourbanp(bounds%endp-bounds%begp+1))
@@ -364,6 +368,7 @@ subroutine setFiltersOneGroup(bounds, this_filter, include_inactive, icemask_grc
! Create column-level hydrology filter (soil and Urban pervious road cols)
f = 0
+ fn= 0
do c = bounds%begc,bounds%endc
if (col_pp%active(c) .or. include_inactive) then
l =col_pp%landunit(c)
@@ -371,10 +376,17 @@ subroutine setFiltersOneGroup(bounds, this_filter, include_inactive, icemask_grc
lun_pp%itype(l) == istcrop) then
f = f + 1
this_filter(nc)%hydrologyc(f) = c
+
+ if (col_pp%itype(c) == icol_road_perv) then
+ fn = fn + 1
+ this_filter(nc)%hydrononsoic(fn) = c
+ end if
+
end if
end if
end do
this_filter(nc)%num_hydrologyc = f
+ this_filter(nc)%num_hydrononsoic = fn
! Create prognostic crop and soil w/o prog. crop filters at pft-level
! according to where the crop model should be used
diff --git a/components/clm/src/main/surfrdMod.F90 b/components/clm/src/main/surfrdMod.F90
index 9da0541be9ed..11f8155f8c84 100644
--- a/components/clm/src/main/surfrdMod.F90
+++ b/components/clm/src/main/surfrdMod.F90
@@ -15,7 +15,7 @@ module surfrdMod
use clm_varctl , only : create_glacier_mec_landunit, use_cndv
use surfrdUtilsMod , only : check_sums_equal_1
use ncdio_pio , only : file_desc_t, var_desc_t, ncd_pio_openfile, ncd_pio_closefile
- use ncdio_pio , only : ncd_io, check_var, ncd_inqfdims, check_dim, ncd_inqdid
+ use ncdio_pio , only : ncd_io, check_var, ncd_inqfdims, check_dim, ncd_inqdid, ncd_inqdlen
use pio
use spmdMod
!
@@ -139,6 +139,7 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename)
use clm_varcon, only : spval, re
use domainMod , only : domain_type, domain_init, domain_clean, lon1d, lat1d
use fileutils , only : getfil
+ use clm_varctl, only : use_pflotran
!
! !ARGUMENTS:
integer ,intent(in) :: begg, endg
@@ -160,10 +161,16 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename)
logical :: isgrid2d ! true => file is 2d lat/lon
logical :: istype_domain ! true => input file is of type domain
real(r8), allocatable :: rdata2d(:,:) ! temporary
+ real(r8), allocatable :: rdata3d(:,:,:) ! temporary ! pflotran
character(len=16) :: vname ! temporary
character(len=256):: locfn ! local file name
integer :: n ! indices
real(r8):: eps = 1.0e-12_r8 ! lat/lon error tolerance
+
+ ! pflotran:beg-----------------------------
+ integer :: j, np, nv
+
+ ! pflotran:end-----------------------------
character(len=32) :: subname = 'surfrd_get_grid' ! subroutine name
!-----------------------------------------------------------------------
@@ -179,6 +186,15 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename)
! Determine dimensions
call ncd_inqfdims(ncid, isgrid2d, ni, nj, ns)
+
+ ! pflotran:beg-----------------------------------------------
+ call ncd_inqdlen(ncid, dimid, nv, 'nv')
+ if (nv>0) then
+ ldomain%nv = nv
+ else
+ ldomain%nv = 0
+ endif
+ ! pflotran:end-----------------------------------------------
! Determine isgrid2d flag for domain
call domain_init(ldomain, isgrid2d=isgrid2d, ni=ni, nj=nj, nbeg=begg, nend=endg)
@@ -206,6 +222,21 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename)
call ncd_io(ncid=ncid, varname= 'yc', flag='read', data=ldomain%latc, &
dim1name=grlnd, readvar=readvar)
if (.not. readvar) call endrun( msg=' ERROR: yc NOT on file'//errMsg(__FILE__, __LINE__))
+
+ ! pflotran:beg-----------------------------------------------
+ ! user-defined grid-cell vertices (ususally 'nv' is 4,
+ ! but for future use, we set the following if condition of 'nv>=3' so that possible to use TIN grids
+ if (ldomain%nv>=3 .and. use_pflotran) then
+ call ncd_io(ncid=ncid, varname='xv', flag='read', data=ldomain%lonv, &
+ dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) call endrun( msg=trim(subname)//' ERROR: xv NOT on file'//errMsg(__FILE__, __LINE__))
+
+ call ncd_io(ncid=ncid, varname='yv', flag='read', data=ldomain%latv, &
+ dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) call endrun( msg=trim(subname)//' ERROR: yv NOT on file'//errMsg(__FILE__, __LINE__))
+
+ end if
+ ! pflotran:end-----------------------------------------------
else
call ncd_io(ncid=ncid, varname= 'AREA', flag='read', data=ldomain%area, &
dim1name=grlnd, readvar=readvar)
@@ -218,9 +249,27 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename)
call ncd_io(ncid=ncid, varname= 'LATIXY', flag='read', data=ldomain%latc, &
dim1name=grlnd, readvar=readvar)
if (.not. readvar) call endrun( msg=' ERROR: LATIXY NOT on file'//errMsg(__FILE__, __LINE__))
+
+ ! pflotran:beg-----------------------------------------------
+ ! user-defined grid-cell vertices (ususally 'nv' is 4,
+ ! but for future use, we set the following if condition of 'nv>=3' so that possible to use TIN grids
+ if (ldomain%nv>=3 .and. use_pflotran) then
+
+ call ncd_io(ncid=ncid, varname='LONGV', flag='read', data=ldomain%lonv, &
+ dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) call endrun( msg=trim(subname)//' ERROR: LONGV NOT on file'//errMsg(__FILE__, __LINE__))
+
+ call ncd_io(ncid=ncid, varname='LATIV', flag='read', data=ldomain%latv, &
+ dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) call endrun( msg=trim(subname)//' ERROR: LATIV NOT on file'//errMsg(__FILE__, __LINE__))
+
+ end if
+ ! pflotran:end-----------------------------------------------
end if
- if (isgrid2d) then
+
+ ! let lat1d/lon1d data available for all grid-types, if coupled with PFLOTRAN.
+ if (isgrid2d .or. use_pflotran) then
allocate(rdata2d(ni,nj), lon1d(ni), lat1d(nj))
if (istype_domain) then
vname = 'xc'
@@ -237,7 +286,81 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename)
call ncd_io(ncid=ncid, varname=trim(vname), data=rdata2d, flag='read', readvar=readvar)
lat1d(:) = rdata2d(1,:)
deallocate(rdata2d)
- end if
+
+ ! pflotran:beg-----------------------------------------------
+ ! find the origin of ldomain, if vertices of first grid known
+ if (use_pflotran) then
+ ldomain%lon0 = -9999._r8
+ ldomain%lat0 = -9999._r8
+ if (ldomain%nv==4 .and. ldomain%nv /= huge(1)) then
+ allocate(rdata3d(ni,nj,nv))
+ if (istype_domain) then
+ vname = 'xv'
+ else
+ vname = 'LONGV'
+ end if
+
+ call ncd_io(ncid=ncid, varname=trim(vname), data=rdata3d, flag='read', readvar=readvar)
+
+ if (readvar) then
+ ldomain%lon0 = 0._r8
+ np=0
+ do j=1,nv
+ ! may have issue if mixed longitude values (i.e. 0~360 or -180~180)
+ if ( ni>1 .and. &
+ ( (rdata3d(1,1,j) < lon1d(1) .and. rdata3d(1,1,j) < lon1d(2)) .or. &
+ (rdata3d(1,1,j) > lon1d(1) .and. rdata3d(1,1,j) > lon1d(2)) ) ) then
+ np = np + 1
+ ldomain%lon0 = ldomain%lon0+rdata3d(1,1,j)
+
+ else if (ni==1 .and. rdata3d(1,1,j)0) then
+ ldomain%lon0 = ldomain%lon0/np
+ else
+ ldomain%lon0 = -9999._r8
+ end if
+ end if
+
+ !
+ if (istype_domain) then
+ vname = 'yv'
+ else
+ vname = 'LATIV'
+ end if
+ call ncd_io(ncid=ncid, varname=trim(vname), data=rdata3d, flag='read', readvar=readvar)
+ if (readvar) then
+ ldomain%lat0 = 0._r8
+ np=0
+ do j=1,nv
+ if ( nj>1 .and. &
+ ( (rdata3d(1,1,j) < lat1d(1) .and. rdata3d(1,1,j) < lat1d(2)) .or. &
+ (rdata3d(1,1,j) > lat1d(1) .and. rdata3d(1,1,j) > lat1d(2)) ) ) then
+ np = np + 1
+ ldomain%lat0 = ldomain%lat0+rdata3d(1,1,j)
+
+ else if (nj==1 .and. rdata3d(1,1,j)0) then
+ ldomain%lat0 = ldomain%lat0/np
+ else
+ ldomain%lat0 = -9999._r8
+ end if
+ end if
+ !
+ deallocate(rdata3d)
+ end if
+ end if
+ ! pflotran:end-----------------------------------------------
+ end if ! if (isgrid2d .or. use_pflotran)
+
+
! Check lat limited to -90,90
@@ -495,6 +618,7 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat)
end if
call ncd_inqfdims(ncid, isgrid2d, ni, nj, ns)
+ surfdata_domain%nv = 0 ! must be initialized to 0 here prior to call 'domain_init'
call domain_init(surfdata_domain, isgrid2d, ni, nj, begg, endg, clmlevel=grlnd)
call ncd_io(ncid=ncid, varname=lon_var, flag='read', data=surfdata_domain%lonc, &
diff --git a/components/clm/src/utils/clm_time_manager.F90 b/components/clm/src/utils/clm_time_manager.F90
index cc5e2aa6a41a..f12102f4d280 100644
--- a/components/clm/src/utils/clm_time_manager.F90
+++ b/components/clm/src/utils/clm_time_manager.F90
@@ -50,7 +50,7 @@ module clm_time_manager
is_perpetual, &! return true if perpetual calendar is in use
is_restart, &! return true if this is a restart run
update_rad_dtime, &! track radiation interval via nstep
- !!below used by pflotran
+ !below used by pflotran
nsstep, &! (re-)start timestep
nestep ! ending timestep
@@ -112,7 +112,8 @@ module clm_time_manager
private :: timemgr_spmdbcast
private :: init_calendar
private :: init_clock
- private :: calc_nestep
+! private :: calc_nestep
+ public :: calc_nestep !pflotran
private :: timemgr_print
private :: TimeGetymd
@@ -632,7 +633,7 @@ subroutine timemgr_restart( )
tm_first_restart_step = .true.
- !! pflotran: nsstep
+ ! pflotran: nsstep
! save the first restart 'nstep'
nsstep = get_nstep()
diff --git a/components/clm/src/utils/domainMod.F90 b/components/clm/src/utils/domainMod.F90
index 2d752adcc1b4..b82f97321e19 100644
--- a/components/clm/src/utils/domainMod.F90
+++ b/components/clm/src/utils/domainMod.F90
@@ -40,6 +40,15 @@ module domainMod
! (glcmask is just a guess at the appropriate mask, known at initialization - in contrast to icemask, which is the true mask obtained from glc)
character*16 :: set ! flag to check if domain is set
logical :: decomped ! decomposed locally or global copy
+
+ ! pflotran:beg-----------------------------------------------------
+ integer :: nv ! number of vertices
+ real(r8),pointer :: latv(:,:) ! latitude of grid cell's vertices (deg)
+ real(r8),pointer :: lonv(:,:) ! longitude of grid cell's vertices (deg)
+ real(r8) :: lon0 ! the origin lon/lat (Most western/southern corner, if not globally covered grids; OR -180W(360E)/-90N)
+ real(r8) :: lat0 ! the origin lon/lat (Most western/southern corner, if not globally covered grids; OR -180W(360E)/-90N)
+
+ ! pflotran:end-----------------------------------------------------
end type domain_type
type(domain_type) , public :: ldomain
@@ -115,6 +124,24 @@ subroutine domain_init(domain,isgrid2d,ni,nj,nbeg,nend,clmlevel)
call shr_sys_abort('domain_init ERROR: allocate mask, frac, lat, lon, area ')
endif
+ ! pflotran:beg-----------------------------------------------------
+ ! 'nv' is user-defined, so it must be initialized or assigned value prior to call this subroutine
+ if (domain%nv > 0 .and. domain%nv /= huge(1)) then
+ if(.not.associated(domain%lonv)) then
+ allocate(domain%lonv(nb:ne, 1:domain%nv), stat=ier)
+ if (ier /= 0) &
+ call shr_sys_abort('domain_init ERROR: allocate lonv ')
+ domain%lonv = nan
+ endif
+ if(.not.associated(domain%latv)) then
+ allocate(domain%latv(nb:ne, 1:domain%nv))
+ if (ier /= 0) &
+ call shr_sys_abort('domain_init ERROR: allocate latv ')
+ domain%latv = nan
+ endif
+ end if
+ ! pflotran:end-----------------------------------------------------
+
if (present(clmlevel)) then
domain%clmlevel = clmlevel
endif
@@ -179,6 +206,26 @@ subroutine domain_clean(domain)
if (ier /= 0) then
call shr_sys_abort('domain_clean ERROR: deallocate mask, frac, lat, lon, area ')
endif
+
+ ! pflotran:beg-----------------------------------------------------
+ ! 'nv' is user-defined, so it must be initialized or assigned value prior to call this subroutine
+ if (domain%nv > 0 .and. domain%nv /= huge(1)) then
+ if (associated(domain%lonv)) then
+ deallocate(domain%lonv, stat=ier)
+ if (ier /= 0) &
+ call shr_sys_abort('domain_clean ERROR: deallocate lonv ')
+ nullify(domain%lonv)
+ endif
+
+ if (associated(domain%latv)) then
+ deallocate(domain%latv, stat=ier)
+ if (ier /= 0) &
+ call shr_sys_abort('domain_clean ERROR: deallocate latv ')
+ nullify(domain%latv)
+ endif
+ endif
+ ! pflotran:beg-----------------------------------------------------
+
else
if (masterproc) then
write(iulog,*) 'domain_clean WARN: clean domain unecessary '