From 73c87f3e3e2e1c48611a5f9fbb53959921767eef Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Fri, 2 Jun 2017 10:04:56 -0400 Subject: [PATCH 01/35] Migrating NGEE-Arctic CLM-PFLOTRAN codes - STEP 1: coding. --- .../clm/src/biogeochem/CNAllocationMod.F90 | 66 +- .../clm/src/biogeochem/CNBalanceCheckMod.F90 | 43 +- .../clm/src/biogeochem/CNCStateUpdate3Mod.F90 | 26 +- .../clm/src/biogeochem/CNCarbonFluxType.F90 | 168 +- .../clm/src/biogeochem/CNCarbonStateType.F90 | 25 +- .../src/biogeochem/CNDecompCascadeBGCMod.F90 | 27 +- .../src/biogeochem/CNDecompCascadeCNMod.F90 | 48 +- .../src/biogeochem/CNDecompCascadeConType.F90 | 5 +- components/clm/src/biogeochem/CNDecompMod.F90 | 25 +- .../clm/src/biogeochem/CNEcosystemDynMod.F90 | 30 +- .../clm/src/biogeochem/CNNStateUpdate3Mod.F90 | 5 + .../clm/src/biogeochem/CNNitrogenFluxType.F90 | 204 +- .../src/biogeochem/CNNitrogenStateType.F90 | 51 +- .../clm/src/main/clm_bgc_interfaceMod.F90 | 434 +- .../clm/src/main/clm_bgc_interface_data.F90 | 60 +- components/clm/src/main/clm_driver.F90 | 8 +- components/clm/src/main/clm_initializeMod.F90 | 2 +- .../src/main/clm_pflotran_interfaceMod.F90 | 5407 ++++++++++------- components/clm/src/main/clm_varctl.F90 | 3 +- components/clm/src/main/controlMod.F90 | 2 +- components/clm/src/main/surfrdMod.F90 | 129 +- components/clm/src/utils/clm_time_manager.F90 | 3 +- components/clm/src/utils/domainMod.F90 | 47 + 23 files changed, 4171 insertions(+), 2647 deletions(-) diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index e6711180c0fb..e95b3a36ef34 100755 --- a/components/clm/src/biogeochem/CNAllocationMod.F90 +++ b/components/clm/src/biogeochem/CNAllocationMod.F90 @@ -3926,22 +3926,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 +3955,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 + 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 +3992,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 + 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 +4015,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 ! !---------------------------------------------------------------- @@ -4070,7 +4074,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) !!original: if (use_nitrif_denitrif): sminn_tot(c) = sminn_tot(c) + (smin_no3_vr(c,j) + smin_nh4_vr(c,j)) * dzsoi_decomp(j) + end if end do end do @@ -4078,10 +4087,15 @@ 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 + end if !! 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 do diff --git a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 index 36b147dc7780..e0379cf8b223 100644 --- a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 +++ b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 @@ -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 @@ -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 @@ -449,9 +464,9 @@ subroutine PBalanceCheck(bounds, & !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 + 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 ,& diff --git a/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 b/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 index e38819b4c0a1..4d51ce5599fa 100644 --- a/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 +++ b/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 @@ -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 9750574fba76..be3c302ada66 100644 --- a/components/clm/src/biogeochem/CNCarbonFluxType.F90 +++ b/components/clm/src/biogeochem/CNCarbonFluxType.F90 @@ -4370,6 +4370,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 @@ -4385,6 +4386,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(& @@ -4765,6 +4767,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 @@ -4779,9 +4784,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) + & @@ -4850,7 +4855,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) = & @@ -4907,10 +4912,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 @@ -4941,81 +4943,83 @@ 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 + 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) + 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) + this%som_c_leached_col(c) = & + this%som_c_leached_col(c) + & + this%decomp_cpools_leached_col(c,l) end do end do - endif + endif + ! debug do fc = 1,num_soilc - c = filter_soilc(fc) - this%plant_to_litter_cflux(c) = 0._r8 - this%plant_to_cwd_cflux(c) = 0._r8 - do j = 1, nlevdecomp - this%plant_to_litter_cflux(c) = & - this%plant_to_litter_cflux(c) + & - this%phenology_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + & - this%phenology_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + & - this%phenology_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + & - this%gap_mortality_c_to_litr_met_c_col(c,j)* dzsoi_decomp(j) + & - this%gap_mortality_c_to_litr_cel_c_col(c,j)* dzsoi_decomp(j) + & - this%gap_mortality_c_to_litr_lig_c_col(c,j)* dzsoi_decomp(j) + & - this%m_c_to_litr_met_fire_col(c,j)* dzsoi_decomp(j) + & - this%m_c_to_litr_cel_fire_col(c,j)* dzsoi_decomp(j) + & - this%m_c_to_litr_lig_fire_col(c,j)* dzsoi_decomp(j) - this%plant_to_cwd_cflux(c) = & - this%plant_to_cwd_cflux(c) + & - this%gap_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j) + & - this%fire_mortality_c_to_cwdc_col(c,j)* dzsoi_decomp(j) - end do + 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 @@ -5033,7 +5037,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc) ! ! !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 ! @@ -5063,10 +5067,9 @@ 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) + & @@ -5079,7 +5082,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) + & @@ -5100,7 +5103,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 @@ -5111,7 +5114,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 @@ -5120,7 +5123,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) @@ -5128,7 +5130,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) + & @@ -5136,14 +5138,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) @@ -5154,9 +5155,9 @@ 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%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) elseif (l==i_cel_lit) then @@ -5165,9 +5166,9 @@ 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%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) elseif (l==i_lig_lit) then @@ -5176,9 +5177,9 @@ 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%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) ! for cwd @@ -5188,17 +5189,18 @@ 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%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 + !! wgs:2017 ! 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%decomp_cpools_transport_tendency_col(c,j,l) !!& ! - this%m_decomp_cpools_to_fire_vr_col(c,j,l) end if @@ -5331,7 +5333,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 b18eb5c57a38..bd2a3e00586f 100644 --- a/components/clm/src/biogeochem/CNCarbonStateType.F90 +++ b/components/clm/src/biogeochem/CNCarbonStateType.F90 @@ -20,6 +20,10 @@ 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_bgc_interface, use_pflotran, pf_cmode + ! ! !PUBLIC TYPES: @@ -2719,13 +2723,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 @@ -2885,7 +2889,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 @@ -2900,6 +2904,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 @@ -2979,6 +2984,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 @@ -2989,7 +2996,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) = & @@ -3117,7 +3124,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..236f2038a4e1 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..e1697958cf28 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..97aeda08d843 100644 --- a/components/clm/src/biogeochem/CNDecompMod.F90 +++ b/components/clm/src/biogeochem/CNDecompMod.F90 @@ -214,13 +214,6 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, & !!------------------------------------------------------------------------------------------------- ! 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 !!------------------------------------------------------------------------------------------------- ! set initial values for potential C and N fluxes @@ -701,8 +694,11 @@ 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) @@ -759,15 +755,28 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so ! 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(c) = 1.0_r8 + end if + end do + if (use_lch4) then ! Add up potential hr for methane calculations diff --git a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 b/components/clm/src/biogeochem/CNEcosystemDynMod.F90 index 048768f2c72a..aa0d529b35b5 100755 --- a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 +++ b/components/clm/src/biogeochem/CNEcosystemDynMod.F90 @@ -180,16 +180,16 @@ subroutine CNEcosystemDynLeaching(bounds, num_soilc, filter_soilc, & 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') @@ -430,14 +430,14 @@ subroutine CNEcosystemDynNoLeaching1(bounds, & 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 +!! plfotran: 'decomp_rate_constants' must be calculated before entering "clm_bgc_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: diff --git a/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 b/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 index 057600453fde..acf29d33da75 100644 --- a/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 +++ b/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 @@ -74,8 +74,12 @@ 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 !!wgs:2017 + ns%sminn_vr_col(c,j) = ns%sminn_vr_col(c,j) + ns%smin_nh4sorb_vr_col(c,j) + end if end if + 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 @@ -84,6 +88,7 @@ subroutine NStateUpdate3(num_soilc, filter_soilc, num_soilp, filter_soilp, & 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 67be7a52c2c3..952efc06670f 100644 --- a/components/clm/src/biogeochem/CNNitrogenFluxType.F90 +++ b/components/clm/src/biogeochem/CNNitrogenFluxType.F90 @@ -338,7 +338,7 @@ 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 @@ -360,8 +360,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 @@ -755,7 +755,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 @@ -1463,14 +1463,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', & @@ -1491,28 +1491,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', & @@ -1533,14 +1535,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', & @@ -1554,28 +1558,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', & @@ -1702,21 +1710,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', & @@ -1724,21 +1735,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', & @@ -2141,7 +2155,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(:,:) @@ -2161,7 +2175,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(:,:) @@ -2522,7 +2536,8 @@ subroutine SetValues ( this, & this%gross_nmin_col(i) = value_column this%net_nmin_col(i) = value_column this%denit_col(i) = value_column - if (use_nitrif_denitrif .or. is_active_betr_bgc) then + if (use_nitrif_denitrif .or. is_active_betr_bgc & + .or. (use_pflotran.and.pf_cmode) ) then this%f_nit_col(i) = value_column this%pot_f_nit_col(i) = value_column this%f_denit_col(i) = value_column @@ -2636,6 +2651,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 @@ -2645,9 +2663,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 !------------------------------------------------------------------------ @@ -2696,6 +2711,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, do_betr_leaching + use clm_varpar , only: nlevdecomp_full ! ! !ARGUMENTS: class (nitrogenflux_type) :: this @@ -2709,6 +2725,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 @@ -2761,6 +2778,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 @@ -2778,7 +2798,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) @@ -2796,7 +2816,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) = & @@ -2807,7 +2827,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) = & @@ -2840,7 +2860,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 +2913,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil ! BeTR is active - do j = 1, nlevdecomp + do j = 1, nlev do fc = 1,num_soilc c = filter_soilc(fc) this%f_denit_col(c) = & @@ -2935,7 +2955,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) = & @@ -2960,7 +2980,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) = & @@ -3002,7 +3022,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) = & @@ -3028,7 +3048,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) + & @@ -3050,7 +3070,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) + & @@ -3061,7 +3081,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil ! bgc interface & pflotran !---------------------------------------------------------------- - if (use_bgc_interface) then + if (use_bgc_interface .and. pf_cmode) then call NSummary_interface(this, bounds, num_soilc, filter_soilc) end if !---------------------------------------------------------------- @@ -3073,11 +3093,11 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) ! ! !DESCRIPTION: !! bgc interface & pflotran: -! On the radiation time step, perform olumn-level nitrogen +! 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 @@ -3091,7 +3111,7 @@ 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 @@ -3106,11 +3126,13 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) if (use_pflotran .and. pf_cmode) then ! nitrification-denitrification rates (not yet passing out from PF, but will) +!! wgs:beg------------------------------------------------ +!! 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) @@ -3123,8 +3145,9 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) this%denit_col(c) = this%f_denit_col(c) end do +!! wgs: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 @@ -3134,8 +3157,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) + & @@ -3152,27 +3176,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 @@ -3182,32 +3213,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 @@ -3216,8 +3240,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%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) elseif (l==i_cel_lit) then @@ -3226,8 +3250,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%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) elseif (l==i_lig_lit) then @@ -3236,8 +3260,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%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) ! for cwd @@ -3247,8 +3271,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) + + this%harvest_n_to_cwdn_col(c,j) & + + this%fire_mortality_n_to_cwdn_col(c,j) ! for som n ! else @@ -3270,32 +3294,34 @@ 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 !!------------------------------------------------------------------------------------------------- diff --git a/components/clm/src/biogeochem/CNNitrogenStateType.F90 b/components/clm/src/biogeochem/CNNitrogenStateType.F90 index bcaf8eb705db..18c9417c790c 100644 --- a/components/clm/src/biogeochem/CNNitrogenStateType.F90 +++ b/components/clm/src/biogeochem/CNNitrogenStateType.F90 @@ -617,7 +617,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.)', & @@ -629,10 +629,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 @@ -646,11 +648,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', & @@ -874,15 +878,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 @@ -1134,7 +1142,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(:,:) @@ -1154,7 +1162,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(:,:) @@ -1240,7 +1248,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 @@ -1422,7 +1430,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 @@ -1442,7 +1450,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 @@ -1503,6 +1511,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 @@ -1516,6 +1525,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 @@ -1579,7 +1589,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 @@ -1588,7 +1601,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) = & @@ -1614,7 +1627,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) = & @@ -1743,7 +1756,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) = & @@ -1757,7 +1770,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/main/clm_bgc_interfaceMod.F90 b/components/clm/src/main/clm_bgc_interfaceMod.F90 index 3a7ba894214f..d980db3678ba 100644 --- a/components/clm/src/main/clm_bgc_interfaceMod.F90 +++ b/components/clm/src/main/clm_bgc_interfaceMod.F90 @@ -59,11 +59,12 @@ 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 ! 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 @@ -174,7 +175,7 @@ subroutine get_clm_bgc_data(clm_bgc_data,bounds, & call get_clm_soil_property(clm_bgc_data, & bounds, num_soilc, filter_soilc, & - soilstate_vars) + soilstate_vars, cnstate_vars) call get_clm_soil_thermohydro(clm_bgc_data, & bounds, num_soilc, filter_soilc, & @@ -200,10 +201,11 @@ end subroutine get_clm_bgc_data !!-------------------------------------------------------------------------------------- subroutine get_clm_soil_property(clm_bgc_data, & 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 +220,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 - 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) @@ -238,7 +242,7 @@ subroutine get_clm_soil_property(clm_bgc_data, & 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) + 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 , & @@ -248,7 +252,11 @@ subroutine get_clm_soil_property(clm_bgc_data, & 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 & ) @@ -261,29 +269,36 @@ subroutine get_clm_soil_property(clm_bgc_data, & clm_bgc_data%initial_cn_ratio(:) = initial_cn_ratio(:) clm_bgc_data%initial_cp_ratio(:) = initial_cp_ratio(:) - - + clm_bgc_data%decomp_k_pools(:) = decomp_k_pools(1:ndecomp_pools) + clm_bgc_data%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_bgc_data%z(c,:) = z(c,:) + clm_bgc_data%zi(c,:) = zi(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,:) + + ! + do k = 1, ndecomp_cascade_transitions + clm_bgc_data%rf_decomp_cascade_col(c,:,k) = rf_decomp_cascade(c,:,k) + clm_bgc_data%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 !!-------------------------------------------------------------------------------------- @@ -325,9 +340,6 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, & ! !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) !EOP !----------------------------------------------------------------------- @@ -340,6 +352,8 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, & 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 + 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] 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) @@ -378,9 +392,6 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, & !-------------------------------------------------------------------------------------- ! -! 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(:) @@ -407,24 +418,25 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, & clm_bgc_data%htvp_col(c) = htvp(c) clm_bgc_data%eflx_bot_col(c) = eflx_bot(c) -! do j = 1, nlevsoi - clm_bgc_data%soilpsi_col(c,:) = soilpsi(c,:) - clm_bgc_data%rootfr_col(c,:) = rootfr(c,:) + clm_bgc_data%soilpsi_col(c,:) = soilpsi(c,:) + clm_bgc_data%rootfr_col(c,:) = rootfr(c,:) + + clm_bgc_data%watmin_col(c,:) = watmin(c,:) + clm_bgc_data%sucmin_col(c,:) = sucmin(c,:) - 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,:) + 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,:) - clm_bgc_data%t_soisno_col(c,:) = t_soisno(c,:) + 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,:) + 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 do ! CLM appears NO column-level ground-heat-flux variable, instead by 'patch' @@ -442,11 +454,6 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, & end if end do 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_thermohydro @@ -476,20 +483,16 @@ subroutine get_clm_bgc_state(clm_bgc_data, & ! 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 @@ -499,13 +502,14 @@ subroutine get_clm_bgc_state(clm_bgc_data, & primp_vr => phosphorusstate_vars%primp_vr_col & ! [real(r8) (:,:) ! col (gP/m3) vertically-resolved soil primary mineral P ) ! + 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 +522,28 @@ 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 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) ! ! !DESCRIPTION: !! 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,6 +556,7 @@ 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 character(len=256) :: subname = "get_clm_bgc_flux" @@ -561,10 +564,9 @@ subroutine get_clm_bgc_flux(clm_bgc_data, & ! !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 +583,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 +596,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,51 +613,69 @@ 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 @@ -672,7 +698,6 @@ 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(waterstate_type), intent(inout) :: waterstate_vars type(clm_bgc_interface_data_type), intent(in) :: clm_bgc_data @@ -689,11 +714,9 @@ 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 end do end associate @@ -728,11 +751,10 @@ 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_bgc_data%t_soisno_col(c,:) end do end associate @@ -740,18 +762,12 @@ end subroutine update_soil_temperature !!-------------------------------------------------------------------------------------- !!-------------------------------------------------------------------------------------- - subroutine update_bgc_state_decomp(clm_bgc_data, & + 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 @@ -767,10 +783,6 @@ subroutine update_bgc_state_decomp(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) !------------------------------------------------------------------------------------ ! @@ -780,17 +792,14 @@ subroutine update_bgc_state_decomp(clm_bgc_data, & 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 @@ -804,9 +813,6 @@ subroutine update_bgc_state_smin(clm_bgc_data, & 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 @@ -822,10 +828,6 @@ subroutine update_bgc_state_smin(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 +846,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,9 +860,7 @@ 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 @@ -875,10 +873,6 @@ subroutine update_bgc_flux_decomp_sourcesink(clm_bgc_data, & 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 @@ -903,13 +897,11 @@ 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 @@ -922,10 +914,6 @@ subroutine update_bgc_flux_decomp_cascade(clm_bgc_data, & 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 @@ -960,8 +948,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,7 +961,6 @@ 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 @@ -987,12 +972,6 @@ subroutine update_bgc_flux_smin(clm_bgc_data, & 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 @@ -1033,6 +1012,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 +1028,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,34 +1044,35 @@ 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 !!-------------------------------------------------------------------------------------- @@ -1099,12 +1082,6 @@ subroutine update_bgc_flux_nitdenit(clm_bgc_data, & 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 @@ -1130,16 +1107,13 @@ 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 @@ -1150,8 +1124,6 @@ subroutine update_bgc_flux_gas_pf(clm_bgc_data, & bounds, num_soilc, filter_soilc, & carbonflux_vars, nitrogenflux_vars) -! use clm_time_manager, only : get_step_size, get_nstep - ! PFLOTRAN gas fluxes implicit none @@ -1166,10 +1138,6 @@ subroutine update_bgc_flux_gas_pf(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,17 +1152,15 @@ 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 @@ -1313,7 +1279,6 @@ subroutine clm_bgc_run(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(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,11 +1287,8 @@ 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 @@ -1381,9 +1343,6 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, & 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,11 +1351,8 @@ 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 @@ -1407,8 +1363,6 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, & !----------------------------------------------------------------------- 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 @@ -1463,34 +1417,31 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, & alt_indx(c) = clm_bgc_data%alt_indx_col(c) finundated(c) = clm_bgc_data%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_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,:) - 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_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,:) - t_soisno(c,:) = clm_bgc_data%t_soisno_col(c,:) + t_soisno(c,:) = clm_bgc_data%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_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,:) -! end do end do !!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) @@ -1507,7 +1458,6 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, & 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 end associate @@ -1528,13 +1478,9 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, & 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 @@ -1587,7 +1533,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 +1545,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 ) diff --git a/components/clm/src/main/clm_bgc_interface_data.F90 b/components/clm/src/main/clm_bgc_interface_data.F90 index 64382b0bbda6..cb6758ea6ca4 100644 --- a/components/clm/src/main/clm_bgc_interface_data.F90 +++ b/components/clm/src/main/clm_bgc_interface_data.F90 @@ -5,15 +5,12 @@ module clm_bgc_interface_data ! Created by wgs @ ORNL ! ! date: 8/25/2015 +! update: 9/16/2016, 2/2/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 @@ -22,7 +19,7 @@ module clm_bgc_interface_data type, public :: clm_bgc_interface_data_type ! 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,10 +27,11 @@ 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 + real(r8), pointer :: initial_cp_ratio (:) ! c:p ratio for initialization of pools ! col: 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: @@ -41,7 +39,9 @@ module clm_bgc_interface_data 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) @@ -72,6 +72,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 +115,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) @@ -184,14 +192,16 @@ module clm_bgc_interface_data 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,6 +215,10 @@ 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) + ! 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 + ! 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) [+] @@ -242,6 +256,7 @@ module clm_bgc_interface_data !!------------------------------------------------------------------------------------------------- subroutine Init(this, bounds) + use decompMod , only : bounds_type class(clm_bgc_interface_data_type) :: this type(bounds_type), intent(in) :: bounds @@ -253,12 +268,15 @@ end subroutine Init subroutine InitAllocate(this, bounds) !! 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: real(r8) :: ival = 0.0_r8 ! initial value - class(clm_bgc_interface_data_type) :: this - type(bounds_type), intent(in) :: bounds + class(clm_bgc_interface_data_type) :: this + type(bounds_type), intent(in) :: bounds !! LOCAL VARIABLES: integer :: begg, endg @@ -278,13 +296,16 @@ subroutine InitAllocate(this, bounds) ! 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,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%watmin_col (begc:endc,nlevgrnd)) ; this%watmin_col (:,:) = nan allocate(this%sucsat_col (begc:endc,nlevgrnd)) ; this%sucsat_col (:,:) = spval + allocate(this%sucmin_col (begc:endc,nlevgrnd)) ; this%sucmin_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 @@ -315,6 +336,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 +383,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 @@ -427,6 +460,10 @@ subroutine InitAllocate(this, bounds) 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 +472,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 diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index 5b969ac71c4b..c512d7824905 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -144,8 +144,9 @@ module clm_driver 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_time_manager , only : nsstep, nestep + 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 !!---------------------------------------------------------------------------- @@ -840,8 +841,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) !! STEP-2: (2) run pflotran !! STEP-2: (3) update clm_bgc_data from pflotran ! ------------------------------------------------------------------------- - call clm_pf_run(clm_bgc_data,bounds_clump, & - filter(nc)%num_soilc, filter(nc)%soilc) + call clm_pf_run(clm_bgc_data,bounds_clump, filter, nc) !! STEP-3: update CLM from clm_bgc_data call update_bgc_data_pf2clm(clm_bgc_data,bounds_clump, & diff --git a/components/clm/src/main/clm_initializeMod.F90 b/components/clm/src/main/clm_initializeMod.F90 index 8524a45f3f9a..219e6be27769 100644 --- a/components/clm/src/main/clm_initializeMod.F90 +++ b/components/clm/src/main/clm_initializeMod.F90 @@ -897,7 +897,7 @@ subroutine initialize2( ) call clm_bgc_data%Init(bounds_proc) ! PFLOTRAN initialization if (use_pflotran) then - call clm_pf_interface_init(bounds_proc) + call clm_pf_interface_init(bounds_proc, filter) end if end if call t_stopf('init_clm_bgc_interface_data & pflotran') diff --git a/components/clm/src/main/clm_pflotran_interfaceMod.F90 b/components/clm/src/main/clm_pflotran_interfaceMod.F90 index 0912c6c9dcc0..6891c036d0b6 100644 --- a/components/clm/src/main/clm_pflotran_interfaceMod.F90 +++ b/components/clm/src/main/clm_pflotran_interfaceMod.F90 @@ -1,7 +1,18 @@ -module clm_pflotran_interfaceMod -!#define FLEXIBLE_POOLS +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. + !---------------------------------------------------------------------------------------------- -! CLM-PFLOTRAN soil bgc coupling interface +! 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 @@ -9,8 +20,11 @@ module clm_pflotran_interfaceMod ! ! 2.Lawrence Berkley National Laboratory ! -! date: 2012 - 2015 -! modified (based on clm_bgc_interface): 8/28/2015, wgs +! date: 2012 - 2017 +! +! Modified by Gangsheng Wang @ ORNL based on clm_bgc_interfaceMod.F90: 8/28/2015, 2/2/2017 +! +! yfm: Added Thermal-Hydrology coupling subroutines: 04/2017 !---------------------------------------------------------------------------------------------- #include "shr_assert.h" @@ -24,61 +38,20 @@ module clm_pflotran_interfaceMod ! 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 - ! 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 + ! currently only works with soil columns, i.e. luntype of 'istsoil/istcrop' + ! use landunit_varcon , only : istsoil, istcrop ! (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 + !! (wgs,8/28/2015): ALM types/variables are replaced by clm_interface_data + use clm_interface_dataType, only : clm_interface_data_type #ifdef CLM_PFLOTRAN @@ -96,6 +69,9 @@ module clm_pflotran_interfaceMod #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 = '' @@ -114,25 +90,38 @@ module clm_pflotran_interfaceMod 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_bcwflx - private :: get_clm_bceflx + private :: get_clm_iceadj_porosity + ! 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 + !! 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 @@ -258,7 +247,7 @@ subroutine pflotran_not_available(subname) !EOP !----------------------------------------------------------------------- call endrun(trim(subname) // ": ERROR: CLM-PFLOTRAN interface has not been compiled " // & - "into this version of CLM.") + "into this version of ALM.") end subroutine pflotran_not_available @@ -286,41 +275,35 @@ end subroutine clm_pf_interface_init !-------------------------------------------------------------------------------------------- - subroutine clm_pf_run(clm_bgc_data,bounds, & - num_soilc, filter_soilc) + 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 - 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 + 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 pflotran_run_onestep(clm_bgc_data,bounds, & - num_soilc, filter_soilc) + 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 @@ -363,13 +346,18 @@ end subroutine clm_pf_finalize -#ifdef CLM_PFLOTRAN !************************************************************************************! -! The following is private and requires explicit coupling between CLM and PFLOTRAN -! -!------------------------------------------------------------------------------------! +! (BEGIN) +! Private interface subroutines, requiring explicit coupling between CLM and PFLOTRAN ! +#ifdef CLM_PFLOTRAN + + !==================================================================================================== + ! ! + ! Main Subroutines to Couple with PFLOTRAN ! + ! ! + !==================================================================================================== !----------------------------------------------------------------------- !BOP @@ -384,31 +372,42 @@ subroutine interface_init(bounds) ! ! !USES: use clm_varctl , only : iulog - use decompMod , only : get_proc_global, ldecomp - use spmdMod , only : mpicom, masterproc - use domainMod , only : ldomain + use GridcellType , only : grc + use LandunitType , only : lun + use ColumnType , only : col + 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 - use abortutils , only : endrun + use CNDecompCascadeConType , only : decomp_cascade_con - 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 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 "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" -#include "finclude/petscviewer.h" +#include "petsc/finclude/petscsys.h" +#include "petsc/finclude/petscvec.h" +#include "petsc/finclude/petscvec.h90" ! ! !REVISION HISTORY: @@ -419,88 +418,450 @@ subroutine interface_init(bounds) ! ! 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(bounds_type), intent(in) :: bounds ! bounds - !type(pflotran_model_type), pointer:: pflotran_m - class(realization_type), pointer :: realization - type(option_type), pointer :: option - PetscErrorCode :: ierr + 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 (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 + ltype => lun%itype , & ! [integer (:)] landunit type index + lgridcell => lun%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 - 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 + cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column + clandunit => col%landunit , & ! [integer (:)] landunit index of column + cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell) + cactive => col%active & ! [logic (:)] column active or not ) - !------------------------------------------------------------------------ + !!wgs:beg---------------------------------------------------------------- + !! wgs: ACME-v2: add lon0/lat0 to ldomain + lon0 = ldomain%lon0 + lat0 = ldomain%lat0 + !!wgs: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 = 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 + l = clandunit(c) + g = cgridcell(c) - col_pp%active(c) = .false. + 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%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,*) '%% clm_pf_interface_init %%' - write(iulog,*) '%%-----------------------------------------------------%%' + 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 - ! Determine necessary indices - call get_proc_global(numg, numl, numc, nump) + pf_clmnstep0 = get_nstep() - !------------------------------------------------------------------------ - allocate(pflotran_m) + !---------------------------------------------------------------------------------------- + ! (1) Initialize PETSc vector for data transfer between CLM and PFLOTRAN + call CLMPFLOTRANIDataInit() - ! Create PFLOTRAN model - call pflotranModelCreate(mpicom, pflotran_prefix, pflotran_m) - option => pflotran_m%option + !---------------------------------------------------------------------------------------- + ! (2) passing grid/mesh info to interface_data so that PF mesh can be established/mapped - call pflotranModelSetupMappingfiles(pflotran_m) + !(2a) domain/decompose + clm_pf_idata%nzclm_mapped = nlevgrnd ! the soil layer no. mapped btw CLM and PF for data-passing - ! initialize pflotran model - call pflotranModelStepperRunInit(pflotran_m) + 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 (subsurface_simulation_type) + 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." @@ -522,12 +878,6 @@ subroutine interface_init(bounds) 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 @@ -537,100 +887,150 @@ subroutine interface_init(bounds) !------------------------------------------------ - ! 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)) + ! 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)) - ! Save cell IDs of CLM grid cellcount = 0 - do g = bounds%begg, bounds%endg - gcount = g - bounds%begg + 1 + do colcount = 1, total_soilc + gid = mapped_gid(colcount) - do j = 1, clm_pf_idata%nzclm_mapped + ! 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_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 + 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) - clm_2dtop_cell_ids_nindex(gcount) = (g-1)*clm_pf_idata%nzclm_mapped + ! 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 - clm_2dbot_cell_ids_nindex(gcount) = g*clm_pf_idata%nzclm_mapped-1 enddo + deallocate(mapped_gid) + +#endif + ! 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_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 = (bounds%endg - bounds%begg + 1) - clm_pf_idata%ngclm_2dtop = (bounds%endg - bounds%begg + 1) + 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 = (bounds%endg - bounds%begg + 1) - clm_pf_idata%ngclm_2dbot = (bounds%endg - bounds%begg + 1) + 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 - ! 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 + 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(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 (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) + 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 - - ! 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) +#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 - ! 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) + 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) @@ -643,18 +1043,28 @@ subroutine interface_init(bounds) pf_hmode = .true. pf_tmode = .true. if (pflotran_m%option%use_th_freezing) then - pf_frzmode = .true. + pf_frzmode = .true. else - pf_frzmode = .false. + pf_frzmode = .false. endif - endif if(pflotran_m%option%ntrandof.gt.0) then pf_cmode = .true. ! initialized as '.false.' in clm initialization endif -!------------------------------------------------------------------------------------- + !! wgs:beg----------------------------------------------------------- + + ! force CLM soil domain into PFLOTRAN subsurface grids + + ! Currently always set soil hydraulic/BGC properties from CLM to PF + + ! Get top surface area of 3-D pflotran subsurface domain +! call pflotranModelGetTopFaceArea(pflotran_m) + !! wgs:end----------------------------------------------------------- + + ! Initialize PFLOTRAN states + call pflotranModelStepperRunInit(pflotran_m) end associate end subroutine interface_init @@ -665,8 +1075,7 @@ end subroutine interface_init ! ! !INTERFACE: - subroutine pflotran_run_onestep(clm_bgc_data,bounds, & - num_soilc, filter_soilc) + subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! ! !DESCRIPTION: ! @@ -674,42 +1083,32 @@ subroutine pflotran_run_onestep(clm_bgc_data,bounds, & ! '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 - -! 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(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_bgc_interface_data_type), intent(inout) :: clm_bgc_data + 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= .TRUE. ! let PF printout or not + logical :: ispfprint ! 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 + integer :: ierr !----------------------------------------------------------------------- - nstep = get_nstep() - nsstep + nstep = get_nstep() - pf_clmnstep0 !!nsstep dtime = get_step_size() if (is_first_step() .or. is_first_restart_step()) then @@ -718,209 +1117,139 @@ subroutine pflotran_run_onestep(clm_bgc_data,bounds, & 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 + 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, ispfprint) - ! Set CLM soil properties onto PFLOTRAN grid + call pflotranModelUpdateFinalWaypoint(pflotran_m, total_clmstep*dtime, dtime, ispfprint) - call get_clm_soil_properties(clm_bgc_data, & - bounds, num_soilc, filter_soilc) - call pflotranModelSetSoilProp(pflotran_m) + !! wgs:beg------------------------------------------------ + !! wgs: move from 'interface_init' + ! force CLM soil domain into PFLOTRAN subsurface grids + call get_clm_soil_dimension(clm_interface_data, bounds) - ! 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) + ! Currently always set soil hydraulic/BGC properties from CLM to PF + call get_clm_soil_properties(clm_interface_data, bounds, filters) - 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 + ! Get top surface area of 3-D pflotran subsurface domain + call pflotranModelGetTopFaceArea(pflotran_m) - ! 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 + !! wgs:end------------------------------------------------ - ! 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 + ! 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 !!if (isinitpf) + endif - ! (1) passing TH states from CLM to PF, if not H/TH mode NOT on in PF, every CLM time-step + ! (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.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) + 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, pf_hmode, pf_tmode) - endif + call pflotranModelUpdateTHfromCLM(pflotran_m, .FALSE., .FALSE.) ! pass TH to global_auxvar + + end if - ! ice-len adjusted porostiy + ! ice-len adjusted porostiy, if PF-ice mode off if (.not.pf_frzmode) then - call get_clm_iceadj_porosity(clm_bgc_data, & - bounds, num_soilc, filter_soilc) + call get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) + 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) + endif - ! pass flux 'vecs' from CLM to pflotran - call pflotranModelUpdateHSourceSink(pflotran_m) ! H SrcSink - call pflotranModelSetSoilHbcsFromCLM(pflotran_m) ! H BC + ! (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) CLM thermal BC to PFLOTRAN - if (pf_tmode) then - call get_clm_bceflx(clm_bgc_data, & - bounds, num_soilc, filter_soilc) + ! (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) - call pflotranModelUpdateSubsurfTCond(pflotran_m) ! SrcSink and T bc + ! 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) 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) + ! (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 balance issue - call pflotranModelGetSaturationFromPF(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 -! 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) + + ! 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) + 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) - + ! (4b) bgc rate (fluxes) from CLM to PFLOTRAN + call get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) 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 + endif -write(*,*)">>>DEBUG | pflotranModelStepperRunTillPauseTime: BEG...PFLOTRAN" ! (5) the main callings of PFLOTRAN - call pflotranModelStepperRunTillPauseTime( pflotran_m, (nstep+1.0d0)*dtime, dtime, .false. ) + call mpi_barrier(mpicom, ierr) -write(*,*)">>>DEBUG | pflotranModelStepperRunTillPauseTime: END...CONTINUE..." + 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 -#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 + 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 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) - 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) + call pflotranModelGetTemperatureFromPF( pflotran_m ) ! thermal states + call update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, ifilter) endif - ! bgc variables if (pf_cmode) then - call pflotranModelGetBgcVariablesFromPF(pflotran_m) + call pflotranModelGetBgcVariablesFromPF( pflotran_m) ! bgc variables + + call update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) - call update_soil_bgc_pf2clm(clm_bgc_data, & - bounds, num_soilc, filter_soilc) + 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 - ! 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 + endif end subroutine pflotran_run_onestep @@ -963,6 +1292,7 @@ subroutine pflotran_finalize() ! finalizing pflotran runs and destroying objects ! ! !USES: + use clm_varctl , only : use_pflotran implicit none @@ -972,10 +1302,359 @@ subroutine pflotran_finalize() call pflotranModelDestroy(pflotran_m) endif + deallocate(mapped_gcount_skip) + end subroutine pflotran_finalize - ! ============================= GET CLM initial/src-sink/BC to PFLOTRAN ================================== + !==================================================================================================== + ! ! + ! 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 + use LandunitType , only : lun + use ColumnType , only : col + + 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%itype , & ! [integer (:)] landunit type index + ! Assign local pointer to derived subtypes components (column-level) + clandunit => col%landunit , & ! [integer (:)] landunit index of column + cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column + cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell) + cactive => col%active , & ! [logic (:)] column active or not + ! + z => col%z , & ! [real(r8) (:,:)] layer depth (m) (sort of centroid from surface 0 ) + zi => col%zi , & ! [real(r8) (:,:)] layer interface depth (m) + dz => col%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 !!wgs: 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 !!wgs: 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 !!wgs: 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%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 @@ -983,13 +1662,18 @@ end subroutine pflotran_finalize ! !IROUTINE: get_clm_soil_properties ! ! !INTERFACE: - subroutine get_clm_soil_properties(clm_bgc_data, & - bounds, num_soilc, filter_soilc) + subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) ! ! !DESCRIPTION: ! get soil column physical properties to PFLOTRAN ! ! !USES: + use LandunitType , only : lun + use ColumnType , only : col + use landunit_varcon , only : istsoil, istcrop + + use clm_varpar , only : nlevgrnd, ndecomp_pools, ndecomp_cascade_transitions + use CNDecompCascadeConType , only : decomp_cascade_con ! pflotran ! @@ -997,10 +1681,10 @@ subroutine get_clm_soil_properties(clm_bgc_data, & implicit none -#include "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" -#include "finclude/petscviewer.h" +#include "petsc/finclude/petscsys.h" +#include "petsc/finclude/petscvec.h" +#include "petsc/finclude/petscvec.h90" +#include "petsc/finclude/petscviewer.h" ! ! !REVISION HISTORY: @@ -1011,14 +1695,19 @@ subroutine get_clm_soil_properties(clm_bgc_data, & ! ! 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 + type(bounds_type), intent(in) :: bounds ! bounds + type(clumpfilter), intent(in) :: filters(:) ! filters on current process - integer :: fc, g, l, c, j ! indices - integer :: gcount, cellcount + 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 @@ -1031,130 +1720,260 @@ subroutine get_clm_soil_properties(clm_bgc_data, & 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(:) + + 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) - 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) + ltype => lun%itype , & ! [integer (:)] landunit type index + ! Assign local pointer to derived subtypes components (column-level) + clandunit => col%landunit , & ! [integer (:)] landunit index of column + cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column + cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell + cactive => col%active , & ! + z => col%z , & ! [real(r8) (:,:)] layer depth (m) + dz => col%dz , & ! [real(r8) (:,:)] layer thickness depth (m) + zi => col%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) ! - 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) + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 - + 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) - gcount = g - bounds%begg - do j = 1,nlevsoi - cellcount = gcount*clm_pf_idata%nzclm_mapped + j + if ( (ltype(l)==istsoil .or. ltype(l)==istcrop) .and. & + (col%active(c) .and. cwtgcell(c)>0._r8) ) then ! skip inactive or zero-weighted column (may be not needed, but in case) - 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 +#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 - else - ! may need to further checking here - 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 - enddo + else + call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // & + " 'clm_varpar%nlevgrnd'. Please check") - enddo ! do c = 1, numsoilc + endif + enddo + endif -!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)) + enddo ! do c = bounds%begc, bounds%endc call VecRestoreArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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) + 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_bgc_data,pftmode, pfhmode, & - bounds, num_soilc, filter_soilc) + subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, filters, ifilter) ! ! !DESCRIPTION: @@ -1162,145 +1981,194 @@ subroutine get_clm_soil_th(clm_bgc_data,pftmode, pfhmode, & ! if either NOT available inside PFLOTRAN ! ! !USES: - use clm_time_manager , only : get_nstep + 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 + 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 "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 +#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, j, gcount, cellcount ! indices - real(r8) :: sattmp, psitmp, itheta - real(r8) :: watmin(num_soilc, nlevsoi) - real(r8) :: sucmin(num_soilc, nlevsoi) + 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 :: soilt_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 ( & - 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) + cgridcell => col%gridcell , & ! column's gridcell + dz => col%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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr) - CHKERRQ(ierr) - - watmin(:,:) = 0.01_r8 - sucmin(:,:) = 1.e8_r8 + 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) - 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 +#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 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 + do j = 1, clm_pf_idata%nzclm_mapped - g = gridcell(c) - gcount = g - bounds%begg - do j = 1, nlevsoi - cellcount = gcount*clm_pf_idata%nzclm_mapped + j + if (j<=nlevgrnd) then + cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based - 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 + 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)/(dz(c,j)*denh2o)) - soilisat_clmp_loc(cellcount) = soilisat_clmp_loc(cellcount) + itheta/watsat(c,j)*wtgcell(c) - endif + itheta = min(itheta, watsat(c,j)-watmin(c,j)) + soilisat_clmp_loc(cellcount) = itheta/watsat(c,j) - 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) + 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) - endif + ! 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 - if (.not.pftmode) then - soilt_clmp_loc(cellcount) = soilt_clmp_loc(cellcount) + (t_soisno(c,j)-tfrz)*wtgcell(c) + 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 - endif + else + call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // & + " 'clm_varpar%nlevgrnd'. Please check") - enddo - enddo + endif !!if (j<=nlevgrnd) then -!----------------------------------------------------------------------------- -!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) -!----------------------------------------------------------------------------- + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr) - CHKERRQ(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 @@ -1312,13 +2180,16 @@ end subroutine get_clm_soil_th ! !ROUTINE: get_clm_iceadj_porosity ! ! !INTERFACE: - subroutine get_clm_iceadj_porosity(clm_bgc_data, & - bounds, num_soilc, filter_soilc) + 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 + 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 @@ -1326,16 +2197,15 @@ subroutine get_clm_iceadj_porosity(clm_bgc_data, & ! !ARGUMENTS: implicit none -#include "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#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(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 + type(clm_interface_data_type), intent(in) :: clm_interface_data ! !LOCAL VARIABLES: integer :: fc, c, g, j, gcount, cellcount ! indices @@ -1345,15 +2215,16 @@ subroutine get_clm_iceadj_porosity(clm_bgc_data, & PetscScalar, pointer :: soilisat_clmp_loc(:) ! PetscErrorCode :: ierr + character(len= 32) :: subname = 'get_clm_iceadj_porosity' ! subroutine name + !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) + cgridcell => col%gridcell , & ! column's gridcell + dz => col%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' @@ -1363,50 +2234,59 @@ subroutine get_clm_iceadj_porosity(clm_bgc_data, & ! 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - 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 + ! 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 - g = gridcell(c) - gcount = g - bounds%begg - do j = 1, nlevsoi - cellcount = gcount*clm_pf_idata%nzclm_mapped + j + do j = 1, clm_pf_idata%nzclm_mapped + if (j<=nlevgrnd) then + cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based - 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) + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(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_bgc_data, & - bounds, num_soilc, filter_soilc) + subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) ! ! !DESCRIPTION: ! @@ -1416,43 +2296,36 @@ subroutine get_clm_bcwflx(clm_bgc_data, & ! 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 ColumnType , only : col + 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 "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#include "petsc/finclude/petscsys.h" +#include "petsc/finclude/petscvec.h" +#include "petsc/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(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(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 + type(clm_interface_data_type), intent(inout) :: clm_interface_data ! !LOCAL VARIABLES: - integer :: fc, g, c, j, p ! do loop indices - integer :: gcount ! gridcell index (0-based) - integer :: pftindex ! pft index + 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 - 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_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 @@ -1460,135 +2333,62 @@ subroutine get_clm_bcwflx(clm_bgc_data, & 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 + 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 :: zsoi_clmp_loc(:) ! - PetscScalar, pointer :: qflx_clmp_loc(:) ! source/sink term for plant Transpiration: unit in mass rate (kgH2O/sec) + 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 :: qflux_top_clmp_loc(:) ! BC in neumann flux type: unit in m/s - PetscScalar, pointer :: qflux_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 ( & - 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 + cgridcell => col%gridcell , & ! column's gridcell + cwtgcell => col%wtgcell , & ! weight (relative to gridcell) + dz => col%dz , & ! layer thickness depth (m) ! - 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] + 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 => 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 & - + 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) 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 + ! (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) @@ -1596,81 +2396,183 @@ subroutine get_clm_bcwflx(clm_bgc_data, & ! 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soillsat_clms, soillsat_clms_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%sr_pcwmax_clms, sr_pcwmax_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - call VecGetArrayF90(clm_pf_idata%qflux_clmp, qflx_clmp_loc, ierr) - CHKERRQ(ierr) + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 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) - CHKERRQ(ierr) - - ! Initialize flux variables and bcs - do fc = 1, num_soilc + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - c = filter_soilc(fc) + ! operating via 'filters' + gcount = -1 + do fc = 1,filters(ifilter)%num_soilc + c = filters(ifilter)%soilc(fc) g = cgridcell(c) - gcount = g - bounds%begg - do j = 1, nlevsoi - cellcount = gcount*clm_pf_idata%nzclm_mapped + j +#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) + - if(j<=clm_pf_idata%nzclm_mapped) then - qflx_clmp_loc(cellcount) = 0.0_r8 + 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 - press_base_clmp_loc(gcount+1) = press_clms_loc(cellcount) ! same as the bottom layer + 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 - endif + 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._r8 ! this is temporarily set (not yet figure out how CLM get this value) - do fc = 1, num_soilc + 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 - 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) + press_maxponding_clmp_loc(gcount+1) = reference_pressure+ponding_pressure + + do j = 1, clm_pf_idata%nzclm_mapped + + if (j<=nlevgrnd) then - do j = 1, nlevsoi - cellcount = gcount*clm_pf_idata%nzclm_mapped + j + 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 + ! 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 - qflx_ground = qflx_top_soil(c) - qflx_evap_col(c) ! unit: mm/sec + ! 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) @@ -1679,114 +2581,95 @@ subroutine get_clm_bcwflx(clm_bgc_data, & ! 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 + 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) = press_top_clmp_loc(gcount+1) + & - qflx_ground*col_pp%wtgcell(c)*dtime*SHR_CONST_G + press_top_clmp_loc(gcount+1) = reference_pressure + & + qflx_ground*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 + end if - ! 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???) + ! 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) - 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 + 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 - qflx_clmp_loc(cellcount)) & + 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 - qflux_base_clmp_loc(gcount+1) = qflux_base_clmp_loc(gcount+1) & - + max(dsoilliq3, -kbot * col_pp%wtgcell(c)) ! mH2O/sec + qfluxw_base_clmp_loc(gcount+1) = max(dsoilliq3, -kbot) ! mH2O/sec end if - endif !if(j<=clm_pf_idata%nzclm_mapped) + 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 ! do j=1,nlevsoi + end do - end do ! do c=1, num_soilc + end do call VecRestoreArrayF90(clm_pf_idata%press_clms, press_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soillsat_clms, soillsat_clms_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%effporosity_clms, porosity_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - call VecRestoreArrayF90(clm_pf_idata%qflux_clmp, qflx_clmp_loc, ierr) - CHKERRQ(ierr) + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 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) - CHKERRQ(ierr) - -!---------------------------------------------------------------------------------------------------------- + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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) + subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) ! ! !DESCRIPTION: ! @@ -1797,183 +2680,235 @@ subroutine get_clm_bceflx(clm_bgc_data, & ! at both ground and bottom interface (BC). ! ! !USES: + use ColumnType , only : col + 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 "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#include "petsc/finclude/petscsys.h" +#include "petsc/finclude/petscvec.h" +#include "petsc/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(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(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 + type(clm_interface_data_type), intent(in) :: clm_interface_data ! !LOCAL VARIABLES: - integer :: fc, c, g, p, gcount ! do loop indices - integer :: pftindex + 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 :: gflux_subsurf_clmp_loc(:) ! BC in neumman type: unit W/m2 + 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 :: gflux_subbase_clmp_loc(:) ! BC in neumman type: unit W/m2 + 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 - 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 + cgridcell => col%gridcell , &! column's gridcell + dz => col%dz , &! layer thickness depth (m) + snl => col%snl , &! number of snow layers (negative) ! - 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) + 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) ! - 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] + 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%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%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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%gtemp_subbase_clmp, gtemp_subbase_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - gflux_subsurf_clmp_loc(:) = 0._r8 - gflux_subbase_clmp_loc(:) = 0._r8 - gtemp_subsurf_clmp_loc(:) = 0._r8 - gtemp_subbase_clmp_loc(:) = 0._r8 + call VecGetArrayF90(clm_pf_idata%area_top_face_clms, area_clms_loc, ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - ! 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 + 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) - 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 +#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 - g = cgridcell(c) - gcount = g - bounds%begg + 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 - 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) + 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 - gtemp_subbase_clmp_loc(gcount+1) = 0._r8 ! not yet get it from CLM (i.e.,dirichlet type not available) + 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%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%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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%gtemp_subbase_clmp, gtemp_subbase_clmp_loc, ierr) - CHKERRQ(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(bounds) + ! !ROUTINE: get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) ! ! !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 + subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) + use ColumnType , only : col + use clm_varctl , only : iulog + use clm_varpar , only : ndecomp_pools, nlevdecomp_full 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(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(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 + type(clm_interface_data_type), intent(in) :: clm_interface_data character(len=256) :: subname = "get_clm_bgc_concentration" -#include "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#include "petsc/finclude/petscsys.h" +#include "petsc/finclude/petscvec.h" +#include "petsc/finclude/petscvec.h90" ! Local variables - integer :: g, fc, c, j, k + integer :: fc, c, g, j, k ! do loop indices integer :: gcount, cellcount - real(r8) :: wtgcell, realc_gcell, realn_gcell + real(r8) :: CN_ratio_mass_to_mol -#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 :: 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 @@ -1984,253 +2919,113 @@ subroutine get_clm_bgc_conc(clm_bgc_data, & !------------------------------------------------------------------------------------------ ! 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 + cgridcell => col%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 ) -#ifdef FLEXIBLE_POOLS call VecGetArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) -#ifdef FLEXIBLE_POOLS + 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 -#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 + ! operating via 'filters' + gcount = -1 + do fc = 1,filters(ifilter)%num_soilc + c = filters(ifilter)%soilc(fc) + g = cgridcell(c) - g = col_pp%gridcell(c) - wtgcell = col_pp%wtgcell(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 - 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' + do j = 1, clm_pf_idata%nzclm_mapped + cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based - 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, T is within 'nlevgrnd', H is within 'nlevsoi', bgc within 'nlevdecomp' - if(j <= clm_pf_idata%nzclm_mapped) then + if(j <= nlevdecomp_full) 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) + 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. -#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) + decomp_cpools_vr_clm_loc(vec_offset+cellcount) = decomp_cpools_vr(c,j,k) & + /clm_pf_idata%C_molecular_weight - 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 + 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 - 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) + 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, nlevdecomp + enddo ! do j = 1, clm_pf_idata%nzclm_mapped - enddo ! do c = begc, endc + enddo ! do fc = 1, num_soilc -#ifdef FLEXIBLE_POOLS call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) end associate end subroutine get_clm_bgc_conc @@ -2240,79 +3035,50 @@ 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) + subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) !! 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 + use ColumnType , only : col + 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 - 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(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(cnstate_type) , intent(in) :: cnstate_vars -! type(carbonflux_type) , intent(in) :: carbonflux_vars -! type(nitrogenflux_type) , intent(in) :: nitrogenflux_vars + type(clm_interface_data_type), intent(in) :: clm_interface_data character(len=256) :: subname = "get_clm_bgc_rate" -#include "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#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) :: 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_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(:) ! + PetscScalar, pointer :: rate_smin_no3_clm_loc(:) ! + PetscScalar, pointer :: rate_smin_nh4_clm_loc(:) ! PetscErrorCode :: ierr @@ -2320,476 +3086,563 @@ subroutine get_clm_bgc_rate(clm_bgc_data, & !--------------------------------------------------------------------------- ! associate ( & + cgridcell => col%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_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 , & + 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_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 & + 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() -#ifdef FLEXIBLE_POOLS + call VecGetArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! 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 + ! operating via 'filters' + gcount = -1 + do fc = 1,filters(ifilter)%num_soilc + c = filters(ifilter)%soilc(fc) + g = cgridcell(c) - g = col_pp%gridcell(c) - gcount = g - bounds%begg - wtgcell = col_pp%wtgcell(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 - cellcount = gcount*clm_pf_idata%nzclm_mapped+j + 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, TH is within clm_pf_idata%nzclm_mapped, bgc within 'nlevdecomp' - if(j <= clm_pf_idata%nzclm_mapped) then + ! 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 - ! 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 + 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 -#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 + ! 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 - 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 + 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 - 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr) - CHKERRQ(ierr) -#else + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) -!----------------------------------------------------------------------------- -!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%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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) end associate end subroutine get_clm_bgc_rate - ! =============================UPDATE PFLOTRAN evolving variables to CLM ========================================== - - !----------------------------------------------------------------------------- - !BOP + !==================================================================================================== + ! ! + ! Subroutines to UPDATE PFLOTRAN evolving variables to CLM ! + ! ! + !==================================================================================================== ! ! !IROUTINE: update_soil_moisture_pf2clm ! ! !INTERFACE: - subroutine update_soil_moisture_pf2clm(clm_bgc_data, & - bounds, num_soilc, filter_soilc) - + subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifilter) ! ! !DESCRIPTION: ! ! ! !USES: + use ColumnType , only : col + use clm_varcon , only : denh2o, denice + use clm_varctl , only : pf_frzmode + use clm_varpar , only : nlevgrnd ! !ARGUMENTS: implicit none -#include "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#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(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 + type(clm_interface_data_type), intent(in) :: clm_interface_data ! !LOCAL VARIABLES: - integer :: fc, c, j, g, gcount ! indices + integer :: fc, c, j, g ! indices + integer :: cellcount, gcount PetscScalar, pointer :: sat_ice_clm_loc(:) PetscScalar, pointer :: sat_clm_loc(:) - PetscScalar, pointer :: watsat_clm_loc(:) + PetscScalar, pointer :: effporo_clm_loc(:) + PetscScalar, pointer :: soilpsi_clm_loc(:) PetscErrorCode :: ierr + character(len=256) :: subname = "update_soil_moisture_pf2clm" + !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 & - ) + cgridcell => col%gridcell , & ! column's gridcell + dz => col%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 - 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) + ! operating via 'filters' + gcount = -1 + do fc = 1,filters(ifilter)%num_soilc + c = filters(ifilter)%soilc(fc) + g = cgridcell(c) - 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 +#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 - g = col_pp%gridcell(c) - gcount = g - bounds%begg - do j = 1, nlevsoi + do j = 1, nlevgrnd 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 + 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 - h2osoi_ice_col(c,j) = sat_ice_clm_loc(gcount*nlevsoi + j) * & - watsat_clm_loc(gcount*nlevsoi + j) * dz(c,j) * denice + ! 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_col(c,j) = h2osoi_liq_col(c,clm_pf_idata%nzclm_mapped) + 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_ice_col(c,j) = h2osoi_ice_col(c,clm_pf_idata%nzclm_mapped) + 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_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)) + 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 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) + 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 !----------------------------------------------------------------------------- - !BOP ! ! !IROUTINE: update_soil_temperature_pf2clm ! ! !INTERFACE: - subroutine update_soil_temperature_pf2clm(clm_bgc_data, & - bounds, num_soilc, filter_soilc) - + subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, ifilter) ! ! !DESCRIPTION: ! ! ! !USES: + use ColumnType , only : col + use clm_varpar , only : nlevgrnd + use clm_varcon , only : tfrz ! !ARGUMENTS: implicit none -#include "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" + 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 - 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 + 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, gcount ! indices + 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 ( & - 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) - ) + cgridcell => col%gridcell , & ! column's gridcell + z => col%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) - CHKERRQ(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) - 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 +#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 - g = col_pp%gridcell(c) - gcount = g - bounds%begg - do j = 1, nlevsoi + do j = 1, nlevgrnd if (j<=clm_pf_idata%nzclm_mapped) then - t_soisno(c,j) = soilt_clms_loc(gcount*clm_pf_idata%nzclm_mapped+j) + tfrz + 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 + 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%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 - else - t_soisno(c,j) = t_soisno(c, clm_pf_idata%nzclm_mapped) + qflx_surf(c) = qflx_top_soil(c) - qflx_infl(c) - qflx_evap + qflx_surf(c) = max(0._r8, qflx_surf(c)) - end if + !'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) - enddo + end do - enddo - call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr) - CHKERRQ(ierr) + 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_soil_temperature_pf2clm + end subroutine update_bcflow_pf2clm + ! !----------------------------------------------------------------------------- ! + ! + !----------------------------------------------------------------------------- ! !ROUTINE: update_soil_bgc_pf2clm() ! ! !INTERFACE: @@ -2798,63 +3651,39 @@ end subroutine update_soil_temperature_pf2clm ! 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) + subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) !! 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 + use ColumnType , only : col + 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 - 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 + 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 "finclude/petscsys.h" -#include "finclude/petscvec.h" -#include "finclude/petscvec.h90" +#include "petsc/finclude/petscsys.h" +#include "petsc/finclude/petscvec.h" +#include "petsc/finclude/petscvec.h90" - integer :: fc,c,g,j,k + integer :: fc,c,g,j,k,l 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 @@ -2876,22 +3705,25 @@ subroutine update_soil_bgc_pf2clm(clm_bgc_data, & !------------------------------------------------------------------------------------ ! 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 & + cgridcell => col%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() @@ -2901,158 +3733,135 @@ subroutine update_soil_bgc_pf2clm(clm_bgc_data, & 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + call VecGetArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) 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 + 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 - 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 + cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based + 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 + 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. - 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 + 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 ) !!/dtime !!wgs: 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) + 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 -#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 + 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 - 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 + ! + 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 - 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 -#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_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 + 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 - ! directly update the 'smin' N pools (SO, must bypass the 'CNNStateUpdate1,2,3' relevant to soil N) +!! wgs-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 @@ -3063,34 +3872,22 @@ subroutine update_soil_bgc_pf2clm(clm_bgc_data, & 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) +!! wgs-end:-------------------------------------------------------------------------------- - ! 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 + !! 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) - 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) + 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 @@ -3239,87 +4024,106 @@ subroutine update_bgc_gaslosses_pf2clm(clm_bgc_data, & 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 & + associate ( & + cgridcell => col%gridcell , & ! gridcell index of column + dz => col%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 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 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) - 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) + + 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 VecGetArrayF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr) - CHKERRQ(ierr) ! PF evolved 'soilt' + call VecGetArrayReadF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! 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 + 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 VecGetArrayF90(clm_pf_idata%soilisat_clms, soilisat_clm_loc, ierr) - CHKERRQ(ierr) ! PF evolved 'soil ice saturation' + 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 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' + 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 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' + 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 VecGetArrayF90(clm_pf_idata%effporosity_clms, soilpor_clm_loc, ierr) ! PF evolved 'soil porosity' - CHKERRQ(ierr) + 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) - 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 + ! 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(c)+ frac_h2osfc(c))>=0.90_r8) then + if((frac_sno_eff(c)+ frac_h2osfc(c))>=0.95_r8) then lair_barrier(c) = 0 endif @@ -3340,21 +4144,17 @@ subroutine update_bgc_gaslosses_pf2clm(clm_bgc_data, & 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 + ! 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 - cellcount = gcount*clm_pf_idata%nzclm_mapped+j + 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 @@ -3433,7 +4233,7 @@ subroutine update_bgc_gaslosses_pf2clm(clm_bgc_data, & 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 VecRestoreArrayF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr) - CHKERRQ(ierr) - call VecRestoreArrayF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr) - CHKERRQ(ierr) - call VecRestoreArrayF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr) - CHKERRQ(ierr) - call VecRestoreArrayF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr) - CHKERRQ(ierr) + 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 VecRestoreArrayF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr) - CHKERRQ(ierr) + call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else - call VecRestoreArrayF90(clm_pf_idata%soilt_clmp, soilt_clm_loc, ierr) - CHKERRQ(ierr) ! for CLM, MPI vecs and Seq. vecs should be same + 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 VecRestoreArrayF90(clm_pf_idata%soilisat_clms, soilisat_clm_loc, ierr) - CHKERRQ(ierr) + 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 VecRestoreArrayF90(clm_pf_idata%soillsat_clms, soillsat_clm_loc, ierr) - CHKERRQ(ierr) ! PF evolved 'soil liq. saturation' - call VecRestoreArrayF90(clm_pf_idata%press_clms, soilpress_clm_loc, ierr) - CHKERRQ(ierr) ! PF evolved 'soil liq. saturation' + 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 VecRestoreArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clm_loc, ierr) - CHKERRQ(ierr)! CLM evolved 'soilt liq. saturation' - call VecRestoreArrayF90(clm_pf_idata%press_clmp, soilpress_clm_loc, ierr) - CHKERRQ(ierr)! CLM evolved 'soilt liq. saturation' + 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 VecRestoreArrayF90(clm_pf_idata%effporosity_clms, soilpor_clm_loc, ierr) - CHKERRQ(ierr) + 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) @@ -3502,156 +4308,595 @@ subroutine update_bgc_gaslosses_pf2clm(clm_bgc_data, & 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 + 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%gridcell , & ! gridcell index of column + dz => col%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 - ! comment out this subroutine currently for bgc-only - ! !IROUTINE: update_bcflow_pf2clm + ! + ! !SUBROUTINE: clm_pf_checkerr(ierr) ! ! !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 + 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 -!---------------------------------------------------------------------------------------------- -! END of CLM-PFLOTRAN bgc coupling interface -!---------------------------------------------------------------------------------------------- +! +! Private interface subroutines, requiring explicit coupling between CLM and PFLOTRAN +! (END) +!************************************************************************************! -end module clm_pflotran_interfaceMod +end module clm_interface_pflotranMod \ No newline at end of file diff --git a/components/clm/src/main/clm_varctl.F90 b/components/clm/src/main/clm_varctl.F90 index 1aa34e2f3521..414901dd3326 100644 --- a/components/clm/src/main/clm_varctl.F90 +++ b/components/clm/src/main/clm_varctl.F90 @@ -342,11 +342,12 @@ module clm_varctl 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 2be60e52f201..f25503650537 100644 --- a/components/clm/src/main/controlMod.F90 +++ b/components/clm/src/main/controlMod.F90 @@ -129,7 +129,7 @@ subroutine control_init( ) ! Time step namelist / clm_inparm/ & - dtime + dtime ! CLM namelist settings diff --git a/components/clm/src/main/surfrdMod.F90 b/components/clm/src/main/surfrdMod.F90 index 9da0541be9ed..b2ccb1660791 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 ! @@ -160,10 +160,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 +185,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 +221,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 +248,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 +285,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 +617,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..78c380d75bcb 100644 --- a/components/clm/src/utils/clm_time_manager.F90 +++ b/components/clm/src/utils/clm_time_manager.F90 @@ -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 diff --git a/components/clm/src/utils/domainMod.F90 b/components/clm/src/utils/domainMod.F90 index 2d752adcc1b4..c259713ebf06 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 ' From 4303af382142971fcddcda187ab0b1aaae7417b5 Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Tue, 6 Jun 2017 14:52:13 -0400 Subject: [PATCH 02/35] Migrating NGEE-Arctic CLM-PFLOTRAN codes - STEP 3: clean codes (now ONLY BGC coupling). --- components/clm/src/main/clm_pflotran_interfaceMod.F90 | 5 +++++ components/clm/src/main/surfrdMod.F90 | 1 + 2 files changed, 6 insertions(+) diff --git a/components/clm/src/main/clm_pflotran_interfaceMod.F90 b/components/clm/src/main/clm_pflotran_interfaceMod.F90 index 6891c036d0b6..31b307ef7416 100644 --- a/components/clm/src/main/clm_pflotran_interfaceMod.F90 +++ b/components/clm/src/main/clm_pflotran_interfaceMod.F90 @@ -117,6 +117,7 @@ module clm_interface_pflotranMod private :: clm_pf_CBalanceCheck private :: clm_pf_NBalanceCheck ! + private :: get_clm_bcwflx private :: get_clm_bceflx private :: update_soil_temperature_pf2clm @@ -1166,12 +1167,15 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (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 @@ -1221,6 +1225,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (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) diff --git a/components/clm/src/main/surfrdMod.F90 b/components/clm/src/main/surfrdMod.F90 index b2ccb1660791..a90eb842274c 100644 --- a/components/clm/src/main/surfrdMod.F90 +++ b/components/clm/src/main/surfrdMod.F90 @@ -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 From f20cdb38a8bf0ceb817e179e856cadf5acc56fb7 Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Tue, 6 Jun 2017 17:00:37 -0400 Subject: [PATCH 03/35] Migrating NGEE-Arctic CLM-PFLOTRAN codes - STEP 4: manually merge recent edits in regarding to soil column indexing and filtering in clm-pflotran-interface subroutines. These edits are for column-mode and tested for at global-scale. --- components/clm/src/main/clm_initializeMod.F90 | 2 +- .../src/main/clm_pflotran_interfaceMod.F90 | 104 +++++++++--------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/components/clm/src/main/clm_initializeMod.F90 b/components/clm/src/main/clm_initializeMod.F90 index 219e6be27769..8524a45f3f9a 100644 --- a/components/clm/src/main/clm_initializeMod.F90 +++ b/components/clm/src/main/clm_initializeMod.F90 @@ -897,7 +897,7 @@ subroutine initialize2( ) call clm_bgc_data%Init(bounds_proc) ! PFLOTRAN initialization if (use_pflotran) then - call clm_pf_interface_init(bounds_proc, filter) + call clm_pf_interface_init(bounds_proc) end if end if call t_stopf('init_clm_bgc_interface_data & pflotran') diff --git a/components/clm/src/main/clm_pflotran_interfaceMod.F90 b/components/clm/src/main/clm_pflotran_interfaceMod.F90 index 31b307ef7416..ab1f5788c009 100644 --- a/components/clm/src/main/clm_pflotran_interfaceMod.F90 +++ b/components/clm/src/main/clm_pflotran_interfaceMod.F90 @@ -3,7 +3,7 @@ module clm_interface_pflotranMod !#define CLM_PFLOTRAN ! the above #directive IS for explicit coupling CLM and PFLOTRAN (i.e. this interface) -!#define COLUMN_MODE +#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; @@ -374,8 +374,8 @@ subroutine interface_init(bounds) ! !USES: use clm_varctl , only : iulog use GridcellType , only : grc - use LandunitType , only : lun - use ColumnType , only : col + 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 @@ -447,13 +447,13 @@ subroutine interface_init(bounds) associate( & ! Assign local pointers to derived subtypes components (landunit-level) - ltype => lun%itype , & ! [integer (:)] landunit type index - lgridcell => lun%gridcell , & ! [integer (:)] gridcell index of landunit + 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%gridcell , & ! [integer (:)] gridcell index of column - clandunit => col%landunit , & ! [integer (:)] landunit index of column - cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell) - cactive => col%active & ! [logic (:)] column active or not + 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 ) @@ -1329,8 +1329,8 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! ! !USES: use GridcellType , only : grc - use LandunitType , only : lun - use ColumnType , only : col + use LandunitType , only : lun_pp + use ColumnType , only : col_pp use clm_varpar , only : nlevgrnd use domainMod , only : ldomain @@ -1405,14 +1405,14 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! landunit ltype => lun%itype , & ! [integer (:)] landunit type index ! Assign local pointer to derived subtypes components (column-level) - clandunit => col%landunit , & ! [integer (:)] landunit index of column - cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column - cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell) - cactive => col%active , & ! [logic (:)] column active or not + 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%z , & ! [real(r8) (:,:)] layer depth (m) (sort of centroid from surface 0 ) - zi => col%zi , & ! [real(r8) (:,:)] layer interface depth (m) - dz => col%dz & ! [real(r8) (:,:)] layer thickness (m) + 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) ) @@ -1673,8 +1673,8 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) ! get soil column physical properties to PFLOTRAN ! ! !USES: - use LandunitType , only : lun - use ColumnType , only : col + 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 @@ -1735,15 +1735,15 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) associate( & ! Assign local pointer to derived subtypes components (column-level) - ltype => lun%itype , & ! [integer (:)] landunit type index + ltype => lun_pp%itype , & ! [integer (:)] landunit type index ! Assign local pointer to derived subtypes components (column-level) - clandunit => col%landunit , & ! [integer (:)] landunit index of column - cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column - cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell - cactive => col%active , & ! - z => col%z , & ! [real(r8) (:,:)] layer depth (m) - dz => col%dz , & ! [real(r8) (:,:)] layer thickness depth (m) - zi => col%zi , & ! [real(r8) (:,:)] interface level below a "z" level (m) + 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) @@ -1839,7 +1839,7 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) 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) @@ -1988,7 +1988,7 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, ! !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 + use ColumnType , only : col_pp use clm_varctl , only : iulog use clm_varcon , only : denh2o, denice, tfrz use clm_varpar , only : nlevgrnd @@ -2031,8 +2031,8 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, !EOP !----------------------------------------------------------------------- associate ( & - cgridcell => col%gridcell , & ! column's gridcell - dz => col%dz , & ! layer thickness depth (m) + 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" @@ -2191,7 +2191,7 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) ! update soil effective porosity from CLM to PFLOTRAN if PF freezing mode is off ! ! !USES: - use ColumnType , only : col + use ColumnType , only : col_pp use clm_varctl , only : iulog use clm_varcon , only : denice use clm_varpar , only : nlevgrnd @@ -2225,8 +2225,8 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) !EOP !----------------------------------------------------------------------- associate ( & - cgridcell => col%gridcell , & ! column's gridcell - dz => col%dz , & ! layer thickness depth (m) + 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) @@ -2301,7 +2301,7 @@ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) ! that and others in 'Hydrology2Mod.F90' so that pflotran can be called out of 'hydrology2'. ! ! !USES: - use ColumnType , only : col + 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 @@ -2364,9 +2364,9 @@ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) !EOP !----------------------------------------------------------------------- associate ( & - cgridcell => col%gridcell , & ! column's gridcell - cwtgcell => col%wtgcell , & ! weight (relative to gridcell) - dz => col%dz , & ! layer thickness depth (m) + 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) @@ -3047,7 +3047,7 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) ! ! ! !USES: - use ColumnType , only : col + 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 @@ -3091,7 +3091,7 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) !--------------------------------------------------------------------------- ! associate ( & - cgridcell => col%gridcell , & ! column's gridcell + 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 @@ -3146,6 +3146,7 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) ! operating via 'filters' gcount = -1 do fc = 1,filters(ifilter)%num_soilc + c = filters(ifilter)%soilc(fc) g = cgridcell(c) @@ -3623,6 +3624,7 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) 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) & @@ -3643,9 +3645,6 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) end associate end subroutine update_bcflow_pf2clm - ! - !----------------------------------------------------------------------------- - ! ! !----------------------------------------------------------------------------- ! !ROUTINE: update_soil_bgc_pf2clm() @@ -3658,7 +3657,7 @@ end subroutine update_bcflow_pf2clm ! subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) !! TODO: add phosphorus vars - use ColumnType , only : col + 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 @@ -3710,7 +3709,7 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) !------------------------------------------------------------------------------------ ! associate ( & - cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column + 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 , & @@ -3967,7 +3966,7 @@ end subroutine update_soil_bgc_pf2clm ! subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifilter) - use ColumnType , only : col + 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 @@ -4030,8 +4029,8 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil !------------------------------------------------------------------------------------ associate ( & - cgridcell => col%gridcell , & ! gridcell index of column - dz => col%dz , & ! soil layer thickness depth (m) + 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) @@ -4326,7 +4325,7 @@ end subroutine update_bgc_gaslosses_pf2clm ! subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter) - use ColumnType , only : col + use ColumnType , only : col_pp use clm_time_manager , only : get_step_size use clm_varpar , only : nlevdecomp_full @@ -4361,8 +4360,8 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter !------------------------------------------------------------------------------------ associate ( & - cgridcell => col%gridcell , & ! gridcell index of column - dz => col%dz , & ! soil layer thickness depth (m) + 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) @@ -4472,6 +4471,7 @@ subroutine clm_pf_checkerr(ierr, subname, filename, line) end subroutine clm_pf_checkerr + !!-------------------------------------------------------------------------------------- subroutine clm_pf_BeginCBalance(clm_interface_data, bounds, filters, ifilter) ! From bcc4e9709dd9c403c39be4115bad0e371beb42f8 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 13 Jun 2017 21:51:38 -0400 Subject: [PATCH 04/35] fix a P cycle nc variable writing error, when coupling with PFLOTRAN. It's because the coupling not yet includes P bgc. --- .../clm/src/biogeochem/CNBalanceCheckMod.F90 | 56 ++++++++++--------- components/clm/src/biogeochem/CNDecompMod.F90 | 31 ++++++++-- .../clm/src/biogeochem/CNEcosystemDynMod.F90 | 8 +-- .../clm/src/biogeochem/PhosphorusFluxType.F90 | 1 + components/clm/src/main/clm_driver.F90 | 15 ++--- 5 files changed, 70 insertions(+), 41 deletions(-) diff --git a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 index e0379cf8b223..65a8f77145ac 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) ) @@ -441,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 + 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 & + 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 @@ -488,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 @@ -513,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/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90 index 97aeda08d843..ed0ef51b8246 100644 --- a/components/clm/src/biogeochem/CNDecompMod.F90 +++ b/components/clm/src/biogeochem/CNDecompMod.F90 @@ -812,10 +812,13 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so end do end if - ! needs to zero CLM-CN variables NOT available from pflotran bgc coupling + ! needs to zero CLM-CNP 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) + num_soilp, filter_soilp, & + carbonflux_vars, nitrogenflux_vars, & + phosphorusstate_vars, phosphorusflux_vars) + + end if !!if(use_clm_interface.and.use_pflotran.and.pf_cmode) !!------------------------------------------------------------------ ! phase-3 Allocation for plants @@ -846,8 +849,8 @@ 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, @@ -855,14 +858,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: ! @@ -890,6 +899,18 @@ subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, & end do + ! 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 diff --git a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 b/components/clm/src/biogeochem/CNEcosystemDynMod.F90 index aa0d529b35b5..47ae86c6da91 100755 --- a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 +++ b/components/clm/src/biogeochem/CNEcosystemDynMod.F90 @@ -103,8 +103,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 +145,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,7 +178,7 @@ 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 diff --git a/components/clm/src/biogeochem/PhosphorusFluxType.F90 b/components/clm/src/biogeochem/PhosphorusFluxType.F90 index 20e0840ed793..ac2541c44137 100755 --- a/components/clm/src/biogeochem/PhosphorusFluxType.F90 +++ b/components/clm/src/biogeochem/PhosphorusFluxType.F90 @@ -2038,6 +2038,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 diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index c512d7824905..34a522abcfc0 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -1308,13 +1308,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 @@ -1343,6 +1336,14 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) betrtracer_vars, tracerstate_vars, tracerflux_vars, & tracercoeff_vars, 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') From f48954eaaa02bc5a4b3296b3a613e18ac8c89da4 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Thu, 8 Jun 2017 15:49:11 -0400 Subject: [PATCH 05/35] Migrating CLM-PFLOTRAN TH-MODE - Step 1. Interface data types and variables. --- .../clm/src/biogeophys/EnergyFluxType.F90 | 14 + .../clm/src/biogeophys/TemperatureType.F90 | 8 +- .../clm/src/biogeophys/WaterfluxType.F90 | 12 +- .../clm/src/main/clm_bgc_interfaceMod.F90 | 597 +++++++++++------- components/clm/src/main/clm_driver.F90 | 68 +- .../clm/src/main/clm_interface_thType.F90 | 159 +++++ .../src/main/clm_pflotran_interfaceMod.F90 | 26 +- 7 files changed, 594 insertions(+), 290 deletions(-) create mode 100644 components/clm/src/main/clm_interface_thType.F90 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/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 0d35cb98138c..25069a508372 100644 --- a/components/clm/src/biogeophys/WaterfluxType.F90 +++ b/components/clm/src/biogeophys/WaterfluxType.F90 @@ -51,12 +51,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_bgc_interfaceMod.F90 b/components/clm/src/main/clm_bgc_interfaceMod.F90 index d980db3678ba..99ed6019f244 100644 --- a/components/clm/src/main/clm_bgc_interfaceMod.F90 +++ b/components/clm/src/main/clm_bgc_interfaceMod.F90 @@ -1,6 +1,6 @@ -module clm_bgc_interfaceMod +module clm_interface_funcsMod !!================================================================================================= -! CLM BioGeoChemistry (BGC) Interface +! CLM Theraml-Hydrology (TH) & BioGeoChemistry (BGC) Interface: Modules ! ! Created by wgs @ ORNL ! @@ -10,11 +10,11 @@ module clm_bgc_interfaceMod #include "shr_assert.h" - !! MODULE: clm_bgc_interfaceMod + !! MODULE: clm_interface_bgcMod !!-------------------------------------------------------------------------------------- !! 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-1: clm vars -> clm_bgc_data (i.e. clm_interface_bgc_datatype) ; 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 @@ -60,7 +60,9 @@ module clm_bgc_interfaceMod 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_full @@ -85,11 +87,11 @@ module clm_bgc_interfaceMod !!-------------------------------------------------------------------------------------- !! (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 + public :: get_clm_data !! STEP-1: clm vars -> clm_bgc_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_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 @@ -110,7 +112,7 @@ module clm_bgc_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_bgc_interface .and. use_clm_bgc) + !! if (use_clm_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 @@ -118,26 +120,27 @@ module clm_bgc_interfaceMod 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) + !! if (use_clm_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 + + 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 @@ -149,12 +152,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 @@ -166,40 +168,53 @@ 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, 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, cnstate_vars) @@ -222,7 +237,7 @@ subroutine get_clm_soil_property(clm_bgc_data, & 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, k ! indices integer :: gcount, cellcount @@ -241,15 +256,19 @@ 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) - + 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 , & @@ -262,38 +281,42 @@ subroutine get_clm_soil_property(clm_bgc_data, & !------------------------------------------------------------------------------------- !! 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_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_bgc_data%initial_cn_ratio(:) = initial_cn_ratio(:) - clm_bgc_data%initial_cp_ratio(:) = initial_cp_ratio(:) - clm_bgc_data%decomp_k_pools(:) = decomp_k_pools(1:ndecomp_pools) - clm_bgc_data%adfactor_kd_pools(:) = adfactor_kd_pools(1:ndecomp_pools) + 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) - clm_bgc_data%z(c,:) = z(c,:) - clm_bgc_data%zi(c,:) = zi(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_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_bgc_data%porosity_col(c,:) = porosity(c,:) - clm_bgc_data%eff_porosity_col(c,:) = eff_porosity(c,:) + clm_idata%cellorg_col(c,:) = cellorg(c,:) - clm_bgc_data%cellorg_col(c,:) = cellorg(c,:) + clm_idata%rootfr_col(c,:) = rootfr(c,:) ! do k = 1, ndecomp_cascade_transitions - clm_bgc_data%rf_decomp_cascade_col(c,:,k) = rf_decomp_cascade(c,:,k) - clm_bgc_data%pathfrac_decomp_cascade_col(c,:,k) = pathfrac_decomp_cascade(c,:,k) + 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 @@ -303,13 +326,10 @@ 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 @@ -328,18 +348,12 @@ 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 + integer :: fc, c, j ! indices !EOP !----------------------------------------------------------------------- @@ -393,77 +407,125 @@ subroutine get_clm_soil_thermohydro(clm_bgc_data, & !-------------------------------------------------------------------------------------- ! !! 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(:) - + clm_idata_th%forc_pbot_not_downscaled_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_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) + + 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_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%t_grnd_col(c) = t_grnd(c) + end do - clm_bgc_data%alt_indx_col(c) = alt_indx(c) - clm_bgc_data%finundated_col(c) = finundated(c) + end associate + end subroutine get_clm_soil_th_state +!!-------------------------------------------------------------------------------------- - 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) +!!-------------------------------------------------------------------------------------- + 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%htvp_col(c) = htvp(c) - clm_bgc_data%eflx_bot_col(c) = eflx_bot(c) - clm_bgc_data%soilpsi_col(c,:) = soilpsi(c,:) - clm_bgc_data%rootfr_col(c,:) = rootfr(c,:) + ! !ARGUMENTS: + implicit none - clm_bgc_data%watmin_col(c,:) = watmin(c,:) - clm_bgc_data%sucmin_col(c,:) = sucmin(c,:) + 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_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,:) + type(clm_interface_th_datatype) , intent(inout) :: clm_idata_th - clm_bgc_data%t_soisno_col(c,:) = t_soisno(c,:) + ! !LOCAL VARIABLES: + integer :: fc, c, j ! indices - 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,:) + !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] - end do + ) - ! CLM appears NO column-level ground-heat-flux variable, instead by 'patch' - do fc = 1, num_soilc + ! 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 - end associate - end subroutine get_clm_soil_thermohydro + end associate + end subroutine get_clm_soil_th_flux !!-------------------------------------------------------------------------------------- + !!-------------------------------------------------------------------------------------- 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 implicit none @@ -472,12 +534,14 @@ subroutine get_clm_bgc_state(clm_bgc_data, & 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" @@ -493,16 +557,30 @@ subroutine get_clm_bgc_state(clm_bgc_data, & 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 k = 1, ndecomp_pools @@ -522,6 +600,15 @@ 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,:) + + 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 !----------------------------------------------------------------------------- @@ -531,10 +618,11 @@ 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: @@ -556,8 +644,9 @@ 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(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_flux" @@ -682,7 +771,7 @@ 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) @@ -699,7 +788,7 @@ subroutine update_soil_moisture(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(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 @@ -714,9 +803,9 @@ subroutine update_soil_moisture(clm_bgc_data, & do fc = 1,num_soilc c = filter_soilc(fc) - 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,:) + 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 @@ -724,8 +813,8 @@ 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) ! @@ -741,7 +830,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 @@ -754,12 +843,55 @@ subroutine update_soil_temperature(clm_bgc_data, & do fc = 1,num_soilc c = filter_soilc(fc) - t_soisno(c,:) = clm_bgc_data%t_soisno_col(c,:) + 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, & + 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(soilhydrology_type) , intent(inout) :: soilhydrology_vars + type(energyflux_type) , intent(inout) :: energyflux_vars + + type(clm_interface_th_datatype), intent(in) :: clm_idata_th + + !----------------------------------------------------------------------- + + 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, & + waterstate_vars) + end if + + end subroutine update_th_data_pf2clm +!!-------------------------------------------------------------------------------------- + !!-------------------------------------------------------------------------------------- subroutine update_bgc_state_decomp(clm_bgc_data, & @@ -778,19 +910,19 @@ 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 !------------------------------------------------------------------------------------ - ! - 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 & + ) ! ------------------------------------------------------------------------ ! do fc = 1, num_soilc @@ -823,7 +955,7 @@ 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" @@ -868,8 +1000,8 @@ 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 @@ -884,7 +1016,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" @@ -925,7 +1057,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" @@ -982,7 +1114,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" @@ -1079,7 +1211,7 @@ 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) implicit none @@ -1090,7 +1222,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" @@ -1121,7 +1253,7 @@ 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) ! PFLOTRAN gas fluxes @@ -1133,7 +1265,7 @@ 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" @@ -1171,16 +1303,12 @@ 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 + use clm_varctl , only : use_pflotran, pf_cmode implicit none @@ -1190,13 +1318,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 @@ -1207,12 +1328,11 @@ 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 @@ -1238,29 +1358,19 @@ 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, & @@ -1292,11 +1402,11 @@ subroutine clm_bgc_run(clm_bgc_data, bounds, & 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, & + call clm_bgc_get_data(clm_interface_data, bounds, & num_soilc, filter_soilc, & canopystate_vars, soilstate_vars, & temperature_vars, waterstate_vars, & @@ -1316,9 +1426,9 @@ subroutine clm_bgc_run(clm_bgc_data, bounds, & 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, & + 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 @@ -1327,8 +1437,8 @@ 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, & + 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, & @@ -1356,7 +1466,7 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, & 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: integer :: fc, c, j, k @@ -1377,12 +1487,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) @@ -1404,38 +1514,37 @@ 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 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) - 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 @@ -1443,21 +1552,21 @@ subroutine clm_bgc_get_data(clm_bgc_data, bounds, & do fc = 1, num_soilc c = filter_soilc(fc) 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,:) + 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 @@ -1484,7 +1593,7 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, & 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: integer :: fc, c, j, k @@ -1612,10 +1721,10 @@ 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, & +! 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, & @@ -1631,13 +1740,13 @@ 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(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 @@ -1648,12 +1757,11 @@ 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 @@ -1676,5 +1784,6 @@ 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_driver.F90 b/components/clm/src/main/clm_driver.F90 index 34a522abcfc0..f036339fda8f 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -47,7 +47,7 @@ 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, @@ -137,18 +137,18 @@ module clm_driver !!---------------------------------------------------------------------------- !! 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 + 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 + 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_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 : 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 !!---------------------------------------------------------------------------- ! @@ -802,9 +802,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) ! - 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, & @@ -819,18 +819,19 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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') @@ -841,16 +842,15 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) !! STEP-2: (2) run pflotran !! STEP-2: (3) update clm_bgc_data from pflotran ! ------------------------------------------------------------------------- - call clm_pf_run(clm_bgc_data,bounds_clump, filter, nc) + 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, & + 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, & + !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, & @@ -866,7 +866,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) !! STEP-2: (2) run CNDecompAlloc !! STEP-2: (3) update clm_bgc_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, & @@ -877,20 +877,20 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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, & + 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, & + !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_clm_interface) !!-------------------------------------------------------------------------------- call CNEcosystemDynNoLeaching2(bounds_clump, & @@ -907,7 +907,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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, & 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..e435e3f6c5f7 --- /dev/null +++ b/components/clm/src/main/clm_interface_thType.F90 @@ -0,0 +1,159 @@ +module clm_interface_thType + +!!================================================================================================= +! ALM Thermal(T)-Hydrology (H) Interface: Data Type (Variables) +! +! Created by wgs @ ORNL +! +! date: 8/25/2015 +! update: 9/16/2016, 2/2/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] + + ! atm2lnd: + real(r8), pointer :: forc_pbot_not_downscaled_grc (:) ! downscaled 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_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_not_downscaled_grc (begg:endg)) ; this%forc_pbot_not_downscaled_grc (:) = 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 index ab1f5788c009..0158bce58e3b 100644 --- a/components/clm/src/main/clm_pflotran_interfaceMod.F90 +++ b/components/clm/src/main/clm_pflotran_interfaceMod.F90 @@ -3,7 +3,7 @@ module clm_interface_pflotranMod !#define CLM_PFLOTRAN ! the above #directive IS for explicit coupling CLM and PFLOTRAN (i.e. this interface) -#define COLUMN_MODE +!#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; @@ -117,13 +117,13 @@ module clm_interface_pflotranMod 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 @@ -294,6 +294,7 @@ subroutine clm_pf_run(clm_interface_data, bounds, filters, ifilter) 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) @@ -305,6 +306,7 @@ subroutine clm_pf_run(clm_interface_data, bounds, filters, ifilter) 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 @@ -1165,6 +1167,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) endif +#ifdef PF_THMODE ! (2) CLM thermal BC to PFLOTRAN-CLM interface if (pf_tmode) then @@ -1182,6 +1185,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) call pflotranModelUpdateHSourceSink( pflotran_m ) ! H SrcSink call pflotranModelSetSoilHbcsFromCLM( pflotran_m ) ! H bc end if +#endif ! (4) if (pf_cmode) then @@ -1224,6 +1228,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (6) update CLM variables from PFLOTRAN +#ifdef PF_THMODE if (pf_hmode) then call pflotranModelGetSaturationFromPF( pflotran_m ) ! hydrological states @@ -1232,14 +1237,18 @@ subroutine pflotran_run_onestep(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 +#endif if (pf_cmode) then call pflotranModelGetBgcVariablesFromPF( pflotran_m) ! bgc variables @@ -1839,7 +1848,7 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) 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) @@ -2287,6 +2296,7 @@ end subroutine get_clm_iceadj_porosity !----------------------------------------------------------------------------- !BOP + ! ! !IROUTINE: get_clm_bcwflx ! @@ -2308,6 +2318,7 @@ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) 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 @@ -3092,6 +3103,7 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) ! 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 @@ -3645,6 +3657,10 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) end associate end subroutine update_bcflow_pf2clm + + ! + !----------------------------------------------------------------------------- + ! ! !----------------------------------------------------------------------------- ! !ROUTINE: update_soil_bgc_pf2clm() @@ -4042,6 +4058,7 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil 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 & ) @@ -4903,5 +4920,4 @@ end subroutine clm_pf_NBalanceCheck ! (END) !************************************************************************************! - -end module clm_interface_pflotranMod \ No newline at end of file +end module clm_interface_pflotranMod From b2a07388e2f629aa18ebe8799f83d6c7d8b4dfed Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 2 May 2017 11:14:34 -0400 Subject: [PATCH 06/35] =?UTF-8?q?Migrating=20CLM-PFLOTRAN=20TH-MODE=20-=20?= =?UTF-8?q?Step=201.=20Interface=20data=20types=20and=20variables:=20(2)?= =?UTF-8?q?=20rename=20namelist=20=E2=80=98use=5Fbgc=5Finterface=E2=80=99?= =?UTF-8?q?=20to=20=E2=80=98use=5Fclm=5Finterface=E2=80=99,=20so=20that=20?= =?UTF-8?q?it=20includes=20thermal-hydrology=20and=20biogeochemical=20inte?= =?UTF-8?q?rfaces.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../namelist_files/namelist_definition_clm4_5.xml | 2 +- components/clm/src/biogeochem/CNAllocationMod.F90 | 4 ++-- components/clm/src/biogeochem/CNCarbonFluxType.F90 | 12 ++++++------ components/clm/src/biogeochem/CNCarbonStateType.F90 | 3 +-- components/clm/src/biogeochem/CNEcosystemDynMod.F90 | 12 ++++++------ components/clm/src/biogeochem/CNNitrogenFluxType.F90 | 4 ++-- components/clm/src/biogeochem/PhosphorusFluxType.F90 | 10 +++++----- components/clm/src/main/clm_varctl.F90 | 2 +- components/clm/src/main/controlMod.F90 | 8 ++++---- 9 files changed, 28 insertions(+), 29 deletions(-) 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 82eaaa0752d4..62663b00a520 100644 --- a/components/clm/bld/namelist_files/namelist_definition_clm4_5.xml +++ b/components/clm/bld/namelist_files/namelist_definition_clm4_5.xml @@ -1575,7 +1575,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/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index e95b3a36ef34..5c149f7ecb29 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 @@ -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) diff --git a/components/clm/src/biogeochem/CNCarbonFluxType.F90 b/components/clm/src/biogeochem/CNCarbonFluxType.F90 index be3c302ada66..5e223a8b0293 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 @@ -393,7 +393,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). @@ -785,7 +785,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 @@ -3912,7 +3912,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 @@ -4816,8 +4816,8 @@ 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 !---------------------------------------------------------------- diff --git a/components/clm/src/biogeochem/CNCarbonStateType.F90 b/components/clm/src/biogeochem/CNCarbonStateType.F90 index bd2a3e00586f..edbabf6b7abd 100644 --- a/components/clm/src/biogeochem/CNCarbonStateType.F90 +++ b/components/clm/src/biogeochem/CNCarbonStateType.F90 @@ -22,8 +22,7 @@ module CNCarbonStateType use VegetationType , only : veg_pp ! bgc interface & pflotran - use clm_varctl , only : use_bgc_interface, use_pflotran, pf_cmode - + use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode ! ! !PUBLIC TYPES: diff --git a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 b/components/clm/src/biogeochem/CNEcosystemDynMod.F90 index 47ae86c6da91..279b5d73674d 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 @@ -430,7 +430,7 @@ subroutine CNEcosystemDynNoLeaching1(bounds, & call t_stopf('PDeposition') !!------------------------------------------------------------------------------------------------- -!! plfotran: 'decomp_rate_constants' must be calculated before entering "clm_bgc_interface" +!! 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) @@ -446,7 +446,7 @@ subroutine CNEcosystemDynNoLeaching1(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) + !! 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 , & @@ -559,9 +559,9 @@ subroutine CNEcosystemDynNoLeaching2(bounds, & call t_startf('CNDecompAlloc') !---------------------------------------------------------------- - if(.not.use_bgc_interface) then + if(.not.use_clm_interface) then !! directly run clm-bgc - !! if (use_bgc_interface & use_clm_bgc), then CNDecomAlloc is called in clm_driver + !! 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,7 +570,7 @@ 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 diff --git a/components/clm/src/biogeochem/CNNitrogenFluxType.F90 b/components/clm/src/biogeochem/CNNitrogenFluxType.F90 index 952efc06670f..3a4f5ce3fa83 100644 --- a/components/clm/src/biogeochem/CNNitrogenFluxType.F90 +++ b/components/clm/src/biogeochem/CNNitrogenFluxType.F90 @@ -14,7 +14,7 @@ module CNNitrogenFluxType 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 + use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc ! ! !PUBLIC TYPES: implicit none @@ -3081,7 +3081,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil ! bgc interface & pflotran !---------------------------------------------------------------- - if (use_bgc_interface .and. pf_cmode) then + if (use_clm_interface .and. pf_cmode) then call NSummary_interface(this, bounds, num_soilc, filter_soilc) end if !---------------------------------------------------------------- diff --git a/components/clm/src/biogeochem/PhosphorusFluxType.F90 b/components/clm/src/biogeochem/PhosphorusFluxType.F90 index ac2541c44137..cc4c9582194f 100755 --- a/components/clm/src/biogeochem/PhosphorusFluxType.F90 +++ b/components/clm/src/biogeochem/PhosphorusFluxType.F90 @@ -14,7 +14,7 @@ module PhosphorusFluxType 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 + use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc ! ! !PUBLIC TYPES: implicit none @@ -281,7 +281,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) @@ -643,7 +643,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 @@ -1685,7 +1685,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 @@ -2399,7 +2399,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil !! bgc interface & pflotran: !---------------------------------------------------------------- - if (use_bgc_interface) then + if (use_clm_interface) then call PSummary_interface(this, bounds, num_soilc, filter_soilc) end if !---------------------------------------------------------------- diff --git a/components/clm/src/main/clm_varctl.F90 b/components/clm/src/main/clm_varctl.F90 index 414901dd3326..81d3e76b6250 100644 --- a/components/clm/src/main/clm_varctl.F90 +++ b/components/clm/src/main/clm_varctl.F90 @@ -337,7 +337,7 @@ 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. diff --git a/components/clm/src/main/controlMod.F90 b/components/clm/src/main/controlMod.F90 index f25503650537..15110b284636 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 betr_initializeMod , only : betr_readNL ! implicit none @@ -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 @@ -403,7 +403,7 @@ subroutine control_init( ) ! ---------------------------------------------------------------------- !! bgc & pflotran interface - if(.not.use_bgc_interface) then + if(.not.use_clm_interface) then use_clm_bgc = .true. use_pflotran = .false. end if @@ -736,7 +736,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) From 1267940a9483a3e52bf3df1d0c78ceb1ecae763d Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 2 May 2017 11:20:54 -0400 Subject: [PATCH 07/35] Migrating CLM-PFLOTRAN TH-MODE - Step 2. Editing codes for including thermal-hydrology (TH) modules in interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (1) Separate original ’clm_bgc_data’ into ‘th’ and ‘bgc’ data types, which included in a general interface data type, ‘clm_interface_data_type’; (2) Rename ‘clm_bgc_interfaceMod’ to ‘clm_interface_funcsMod’; (3) Rename ‘clm_pflotran_interfaceMod’ to ‘clm_interface_pflotranMod’. --- components/clm/src/main/clm_initializeMod.F90 | 12 +- components/clm/src/main/clm_instMod.F90 | 4 +- ...ace_data.F90 => clm_interface_bgcType.F90} | 111 +- .../clm/src/main/clm_interface_dataType.F90 | 130 +++ ...faceMod.F90 => clm_interface_funcsMod.F90} | 199 +--- ...eMod.F90 => clm_interface_pflotranMod.F90} | 974 ++++++++---------- 6 files changed, 628 insertions(+), 802 deletions(-) rename components/clm/src/main/{clm_bgc_interface_data.F90 => clm_interface_bgcType.F90} (79%) create mode 100644 components/clm/src/main/clm_interface_dataType.F90 rename components/clm/src/main/{clm_bgc_interfaceMod.F90 => clm_interface_funcsMod.F90} (89%) rename components/clm/src/main/{clm_pflotran_interfaceMod.F90 => clm_interface_pflotranMod.F90} (87%) diff --git a/components/clm/src/main/clm_initializeMod.F90 b/components/clm/src/main/clm_initializeMod.F90 index 8524a45f3f9a..8d2939e51cbc 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 betr_initializeMod , only : betr_initialize use betr_initializeMod , only : betrtracer_vars, tracerstate_vars, tracerflux_vars, tracercoeff_vars use betr_initializeMod , only : bgc_reaction @@ -892,15 +892,15 @@ subroutine initialize2( ) !------------------------------------------------------------ !! 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) + 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 748659b7fa9d..f5bf24abf411 100644 --- a/components/clm/src/main/clm_instMod.F90 +++ b/components/clm/src/main/clm_instMod.F90 @@ -55,7 +55,7 @@ module clm_instMod 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 CLMFatesInterfaceMod , only : hlm_fates_interface_type @@ -109,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 diff --git a/components/clm/src/main/clm_bgc_interface_data.F90 b/components/clm/src/main/clm_interface_bgcType.F90 similarity index 79% rename from components/clm/src/main/clm_bgc_interface_data.F90 rename to components/clm/src/main/clm_interface_bgcType.F90 index cb6758ea6ca4..941e44f257fb 100644 --- a/components/clm/src/main/clm_bgc_interface_data.F90 +++ b/components/clm/src/main/clm_interface_bgcType.F90 @@ -1,4 +1,4 @@ -module clm_bgc_interface_data +module clm_interface_bgcType !!================================================================================================= ! CLM BioGeoChemistry (BGC) Interface: Data Type (Variables) ! @@ -13,10 +13,10 @@ module clm_bgc_interface_data use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) implicit none -! save +! private - type, public :: clm_bgc_interface_data_type + type, public :: clm_interface_bgc_datatype ! clm_varpar integer :: nlevdecomp_full ! num of CLM soil layers that are mapped to/from PFLOTRAN @@ -29,40 +29,6 @@ module clm_bgc_interface_data real(r8), pointer :: initial_cn_ratio (:) ! c:n ratio for initialization of pools real(r8), pointer :: initial_cp_ratio (:) ! c:p ratio for initialization of pools - ! col: - 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 :: 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 - ! ch4 real(r8), pointer :: finundated_col (:) ! col fractional inundated area (excluding dedicated wetland cols) real(r8), pointer :: o2stress_unsat_col (:,:) ! col Ratio of oxygen available to that demanded by roots, aerobes, & methanotrophs (nlevsoi) @@ -219,21 +185,7 @@ module clm_bgc_interface_data 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 - ! 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] - ! 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) @@ -246,10 +198,10 @@ module clm_bgc_interface_data 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 +!! type(clm_interface_bgc_datatype) , public, target , save :: clm_bgc_data contains @@ -257,7 +209,7 @@ module clm_bgc_interface_data !!------------------------------------------------------------------------------------------------- subroutine Init(this, bounds) use decompMod , only : bounds_type - class(clm_bgc_interface_data_type) :: this + class(clm_interface_bgc_datatype) :: this type(bounds_type), intent(in) :: bounds call this%InitAllocate (bounds) @@ -275,7 +227,7 @@ subroutine InitAllocate(this, bounds) !! ARGUMENTS: real(r8) :: ival = 0.0_r8 ! initial value - class(clm_bgc_interface_data_type) :: this + class(clm_interface_bgc_datatype) :: this type(bounds_type), intent(in) :: bounds !! LOCAL VARIABLES: @@ -294,39 +246,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%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,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%watmin_col (begc:endc,nlevgrnd)) ; this%watmin_col (:,:) = nan - allocate(this%sucsat_col (begc:endc,nlevgrnd)) ; this%sucsat_col (:,:) = spval - allocate(this%sucmin_col (begc:endc,nlevgrnd)) ; this%sucmin_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 @@ -486,21 +405,7 @@ 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 !!------------------------------------------------------------------------------------------ @@ -510,4 +415,4 @@ subroutine InitAllocate(this, bounds) 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..51fc3025dfc9 --- /dev/null +++ b/components/clm/src/main/clm_interface_dataType.F90 @@ -0,0 +1,130 @@ +module clm_interface_dataType + +!!================================================================================================= +! ALM Thermal(T)-Hydrology (H) & BioGeoChemistry (BGC) Interface: Data Type (Variables) +! +! Created by wgs @ ORNL +! +! date: 8/25/2015 +! update: 9/16/2016, 2/2/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+1: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 89% rename from components/clm/src/main/clm_bgc_interfaceMod.F90 rename to components/clm/src/main/clm_interface_funcsMod.F90 index 99ed6019f244..627f7c5a9f45 100644 --- a/components/clm/src/main/clm_bgc_interfaceMod.F90 +++ b/components/clm/src/main/clm_interface_funcsMod.F90 @@ -135,9 +135,8 @@ subroutine get_clm_data(clm_idata, & bounds, num_soilc, filter_soilc, & num_soilp, filter_soilp, & atm2lnd_vars, soilstate_vars, & - waterstate_vars, waterflux_vars, & - temperature_vars, energyflux_vars, & - cnstate_vars, carbonflux_vars, carbonstate_vars, & + waterstate_vars, temperature_vars, cnstate_vars, & + carbonflux_vars, carbonstate_vars, & nitrogenflux_vars, nitrogenstate_vars, & phosphorusflux_vars, phosphorusstate_vars, & ch4_vars & @@ -152,12 +151,9 @@ subroutine get_clm_data(clm_idata, & 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(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(energyflux_type) , intent(in) :: energyflux_vars type(cnstate_type) , intent(in) :: cnstate_vars type(carbonflux_type) , intent(in) :: carbonflux_vars @@ -170,46 +166,32 @@ subroutine get_clm_data(clm_idata, & 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" !----------------------------------------------------------------------- - associate ( & - clm_idata_th => clm_idata%th, & - clm_idata_bgc => clm_idata%bgc & - ) + character(len=256) :: subname = "get_clm_data" call get_clm_soil_property(clm_idata, & bounds, num_soilc, filter_soilc, & soilstate_vars, cnstate_vars) - call get_clm_soil_th_state(clm_idata_th, & + call get_clm_soil_th_state(clm_idata%th, & bounds, num_soilc, filter_soilc, & atm2lnd_vars, soilstate_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_idata_bgc, & + call get_clm_bgc_state(clm_idata%bgc, & bounds, num_soilc, filter_soilc, & atm2lnd_vars, soilstate_vars, & carbonstate_vars, nitrogenstate_vars, & phosphorusstate_vars, & ch4_vars) - call get_clm_bgc_flux(clm_idata_bgc, & + call get_clm_bgc_flux(clm_idata%bgc, & bounds, num_soilc, filter_soilc, & cnstate_vars, carbonflux_vars, & nitrogenflux_vars, phosphorusflux_vars, & ch4_vars) - end associate end subroutine get_clm_data !!-------------------------------------------------------------------------------------- @@ -353,82 +335,42 @@ subroutine get_clm_soil_th_state(clm_idata_th, & type(clm_interface_th_datatype) , intent(inout) :: clm_idata_th ! !LOCAL VARIABLES: - integer :: fc, c, j ! indices + integer :: fc, c ! 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 - 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] - - 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) + ) !-------------------------------------------------------------------------------------- ! !! grid: - clm_idata_th%forc_pbot_not_downscaled_grc = forc_pbot + clm_idata_th%forc_pbot_not_downscaled_grc(:) = forc_pbot(:) do fc = 1,num_soilc c = filter_soilc(fc) - clm_idata_th%frac_sno_eff_col(c) = frac_sno_eff(c) - clm_idata_th%frac_h2osfc_col(c) = frac_h2osfc(c) + clm_idata_th%soilpsi_col(c,:) = soilpsi(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_idata_th%h2osoi_vol_col(c,:) = h2osoi_vol(c,:) + clm_idata_th%h2osoi_liq_col(c,:) = h2osoi_liq(c,:) + clm_idata_th%h2osoi_ice_col(c,:) = h2osoi_ice(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_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_idata_th%t_soisno_col(c,:) = t_soisno(c,:) end do @@ -436,89 +378,6 @@ subroutine get_clm_soil_th_state(clm_idata_th, & end subroutine get_clm_soil_th_state !!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- - 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 - - - ! !ARGUMENTS: - implicit none - - 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 - - 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_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 - - end associate - end subroutine get_clm_soil_th_flux -!!-------------------------------------------------------------------------------------- - - !!-------------------------------------------------------------------------------------- subroutine get_clm_bgc_state(clm_bgc_data, & bounds, num_soilc, filter_soilc, & diff --git a/components/clm/src/main/clm_pflotran_interfaceMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 similarity index 87% rename from components/clm/src/main/clm_pflotran_interfaceMod.F90 rename to components/clm/src/main/clm_interface_pflotranMod.F90 index 0158bce58e3b..23f500ba7d00 100644 --- a/components/clm/src/main/clm_pflotran_interfaceMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -70,8 +70,11 @@ module clm_interface_pflotranMod #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) +#ifdef COLUMN_MODE + integer, pointer, public :: filters_colcount_beg(:) ! dim: column block's 1st col on filters(1:nc) +#else + logical, pointer, public :: mapped_gcount_skip(:) ! dim: inactive grid mask in bounds%begg:endg +#endif #endif ! character(len=256), private:: pflotran_prefix = '' @@ -259,16 +262,17 @@ end subroutine pflotran_not_available !------------------------------------------------------------------------------------------! !----------------------------------------------------------------------------- - subroutine clm_pf_interface_init(bounds) + subroutine clm_pf_interface_init(bounds, filters) implicit none type(bounds_type), intent(in) :: bounds ! bounds + type(clumpfilter), intent(in) :: filters(:) ! filters character(len=256) :: subname = "clm_pf_interface_init()" #ifdef CLM_PFLOTRAN - call interface_init(bounds) + call interface_init(bounds, filters) #else call pflotran_not_available(subname) #endif @@ -368,7 +372,7 @@ end subroutine clm_pf_finalize ! !IROUTINE: interface_init ! ! !INTERFACE: - subroutine interface_init(bounds) + subroutine interface_init(bounds, filters) ! ! !DESCRIPTION: ! initialize the pflotran iterface @@ -381,18 +385,21 @@ subroutine interface_init(bounds) 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 domainMod , only : ldomain, lon1d, lat1d !!lon0,lat0 - use clm_time_manager, only : get_nstep + use clm_time_manager, only : get_nstep !!nsstep, nestep 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 + pf_surfaceflow !! = pflotran_surfaceflow + use filterMod , only : allocFilters use CNDecompCascadeConType , only : decomp_cascade_con +! use abortutils , only : endrun + ! pflotran use Option_module, only : printErrMsg @@ -411,6 +418,7 @@ subroutine interface_init(bounds) #include "petsc/finclude/petscsys.h" #include "petsc/finclude/petscvec.h" #include "petsc/finclude/petscvec.h90" +! #include "finclude/petscviewer.h" ! ! !REVISION HISTORY: @@ -422,13 +430,15 @@ subroutine interface_init(bounds) ! LOCAL VARAIBLES: type(bounds_type), intent(in) :: bounds ! bounds + type(clumpfilter), intent(in) :: filters(:) ! filters integer :: global_numg ! total number of gridcells across all processors (active) integer :: global_numc ! total number of columns across all processors (active) + integer :: global_nump ! total number of pfts 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 :: nc, nclumps, total_soilc, start_mappedgid, nx, ny, npes_pf + integer, pointer :: total_soilc_all(:) ! dim: npes + integer, pointer :: mapped_gid(:) ! dim: num_soilc integer :: gid, gcount, colcount, cellcount integer :: gcolumns(1:bounds%endg-bounds%begg+1) integer :: ierr @@ -465,148 +475,134 @@ subroutine interface_init(bounds) lat0 = ldomain%lat0 !!wgs:end---------------------------------------------------------------- - ! (0) determines Total grids/columns and ids to be mapped between CLM and PFLOTRAN + ! (0) determines Total grids/columns 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 - + nclumps = get_proc_clumps() + do nc=1,nclumps ! current process + total_soilc = total_soilc + filters(nc)%num_soilc end do call mpi_barrier(mpicom, ierr) ! needs all processes done first - ! sum of all active soil columns across all processors (information only) + ! sum of all active soil columns across all processors 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)) + ! and must be in order, corresponding to 'bounds%begc:endc' filtered by 'filter%soilc' + ! bounds: begc, begc+1, begc+2, ..., endc ! note: must skip those not 'ltype(l)==istsoil' or 'ltype(l)==istcrop' + ! filters: (1)%soilc(:), (2)%soilc(:), ..., (nclumps)%soilc(:) + ! columnid: start_columnid(1), start_colunmid+1, ..., start_columnid+total_soilc-1 + + allocate (total_soilc_all(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) + total_soilc_all, 1, MPI_INTEGER, 0, mpicom, ierr) + call mpi_bcast(total_soilc_all, 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)) + ! corresponding starting no. of re-ordered filtered-columns (zero-based) + ! will be used to skip block(s) of columns in 'bounds%begc:endc' for 'filters(nc)%soilc' in the interface data vec. + allocate(filters_colcount_beg(1:nclumps)) + start_mappedgid = 0 + colcount = 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 + do nc=1, nclumps + filters_colcount_beg(nc) = 0 + do c=1,filters(nc)%num_soilc + colcount = colcount + 1 + mapped_gid(colcount) = start_mappedgid + c + + enddo + if (nc>1) filters_colcount_beg(nc) = colcount + start_mappedgid = start_mappedgid + filters(nc)%num_soilc ! skip by fileter's stride, when 'pid==iam' 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 + start_mappedgid = start_mappedgid + total_soilc_all(pid) ! skip by pes's total soil column, until 'pid==iam' and exit do-loop 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. + ! assumption that only 1 natural/cropped soil-column allowed per grid cell NOW + gcolumns(:) = 0 !grc%ncolumns NOT assigned values at all 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' + 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 + ! count active columns for a gridcell + gcount = g - bounds%begg + 1 + if (cactive(c)) 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' + if (gcolumns(g-bounds%begg+1) /= 1) then + write (iulog,*) 'ERROR: More than 1 or no ACTIVE 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.") + 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 - endif + + ! counting active gridcells in current pes + total_soilc = 0 + do l=bounds%begl, bounds%endl + if(ltype(l)==istsoil .or. ltype(l)==istcrop) then + total_soilc = total_soilc + 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) + ! sum of all active gridcells across all processors + call mpi_allreduce(total_soilc, global_numc, 1, MPI_INTEGER,MPI_SUM,mpicom,ierr) - ! counting active gridcells in current pes - total_grid = bounds%endg-bounds%begg+1 + ! collect info for all pes + allocate (total_soilc_all(0:npes-1)) + call mpi_gather(total_soilc, 1, MPI_INTEGER, & + total_soilc_all, 1, MPI_INTEGER, 0, mpicom, ierr) + call mpi_bcast(total_soilc_all, npes, MPI_INTEGER, 0, mpicom, ierr) ! 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)) + allocate(mapped_gid(1:total_soilc)) ! 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%gindex(g) ! this is the globally grid-index, i.e. 'an' in its original calculation - mapped_gcount_skip(gcount) = .false. - endif + gcount = 0 + mapped_gcount_skip(:) = .true. + do l=bounds%begl, bounds%endl + g = lgridcell(l) + if(ltype(l)==istsoil .or. ltype(l)==istcrop) then + gcount = gcount + 1 + mapped_gid(gcount) = grc%gindex(g) ! this is the globally grid-index + mapped_gcount_skip(g-bounds%begg+1) = .false. + endif end do @@ -624,7 +620,7 @@ subroutine interface_init(bounds) 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,' %%' + write(iulog,*) '%% Total grids with active soil columns: ',global_numc,' %%' #endif write(iulog,*) '%% %%' write(iulog,*) '%%--------------------------------------------------------%%' @@ -672,12 +668,12 @@ subroutine interface_init(bounds) ! do pid=0, npes-1 - clm_pf_idata%clm_lx(pid+1) = total_soilc_pes(pid) + clm_pf_idata%clm_lx(pid+1) = total_soilc_all(pid) end do clm_pf_idata%clm_ly = 1 clm_pf_idata%clm_lz = clm_pf_idata%nzclm_mapped - deallocate(total_soilc_pes) + deallocate(total_soilc_all) #else clm_pf_idata%nxclm_mapped = ldomain%ni ! longitudial @@ -732,6 +728,9 @@ subroutine interface_init(bounds) end do clm_pf_idata%clm_lz = clm_pf_idata%nzclm_mapped + ! clean-ups + deallocate(total_soilc_all) + #endif if (masterproc) then @@ -918,15 +917,15 @@ subroutine interface_init(bounds) #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 + clm_all_npts = total_soilc*clm_pf_idata%nzclm_mapped ! 'total_soilc' was only counted with active-column grid + 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 gcount = 1, total_grid + do gcount = 1, total_soilc gid = mapped_gid(gcount) @@ -967,35 +966,29 @@ subroutine interface_init(bounds) 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 + if(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 + if(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 + if(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 + if(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 + if(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 + if(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 @@ -1056,15 +1049,6 @@ subroutine interface_init(bounds) pf_cmode = .true. ! initialized as '.false.' in clm initialization endif - !! wgs:beg----------------------------------------------------------- - - ! force CLM soil domain into PFLOTRAN subsurface grids - - ! Currently always set soil hydraulic/BGC properties from CLM to PF - - ! Get top surface area of 3-D pflotran subsurface domain -! call pflotranModelGetTopFaceArea(pflotran_m) - !! wgs:end----------------------------------------------------------- ! Initialize PFLOTRAN states call pflotranModelStepperRunInit(pflotran_m) @@ -1316,7 +1300,11 @@ subroutine pflotran_finalize() call pflotranModelDestroy(pflotran_m) endif +#ifdef COLUMN_MODE + deallocate(filters_colcount_beg) +#else deallocate(mapped_gcount_skip) +#endif end subroutine pflotran_finalize @@ -1344,7 +1332,6 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) use clm_varpar , only : nlevgrnd use domainMod , only : ldomain use landunit_varcon , only : istsoil, istcrop - use clm_varcon , only : re ! @@ -1368,14 +1355,12 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! LOCAL VARAIBLES: integer :: g,l,c,j ! indices - integer :: gcount, colcount, cellcount ! gcount: 0-based, colcount: 1-based, cellcount: 1-based + integer :: gcount, cellcount ! gcount: 0-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 +#ifndef COLUMN_MODE real(r8) :: wtgcell_sum(1:bounds%endg-bounds%begg+1) integer :: xwtgcell_c(1:bounds%endg-bounds%begg+1) #endif @@ -1425,23 +1410,20 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ) -#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 +#ifndef COLUMN_MODE ! 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 + gcount = cgridcell(c) - bounds%begg + 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 + xwtgcell_c(gcount) = c end if end if @@ -1518,25 +1500,25 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) !!!! call VecGetArrayF90(clm_pf_idata%cellid_clmp, cellid_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%zisoil_clmp, zisoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%dxsoil_clmp, dxsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%dysoil_clmp, dysoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%dzsoil_clmp, dzsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%area_top_face_clmp, toparea_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%xsoil_clmp, xsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%ysoil_clmp, ysoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%zsoil_clmp, zsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) zisoil_clm_loc(:) = 0._r8 dxsoil_clm_loc(:) = 0._r8 @@ -1548,33 +1530,32 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ysoil_clm_loc(:) = 0._r8 zsoil_clm_loc(:) = 0._r8 + do j = 1, clm_pf_idata%nzclm_mapped -#ifdef COLUMN_MODE - gcount = -1 - do c = bounds%begc, bounds%endc - g = cgridcell(c) - l = clandunit(c) + if (j <= nlevgrnd) then - 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 +#ifdef COLUMN_MODE + gcount = 0 + do c = bounds%begc, bounds%endc + g = cgridcell(c) + l = clandunit(c) - cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based + ! note that filters%soilc includes 'istsoil' and 'istcrop' + ! (TODO: checking col_pp%itype and lun%itype - appears not match with each other, and col_pp%itype IS messy) + if (ltype(l)==istsoil .or. ltype(l)==istcrop) then + gcount = gcount + 1 ! actually is the active soil column count + cellcount = (gcount-1)*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) + zisoil_clm_loc(cellcount) = -zi(c, j) + lelev(g) ! cell-node 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 + toparea_clm_loc(cellcount) = cwtgcell(c) * 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 @@ -1585,37 +1566,25 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) 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) + * cwtgcell(c) * 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) + * cwtgcell(c) * 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 + 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 - + do g = bounds%begg, bounds%endg + gcount = g - bounds%begg ! 0-based cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based cellid_clm_loc(cellcount) = (grc%gindex(g)-1)*clm_pf_idata%nzclm_mapped + j ! 1-based @@ -1627,42 +1596,42 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! 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) + zisoil_clm_loc(cellcount) = -zi(xwtgcell_c(gcount+1), j) + lelev(g) ! cell-node 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") + enddo ! do g = bounds%begg, bounds%endg +#endif - endif + else + call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // & + " 'clm_varpar%nlevgrnd'. Please check") - enddo ! do j=1,nzclm_mapped - enddo ! do g = bounds%begg, bounds%endg -#endif + endif + enddo call VecRestoreArrayF90(clm_pf_idata%cellid_clmp, cellid_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%zisoil_clmp, zisoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%dxsoil_clmp, dxsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%dysoil_clmp, dysoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%dzsoil_clmp, dzsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%area_top_face_clmp, toparea_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%xsoil_clmp, xsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%ysoil_clmp, ysoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%zsoil_clmp, zsoil_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) ! Set CLM soil domain onto PFLOTRAN grid call pflotranModelSetSoilDimension(pflotran_m) @@ -1746,6 +1715,7 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) ! 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 @@ -1833,30 +1803,31 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) call VecGetArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%tkwet_clmp, tkwet_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%tkdry_clmp, tkdry_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%tkfrz_clmp, tkfrz_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%hcvsol_clmp, hcvsol_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) + hksat_x_clm_loc(:) = 0._r8 hksat_y_clm_loc(:) = 0._r8 @@ -1872,29 +1843,26 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) 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. + gcount = 0 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. & - (col%active(c) .and. cwtgcell(c)>0._r8) ) then ! skip inactive or zero-weighted column (may be not needed, but in case) + if (ltype(l)==istsoil .or. ltype(l)==istcrop) then #ifdef COLUMN_MODE - gcount = gcount + 1 ! 0-based column (fake grid) count + gcount = gcount + 1 ! 1-based column (fake grid) count wtgcount = 1._r8 #else - gcount = g - bounds%begg ! 0-based actual grid numbering + gcount = g - bounds%begg + 1 ! 1-based 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 + cellcount = (gcount - 1) *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)) @@ -1940,33 +1908,31 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) 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__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%tkwet_clmp, tkwet_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%tkdry_clmp, tkdry_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%tkfrz_clmp, tkfrz_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%hcvsol_clmp, hcvsol_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) ! Set CLM soil properties onto PFLOTRAN grid call pflotranModelSetSoilProp(pflotran_m) @@ -2064,36 +2030,38 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, nstep = get_nstep() call VecGetArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%h2osoi_vol_clmp, soilvwc_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%t_scalar_clmp, t_scalar_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%w_scalar_clmp, w_scalar_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%o_scalar_clmp, o_scalar_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) + - ! 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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. #else gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif do j = 1, clm_pf_idata%nzclm_mapped @@ -2139,15 +2107,15 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, endif endif !!if(.not.pf_frzmode) - soillsat_clmp_loc(cellcount) = sattmp + 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) + 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) + soilvwc_clmp_loc(cellcount) =h2osoi_vol(c,j) endif !!if (initpfhmode) then @@ -2166,23 +2134,23 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, 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__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%h2osoi_vol_clmp, soilvwc_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%t_scalar_clmp, t_scalar_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%w_scalar_clmp, w_scalar_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%o_scalar_clmp, o_scalar_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) end associate end subroutine get_clm_soil_th @@ -2248,22 +2216,23 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) ! 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__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) - ! operating via 'filters' - gcount = -1 do fc = 1,filters(ifilter)%num_soilc - c = filters(ifilter)%soilc(fc) - g = cgridcell(c) + 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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. #else - gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + gcount = g - bounds%begg ! 0-based + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif do j = 1, clm_pf_idata%nzclm_mapped @@ -2284,9 +2253,9 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) end do call VecRestoreArrayF90(clm_pf_idata%effporosity_clmp, adjporosity_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) end if @@ -2294,6 +2263,7 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) end subroutine get_clm_iceadj_porosity ! + !----------------------------------------------------------------------------- !BOP @@ -2318,7 +2288,6 @@ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) 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 @@ -2696,7 +2665,7 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) ! at both ground and bottom interface (BC). ! ! !USES: - use ColumnType , only : col + 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 @@ -2742,9 +2711,9 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) !EOP !----------------------------------------------------------------------- associate ( & - cgridcell => col%gridcell , &! column's gridcell - dz => col%dz , &! layer thickness depth (m) - snl => col%snl , &! number of snow layers (negative) + 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) @@ -2885,7 +2854,6 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) end associate end subroutine get_clm_bceflx - ! !----------------------------------------------------------------------------- ! @@ -2898,7 +2866,7 @@ end subroutine get_clm_bceflx ! !INTERFACE: subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) - use ColumnType , only : col + use ColumnType , only : col_pp use clm_varctl , only : iulog use clm_varpar , only : ndecomp_pools, nlevdecomp_full @@ -2935,61 +2903,59 @@ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) !------------------------------------------------------------------------------------------ ! associate ( & - cgridcell => col%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 + 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__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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 + do fc = 1, filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = cgridcell(c) + g = col_pp%gridcell(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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. #else gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif + 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 do j = 1, clm_pf_idata%nzclm_mapped cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based @@ -3032,16 +2998,16 @@ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) 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__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) end associate end subroutine get_clm_bgc_conc @@ -3132,19 +3098,19 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) call VecGetArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%kscalar_decomp_c_clmp, kscalar_decomp_c_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) ! Initialize to ZERO @@ -3160,14 +3126,17 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = cgridcell(c) + g = col_pp%gridcell(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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. #else gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif do j = 1, clm_pf_idata%nzclm_mapped @@ -3255,30 +3224,30 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) 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__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%kscalar_decomp_c_clmp, kscalar_decomp_c_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) end associate end subroutine get_clm_bgc_rate - - !==================================================================================================== ! ! ! Subroutines to UPDATE PFLOTRAN evolving variables to CLM ! ! ! !==================================================================================================== +#ifdef PF_THMODE + !----------------------------------------------------------------------------- ! ! !IROUTINE: update_soil_moisture_pf2clm ! @@ -3289,7 +3258,7 @@ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifil ! ! ! !USES: - use ColumnType , only : col + use ColumnType , only : col_pp use clm_varcon , only : denh2o, denice use clm_varctl , only : pf_frzmode use clm_varpar , only : nlevgrnd @@ -3322,40 +3291,39 @@ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifil !EOP !----------------------------------------------------------------------- associate ( & - cgridcell => col%gridcell , & ! column's gridcell - dz => col%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] + cgridcell => col_pp%gridcell , & ! column's gridcell + dz => clm_interface_data%dz , & ! layer thickness depth (m) + watsat => clm_interface_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd) + soilpsi => clm_interface_data%soilpsi_col , & ! soil water matric potential in each soil layer (MPa) + h2osoi_liq => clm_interface_data%h2osoi_liq_col, & ! liquid water (kg/m2) + h2osoi_ice => clm_interface_data%h2osoi_ice_col, & ! ice lens (kg/m2) + h2osoi_vol => clm_interface_data%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__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%effporosity_clms, effporo_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%soilpsi_clms, soilpsi_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) if (pf_frzmode) then call VecGetArrayReadF90(clm_pf_idata%soilisat_clms, sat_ice_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. #else gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif do j = 1, nlevgrnd @@ -3403,14 +3371,14 @@ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifil enddo call VecRestoreArrayReadF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%effporosity_clms, effporo_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%soilpsi_clms, soilpsi_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) if (pf_frzmode) then call VecRestoreArrayReadF90(clm_pf_idata%soilisat_clms, sat_ice_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) endif end associate @@ -3457,8 +3425,8 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i !EOP !----------------------------------------------------------------------- associate ( & - cgridcell => col%gridcell , & ! column's gridcell - z => col%z , & ! [real(r8) (:,:) ] layer depth (m) + 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) @@ -3466,20 +3434,21 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i ! call VecGetArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) - ! 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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. #else gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif do j = 1, nlevgrnd @@ -3504,7 +3473,7 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i enddo call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) ! define frost table as first frozen layer with unfrozen layer above it @@ -3572,12 +3541,12 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) 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 + !character(len=32) :: subname = 'update_bcflow_pf2clm' ! subroutine name !----------------------------------------------------------------------- associate(& - cgridcell => col%gridcell , & ! gridcell index of column + 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) @@ -3598,27 +3567,29 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) ! from PF==>CLM call VecGetArrayReadF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) + + do fc = 1, filters(ifilter)%num_soilc - ! operating via 'filters' - gcount = -1 - do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = cgridcell(c) + g = col_pp%gridcell(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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. #else gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif ! the following was actually duplicated from 'get_clm_bcwflx' to calculate total water evap from 'qflx_topsoil' @@ -3646,13 +3617,13 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) call VecRestoreArrayReadF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) end associate end subroutine update_bcflow_pf2clm @@ -3735,7 +3706,7 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) 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_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 , & @@ -3754,59 +3725,61 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) ! 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__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_clms, decomp_npools_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%accextrno3_vr_clms, accextrno3_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) else call VecGetArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) else call VecGetArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) else call VecGetArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) endif - ! operating via 'filters' - gcount = -1 - do fc = 1,filters(ifilter)%num_soilc + ! soil C/N pool increments, and actual plant N uptake, gross N mineralization and immobilization + do fc = 1,filters(ifilter)%num_soilc ! only operating on soil column, which then back to CLM-CN c = filters(ifilter)%soilc(fc) - g = cgridcell(c) + g = col_pp%gridcell(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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. #else - gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + gcount = g - bounds%begg ! 0-based + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif do j = 1, nlevdecomp_full @@ -3827,7 +3800,7 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) 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 ) !!/dtime !!wgs: decomp_cpools_delta_vr=> clm_bgc_data%decomp_cpools_sourcesink_col + * clm_pf_idata%C_molecular_weight ) !!/dtime !!wgs: decomp_cpools_delta_vr=> clm_interface_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) & @@ -3923,44 +3896,44 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) call VecRestoreArrayReadF90(clm_pf_idata%decomp_cpools_vr_clms, decomp_cpools_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%decomp_npools_vr_clms, decomp_npools_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%accextrno3_vr_clms, accextrno3_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) if(clm_pf_idata%ispec_nmin>0) then call VecRestoreArrayReadF90(clm_pf_idata%acctotnmin_vr_clms, accnmin_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) else call VecRestoreArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) else call VecRestoreArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) else call VecRestoreArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) endif ! update bgc gas losses @@ -4014,7 +3987,7 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil 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) + integer :: lair_barrier(1:filters(ifilter)%num_soilc) ! 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 @@ -4068,83 +4041,83 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil ! 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__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%gn2_vr_clms, gn2_vr_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%gn2o_vr_clms, gn2o_vr_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%gco2_vr_clmp, gco2_vr_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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__) + CHKERRQ(ierr) else call VecGetArrayReadF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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' + CHKERRQ(ierr) ! 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 + CHKERRQ(ierr) ! 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' + CHKERRQ(ierr) ! 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' + CHKERRQ(ierr) ! 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' + CHKERRQ(ierr) ! 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' + CHKERRQ(ierr)! 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' + CHKERRQ(ierr)! 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__) + 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) - - ! operating via 'filters' - gcount = -1 do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = cgridcell(c) + g = col_pp%gridcell(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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. #else - gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + gcount = g - bounds%begg ! 0-based + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #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 + if((frac_sno(c)+ frac_h2osfc(c))>=0.90_r8) then lair_barrier(c) = 0 endif @@ -4270,58 +4243,58 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil enddo !! do fc = 1,filters(ifilter)%num_soilc call VecRestoreArrayReadF90(clm_pf_idata%gco2_vr_clms, gco2_vr_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%gn2_vr_clms, gn2_vr_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%gn2o_vr_clms, gn2o_vr_clms_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%gco2_vr_clmp, gco2_vr_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) if(clm_pf_idata%ispec_hrimm>0) then call VecRestoreArrayReadF90(clm_pf_idata%acctothr_vr_clms, acchr_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) else call VecRestoreArrayReadF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) endif call VecRestoreArrayReadF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) if (pf_tmode) then call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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 + CHKERRQ(ierr) ! 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__) + CHKERRQ(ierr) 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' + CHKERRQ(ierr) ! 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' + CHKERRQ(ierr) ! 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' + CHKERRQ(ierr)! 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' + CHKERRQ(ierr)! 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__) + CHKERRQ(ierr) ! need to reset the PF's internal gas concentration (CLM ==> PF) call pflotranModelUpdateAqGasesfromCLM(pflotran_m) @@ -4381,35 +4354,36 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter 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) + 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__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%f_no3_subsurf_clms, f_no3_subsurf_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%f_nh4_subbase_clms, f_nh4_subbase_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecGetArrayReadF90(clm_pf_idata%f_no3_subbase_clms, f_no3_subbase_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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) + g = col_pp%gridcell(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 + gcount = c - bounds%begc ! 0-based + gcount = gcount + filters_colcount_beg(ifilter) + ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, + ! when assigning values from 'filters(nc)%soilc(fc)'. + ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. #else - gcount = g - bounds%begg ! 0-based - if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering + gcount = g - bounds%begg ! 0-based + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid #endif ! add actual BC mass fluxes ( in gN/m2/s) from PFLOTRAN @@ -4435,59 +4409,17 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter 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__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%f_no3_subsurf_clms, f_no3_subsurf_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%f_nh4_subbase_clms, f_nh4_subbase_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) call VecRestoreArrayReadF90(clm_pf_idata%f_no3_subbase_clms, f_no3_subbase_clm_loc, ierr) - call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) + CHKERRQ(ierr) 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) From 52dfa86fb9bc0c02193da17a6d3ed5bc6c383aad Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Fri, 9 Jun 2017 15:17:34 -0400 Subject: [PATCH 08/35] Migrating CLM-PFLOTRAN TH-MODE - Step 3. Hydrology coupling. --- .../src/biogeophys/HydrologyNoDrainageMod.F90 | 69 +- .../clm/src/biogeophys/SoilHydrologyMod.F90 | 6 +- components/clm/src/main/clm_driver.F90 | 18 +- .../clm/src/main/clm_interface_funcsMod.F90 | 160 ++- .../src/main/clm_interface_pflotranMod.F90 | 949 ++++++++++-------- .../clm/src/main/clm_interface_thType.F90 | 17 +- components/clm/src/main/filterMod.F90 | 12 + 7 files changed, 764 insertions(+), 467 deletions(-) diff --git a/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90 b/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90 index e5abe8ca86c0..3b8552a9fd1d 100644 --- a/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90 +++ b/components/clm/src/biogeophys/HydrologyNoDrainageMod.F90 @@ -34,6 +34,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, & @@ -62,7 +63,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 @@ -86,6 +87,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 @@ -188,8 +191,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, & @@ -199,9 +200,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 pre_diagnose_soilcol_water_flux(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, & @@ -223,9 +239,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 diagnose_advect_water_flux(bounds, num_hydrologyc, filter_hydrologyc, num_urbanc, filter_urbanc, & @@ -243,15 +275,31 @@ 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 call calc_dew_sub_flux(bounds, num_hydrologyc, filter_hydrologyc, & waterstate_vars, waterflux_vars, betrtracer_vars, tracerflux_vars, tracerstate_vars) - endif + endif + ! Natural compaction and metamorphosis. call SnowCompaction(bounds, num_snowc, filter_snowc, & temperature_vars, waterstate_vars) @@ -413,7 +461,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/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index f036339fda8f..62287d1edbed 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -650,6 +650,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, & @@ -990,7 +991,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) + + 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, & @@ -998,6 +1012,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) + end if + call t_stopf('hydro2 drainage') if (use_betr) then diff --git a/components/clm/src/main/clm_interface_funcsMod.F90 b/components/clm/src/main/clm_interface_funcsMod.F90 index 627f7c5a9f45..93f55e533e02 100644 --- a/components/clm/src/main/clm_interface_funcsMod.F90 +++ b/components/clm/src/main/clm_interface_funcsMod.F90 @@ -135,8 +135,9 @@ subroutine get_clm_data(clm_idata, & bounds, num_soilc, filter_soilc, & num_soilp, filter_soilp, & atm2lnd_vars, soilstate_vars, & - waterstate_vars, temperature_vars, cnstate_vars, & - carbonflux_vars, carbonstate_vars, & + waterstate_vars, waterflux_vars, & + temperature_vars, energyflux_vars, & + cnstate_vars, carbonflux_vars, carbonstate_vars, & nitrogenflux_vars, nitrogenstate_vars, & phosphorusflux_vars, phosphorusstate_vars, & ch4_vars & @@ -151,9 +152,12 @@ subroutine get_clm_data(clm_idata, & 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(in) :: waterstate_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(cnstate_type) , intent(in) :: cnstate_vars type(carbonflux_type) , intent(in) :: carbonflux_vars @@ -166,32 +170,46 @@ subroutine get_clm_data(clm_idata, & 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" + !----------------------------------------------------------------------- + + associate ( & + clm_idata_th => clm_idata%th, & + clm_idata_bgc => clm_idata%bgc & + ) call get_clm_soil_property(clm_idata, & bounds, num_soilc, filter_soilc, & soilstate_vars, cnstate_vars) - call get_clm_soil_th_state(clm_idata%th, & + call get_clm_soil_th_state(clm_idata_th, & bounds, num_soilc, filter_soilc, & atm2lnd_vars, soilstate_vars, & waterstate_vars, temperature_vars) - call get_clm_bgc_state(clm_idata%bgc, & + call get_clm_soil_th_flux(clm_idata_th, & + bounds, num_soilc, filter_soilc, & + waterflux_vars, energyflux_vars) + + call get_clm_bgc_state(clm_idata_bgc, & bounds, num_soilc, filter_soilc, & atm2lnd_vars, soilstate_vars, & carbonstate_vars, nitrogenstate_vars, & phosphorusstate_vars, & ch4_vars) - call get_clm_bgc_flux(clm_idata%bgc, & + call get_clm_bgc_flux(clm_idata_bgc, & bounds, num_soilc, filter_soilc, & cnstate_vars, carbonflux_vars, & nitrogenflux_vars, phosphorusflux_vars, & ch4_vars) + end associate end subroutine get_clm_data !!-------------------------------------------------------------------------------------- @@ -335,7 +353,7 @@ subroutine get_clm_soil_th_state(clm_idata_th, & type(clm_interface_th_datatype) , intent(inout) :: clm_idata_th ! !LOCAL VARIABLES: - integer :: fc, c ! indices + integer :: fc, c, j ! indices !EOP !----------------------------------------------------------------------- @@ -356,21 +374,32 @@ subroutine get_clm_soil_th_state(clm_idata_th, & forc_pbot => atm2lnd_vars%forc_pbot_not_downscaled_grc & ! atmospheric pressure (Pa) ) + !-------------------------------------------------------------------------------------- ! !! grid: - clm_idata_th%forc_pbot_not_downscaled_grc(:) = forc_pbot(:) + clm_idata_th%forc_pbot_grc = forc_pbot do fc = 1,num_soilc c = filter_soilc(fc) - clm_idata_th%soilpsi_col(c,:) = soilpsi(c,:) + clm_idata_th%frac_sno_eff_col(c) = frac_sno_eff(c) + clm_idata_th%frac_h2osfc_col(c) = frac_h2osfc(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_idata_th%h2osoi_vol_col(c,:) = h2osoi_vol(c,:) - clm_idata_th%h2osoi_liq_col(c,:) = h2osoi_liq(c,:) - clm_idata_th%h2osoi_ice_col(c,:) = h2osoi_ice(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_idata_th%t_soisno_col(c,:) = t_soisno(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 end do @@ -378,6 +407,89 @@ subroutine get_clm_soil_th_state(clm_idata_th, & end subroutine get_clm_soil_th_state !!-------------------------------------------------------------------------------------- +!!-------------------------------------------------------------------------------------- + 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 + + + ! !ARGUMENTS: + implicit none + + 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 + + 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_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 + + end associate + end subroutine get_clm_soil_th_flux +!!-------------------------------------------------------------------------------------- + + !!-------------------------------------------------------------------------------------- subroutine get_clm_bgc_state(clm_bgc_data, & bounds, num_soilc, filter_soilc, & @@ -632,7 +744,7 @@ end subroutine get_clm_bgc_flux !!-------------------------------------------------------------------------------------- subroutine update_soil_moisture(clm_idata_th, & bounds, num_soilc, filter_soilc, & - waterstate_vars) + soilstate_vars, waterstate_vars) ! ! !DESCRIPTION: @@ -646,7 +758,9 @@ subroutine update_soil_moisture(clm_idata_th, & 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(inout) :: soilstate_vars type(waterstate_type), intent(inout) :: waterstate_vars + type(clm_interface_th_datatype), intent(in) :: clm_idata_th ! !LOCAL VARIABLES: @@ -655,6 +769,8 @@ subroutine update_soil_moisture(clm_idata_th, & !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 & @@ -662,9 +778,12 @@ subroutine update_soil_moisture(clm_idata_th, & do fc = 1,num_soilc c = filter_soilc(fc) - 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,:) + + 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 @@ -713,7 +832,7 @@ subroutine update_th_data_pf2clm(clm_idata_th, & bounds, num_soilc, filter_soilc, & waterstate_vars, waterflux_vars, & temperature_vars, energyflux_vars, & - soilhydrology_vars) + soilstate_vars, soilhydrology_vars) !! USES use clm_varctl , only : use_pflotran, pf_tmode, pf_hmode @@ -727,6 +846,7 @@ subroutine update_th_data_pf2clm(clm_idata_th, & 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 @@ -745,7 +865,7 @@ subroutine update_th_data_pf2clm(clm_idata_th, & if (pf_hmode) then call update_soil_moisture(clm_idata_th, & bounds, num_soilc, filter_soilc, & - waterstate_vars) + soilstate_vars, waterstate_vars) end if end subroutine update_th_data_pf2clm diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 23f500ba7d00..149f63e43e96 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -70,11 +70,8 @@ module clm_interface_pflotranMod #ifdef CLM_PFLOTRAN type(pflotran_model_type), pointer, public :: pflotran_m -#ifdef COLUMN_MODE - integer, pointer, public :: filters_colcount_beg(:) ! dim: column block's 1st col on filters(1:nc) -#else - logical, pointer, public :: mapped_gcount_skip(:) ! dim: inactive grid mask in bounds%begg:endg -#endif + 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 = '' @@ -262,17 +259,16 @@ end subroutine pflotran_not_available !------------------------------------------------------------------------------------------! !----------------------------------------------------------------------------- - subroutine clm_pf_interface_init(bounds, filters) + subroutine clm_pf_interface_init(bounds) implicit none type(bounds_type), intent(in) :: bounds ! bounds - type(clumpfilter), intent(in) :: filters(:) ! filters character(len=256) :: subname = "clm_pf_interface_init()" #ifdef CLM_PFLOTRAN - call interface_init(bounds, filters) + call interface_init(bounds) #else call pflotran_not_available(subname) #endif @@ -372,7 +368,7 @@ end subroutine clm_pf_finalize ! !IROUTINE: interface_init ! ! !INTERFACE: - subroutine interface_init(bounds, filters) + subroutine interface_init(bounds) ! ! !DESCRIPTION: ! initialize the pflotran iterface @@ -385,21 +381,18 @@ subroutine interface_init(bounds, filters) 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 !!lon0,lat0 + use domainMod , only : ldomain, lon1d, lat1d - use clm_time_manager, only : get_nstep !!nsstep, nestep + 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 !! = pflotran_surfaceflow - use filterMod , only : allocFilters + pf_surfaceflow use CNDecompCascadeConType , only : decomp_cascade_con -! use abortutils , only : endrun - ! pflotran use Option_module, only : printErrMsg @@ -418,7 +411,6 @@ subroutine interface_init(bounds, filters) #include "petsc/finclude/petscsys.h" #include "petsc/finclude/petscvec.h" #include "petsc/finclude/petscvec.h90" -! #include "finclude/petscviewer.h" ! ! !REVISION HISTORY: @@ -430,15 +422,13 @@ subroutine interface_init(bounds, filters) ! LOCAL VARAIBLES: type(bounds_type), intent(in) :: bounds ! bounds - type(clumpfilter), intent(in) :: filters(:) ! filters integer :: global_numg ! total number of gridcells across all processors (active) integer :: global_numc ! total number of columns across all processors (active) - integer :: global_nump ! total number of pfts across all processors (active) integer :: g,l,c, pid ! indices - integer :: nc, nclumps, total_soilc, start_mappedgid, nx, ny, npes_pf - integer, pointer :: total_soilc_all(:) ! dim: npes - integer, pointer :: mapped_gid(:) ! dim: num_soilc + 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 @@ -466,6 +456,7 @@ subroutine interface_init(bounds, filters) 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 + ) @@ -475,134 +466,148 @@ subroutine interface_init(bounds, filters) lat0 = ldomain%lat0 !!wgs:end---------------------------------------------------------------- - ! (0) determines Total grids/columns to be mapped between CLM and PFLOTRAN + ! (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 - nclumps = get_proc_clumps() - do nc=1,nclumps ! current process - total_soilc = total_soilc + filters(nc)%num_soilc + + ! 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 + ! 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 - ! and must be in order, corresponding to 'bounds%begc:endc' filtered by 'filter%soilc' - ! bounds: begc, begc+1, begc+2, ..., endc ! note: must skip those not 'ltype(l)==istsoil' or 'ltype(l)==istcrop' - ! filters: (1)%soilc(:), (2)%soilc(:), ..., (nclumps)%soilc(:) - ! columnid: start_columnid(1), start_colunmid+1, ..., start_columnid+total_soilc-1 - - allocate (total_soilc_all(0:npes-1)) + allocate (total_soilc_pes(0:npes-1)) call mpi_gather(total_soilc, 1, MPI_INTEGER, & - total_soilc_all, 1, MPI_INTEGER, 0, mpicom, ierr) - call mpi_bcast(total_soilc_all, npes, MPI_INTEGER, 0, mpicom, ierr) + 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)) - ! corresponding starting no. of re-ordered filtered-columns (zero-based) - ! will be used to skip block(s) of columns in 'bounds%begc:endc' for 'filters(nc)%soilc' in the interface data vec. - allocate(filters_colcount_beg(1:nclumps)) - start_mappedgid = 0 - colcount = 0 do pid=0, npes-1 if (pid==iam) then - do nc=1, nclumps - filters_colcount_beg(nc) = 0 - do c=1,filters(nc)%num_soilc - colcount = colcount + 1 - mapped_gid(colcount) = start_mappedgid + c - - enddo - if (nc>1) filters_colcount_beg(nc) = colcount - start_mappedgid = start_mappedgid + filters(nc)%num_soilc ! skip by fileter's stride, when 'pid==iam' + 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 - start_mappedgid = start_mappedgid + total_soilc_all(pid) ! skip by pes's total soil column, until 'pid==iam' and exit do-loop end do + #else - ! assumption that only 1 natural/cropped soil-column allowed per grid cell NOW - gcolumns(:) = 0 !grc%ncolumns NOT assigned values at all + ! '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' + !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 - ! count active columns for a gridcell - gcount = g - bounds%begg + 1 - if (cactive(c)) then + 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 or no ACTIVE 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' + 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.") - - endif - enddo + 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) - ! counting active gridcells in current pes - total_soilc = 0 - do l=bounds%begl, bounds%endl - if(ltype(l)==istsoil .or. ltype(l)==istcrop) then - total_soilc = total_soilc + 1 - endif + endif enddo call mpi_barrier(mpicom, ierr) ! needs all processes done first - ! sum of all active gridcells across all processors - call mpi_allreduce(total_soilc, global_numc, 1, MPI_INTEGER,MPI_SUM,mpicom,ierr) + ! 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) - ! collect info for all pes - allocate (total_soilc_all(0:npes-1)) - call mpi_gather(total_soilc, 1, MPI_INTEGER, & - total_soilc_all, 1, MPI_INTEGER, 0, mpicom, ierr) - call mpi_bcast(total_soilc_all, npes, MPI_INTEGER, 0, 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_soilc)) + 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)) - - gcount = 0 mapped_gcount_skip(:) = .true. - do l=bounds%begl, bounds%endl - g = lgridcell(l) - if(ltype(l)==istsoil .or. ltype(l)==istcrop) then - gcount = gcount + 1 - mapped_gid(gcount) = grc%gindex(g) ! this is the globally grid-index - mapped_gcount_skip(g-bounds%begg+1) = .false. - endif + ! 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%gindex(g) ! this is the globally grid-index, i.e. 'an' in its original calculation + + mapped_gcount_skip(gcount) = .false. + endif end do @@ -620,7 +625,7 @@ subroutine interface_init(bounds, filters) 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_numc,' %%' + write(iulog,*) '%% Total grids with active soil columns: ',global_numg,' %%' #endif write(iulog,*) '%% %%' write(iulog,*) '%%--------------------------------------------------------%%' @@ -668,12 +673,12 @@ subroutine interface_init(bounds, filters) ! do pid=0, npes-1 - clm_pf_idata%clm_lx(pid+1) = total_soilc_all(pid) + 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_all) + deallocate(total_soilc_pes) #else clm_pf_idata%nxclm_mapped = ldomain%ni ! longitudial @@ -728,9 +733,6 @@ subroutine interface_init(bounds, filters) end do clm_pf_idata%clm_lz = clm_pf_idata%nzclm_mapped - ! clean-ups - deallocate(total_soilc_all) - #endif if (masterproc) then @@ -917,15 +919,15 @@ subroutine interface_init(bounds, filters) #else !grid-wised for mapping. - clm_all_npts = total_soilc*clm_pf_idata%nzclm_mapped ! 'total_soilc' was only counted with active-column grid - clm_top_npts = total_soilc - clm_bot_npts = total_soilc + 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_soilc + do gcount = 1, total_grid gid = mapped_gid(gcount) @@ -966,29 +968,35 @@ subroutine interface_init(bounds, filters) clm_pf_idata%ngpf_srf = 0 ! Initialize maps for transferring data between CLM and PFLOTRAN. - if(pflotran_m%map_clm_sub_to_pf_sub%id == CLM_3DSUB_TO_PF_3DSUB) then + 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(pflotran_m%map_pf_sub_to_clm_sub%id == PF_3DSUB_TO_CLM_3DSUB) then + 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(pflotran_m%map_clm_2dtop_to_pf_2dtop%id == CLM_2DTOP_TO_PF_2DTOP) then + 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(pflotran_m%map_pf_2dtop_to_clm_2dtop%id == PF_2DTOP_TO_CLM_2DTOP) then + 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(pflotran_m%map_clm_2dbot_to_pf_2dbot%id == CLM_2DBOT_TO_PF_2DBOT) then + 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(pflotran_m%map_pf_2dbot_to_clm_2dbot%id == PF_2DBOT_TO_CLM_2DBOT) then + 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 @@ -1300,11 +1308,7 @@ subroutine pflotran_finalize() call pflotranModelDestroy(pflotran_m) endif -#ifdef COLUMN_MODE - deallocate(filters_colcount_beg) -#else deallocate(mapped_gcount_skip) -#endif end subroutine pflotran_finalize @@ -1332,6 +1336,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) use clm_varpar , only : nlevgrnd use domainMod , only : ldomain use landunit_varcon , only : istsoil, istcrop + use clm_varcon , only : re ! @@ -1355,12 +1360,14 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! LOCAL VARAIBLES: integer :: g,l,c,j ! indices - integer :: gcount, cellcount ! gcount: 0-based, cellcount: 1-based + 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) -#ifndef COLUMN_MODE +#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 @@ -1407,23 +1414,27 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) 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) + ) -#ifndef COLUMN_MODE +#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%begg + 1 + 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 + xwtgcell_c(gcount) = c ! column index with max. weight in a gridcell end if end if @@ -1500,25 +1511,25 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) !!!! call VecGetArrayF90(clm_pf_idata%cellid_clmp, cellid_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%zisoil_clmp, zisoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%dxsoil_clmp, dxsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%dysoil_clmp, dysoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%dzsoil_clmp, dzsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%area_top_face_clmp, toparea_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%xsoil_clmp, xsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%ysoil_clmp, ysoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%zsoil_clmp, zsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) zisoil_clm_loc(:) = 0._r8 dxsoil_clm_loc(:) = 0._r8 @@ -1530,16 +1541,21 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ysoil_clm_loc(:) = 0._r8 zsoil_clm_loc(:) = 0._r8 - do j = 1, clm_pf_idata%nzclm_mapped - if (j <= nlevgrnd) then +#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 -#ifdef COLUMN_MODE - gcount = 0 - do c = bounds%begc, bounds%endc - g = cgridcell(c) - l = clandunit(c) + do j = 1, clm_pf_idata%nzclm_mapped + if (j <= nlevgrnd) then ! note that filters%soilc includes 'istsoil' and 'istcrop' ! (TODO: checking col_pp%itype and lun%itype - appears not match with each other, and col_pp%itype IS messy) @@ -1551,11 +1567,11 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ysoil_clm_loc(cellcount) = latc(g) ! dzsoil_clm_loc(cellcount) = dz(c, j) ! cell vertical thickness (m) - zisoil_clm_loc(cellcount) = -zi(c, j) + lelev(g) ! cell-node elevation (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) = cwtgcell(c) * ldomain%frac(g) * larea(g) * 1.e6_r8 ! m^2 + 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 @@ -1566,25 +1582,37 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) 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 & - * cwtgcell(c) * ldomain%frac(g) + * 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 - * cwtgcell(c) * ldomain%frac(g) + * 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 c = bounds%begc, bounds%endc + 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 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%gindex(g)-1)*clm_pf_idata%nzclm_mapped + j ! 1-based @@ -1596,42 +1624,42 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! 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) + lelev(g) ! cell-node elevation (m) + 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 - enddo ! do g = bounds%begg, bounds%endg -#endif + else + call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // & + " 'clm_varpar%nlevgrnd'. Please check") - 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 - enddo +#endif call VecRestoreArrayF90(clm_pf_idata%cellid_clmp, cellid_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%zisoil_clmp, zisoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%dxsoil_clmp, dxsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%dysoil_clmp, dysoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%dzsoil_clmp, dzsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%area_top_face_clmp, toparea_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%xsoil_clmp, xsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%ysoil_clmp, ysoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%zsoil_clmp, zsoil_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! Set CLM soil domain onto PFLOTRAN grid call pflotranModelSetSoilDimension(pflotran_m) @@ -1803,31 +1831,30 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) call VecGetArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%tkwet_clmp, tkwet_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%tkdry_clmp, tkdry_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%tkfrz_clmp, tkfrz_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%hcvsol_clmp, hcvsol_clm_loc, ierr) - CHKERRQ(ierr) - + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) hksat_x_clm_loc(:) = 0._r8 hksat_y_clm_loc(:) = 0._r8 @@ -1843,26 +1870,29 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) tkfrz_clm_loc(:) = 0._r8 hcvsol_clm_loc(:) = 0._r8 - gcount = 0 + 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) then + if ( (ltype(l)==istsoil .or. ltype(l)==istcrop) .and. & + (col%active(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 ! 1-based column (fake grid) count + gcount = gcount + 1 ! 0-based column (fake grid) count wtgcount = 1._r8 #else - gcount = g - bounds%begg + 1 ! 1-based + 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 - 1) *clm_pf_idata%nzclm_mapped + j ! 1-based + 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)) @@ -1908,31 +1938,33 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) enddo ! do c = bounds%begc, bounds%endc call VecRestoreArrayF90(clm_pf_idata%hksat_x_clmp, hksat_x_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%hksat_y_clmp, hksat_y_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%hksat_z_clmp, hksat_z_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%sucsat_clmp, sucsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%watsat_clmp, watsat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%bsw_clmp, bsw_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%watfc_clmp, watfc_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%bulkdensity_dry_clmp, bulkdensity_dry_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%tkdry_clmp, tkdry_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%tkfrz_clmp, tkfrz_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%hcvsol_clmp, hcvsol_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! Set CLM soil properties onto PFLOTRAN grid call pflotranModelSetSoilProp(pflotran_m) @@ -2030,38 +2062,36 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, nstep = get_nstep() call VecGetArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%h2osoi_vol_clmp, soilvwc_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%t_scalar_clmp, t_scalar_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%w_scalar_clmp, w_scalar_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%o_scalar_clmp, o_scalar_clmp_loc, ierr) - CHKERRQ(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 - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. + 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 + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering #endif do j = 1, clm_pf_idata%nzclm_mapped @@ -2107,15 +2137,15 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, endif endif !!if(.not.pf_frzmode) - soillsat_clmp_loc(cellcount) = sattmp + 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) + 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) + soilvwc_clmp_loc(cellcount) = h2osoi_vol(c,j) endif !!if (initpfhmode) then @@ -2134,23 +2164,23 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, enddo !!do fc = 1,filters(ifilter)%num_soilc call VecRestoreArrayF90(clm_pf_idata%press_clmp, soilpress_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilpsi_clmp, soilpsi_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soillsat_clmp, soillsat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilt_clmp, soilt_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%h2osoi_vol_clmp, soilvwc_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%t_scalar_clmp, t_scalar_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%w_scalar_clmp, w_scalar_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%o_scalar_clmp, o_scalar_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) end associate end subroutine get_clm_soil_th @@ -2216,23 +2246,22 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) ! 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 clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(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) + c = filters(ifilter)%soilc(fc) + g = cgridcell(c) #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. + 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 + 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 @@ -2253,9 +2282,9 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) end do call VecRestoreArrayF90(clm_pf_idata%effporosity_clmp, adjporosity_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%soilisat_clmp, soilisat_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) end if @@ -2263,7 +2292,6 @@ subroutine get_clm_iceadj_porosity(clm_interface_data, bounds, filters, ifilter) end subroutine get_clm_iceadj_porosity ! - !----------------------------------------------------------------------------- !BOP @@ -2347,6 +2375,7 @@ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) 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) @@ -2714,6 +2743,7 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) 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) @@ -2854,7 +2884,7 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) end associate end subroutine get_clm_bceflx - ! + !----------------------------------------------------------------------------- ! ! @@ -2903,59 +2933,61 @@ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) !------------------------------------------------------------------------------------------ ! associate ( & - 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 + cgridcell => col%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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(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 - do fc = 1, filters(ifilter)%num_soilc + ! + 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 = col_pp%gridcell(c) #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. + 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 + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering #endif - 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 do j = 1, clm_pf_idata%nzclm_mapped cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based @@ -2998,16 +3030,16 @@ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) enddo ! do fc = 1, num_soilc call VecRestoreArrayF90(clm_pf_idata%decomp_cpools_vr_clmp, decomp_cpools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%decomp_npools_vr_clmp, decomp_npools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%smin_no3_vr_clmp, smin_no3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%smin_nh4_vr_clmp, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%smin_nh4sorb_vr_clmp, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) end associate end subroutine get_clm_bgc_conc @@ -3098,19 +3130,19 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) call VecGetArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%kscalar_decomp_c_clmp, kscalar_decomp_c_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! Initialize to ZERO @@ -3129,14 +3161,11 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) g = col_pp%gridcell(c) #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clmp' vector. + 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 + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering #endif do j = 1, clm_pf_idata%nzclm_mapped @@ -3224,30 +3253,30 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) enddo ! do fc=1,numsoic call VecRestoreArrayF90(clm_pf_idata%rate_decomp_c_clmp, rate_decomp_c_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_decomp_n_clmp, rate_decomp_n_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%kscalar_decomp_c_clmp, kscalar_decomp_c_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_plantndemand_clmp, rate_plantndemand_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_smin_no3_clmp, rate_smin_no3_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%rate_smin_nh4_clmp, rate_smin_nh4_clm_loc, ierr) - CHKERRQ(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 ! ! ! !==================================================================================================== -#ifdef PF_THMODE - !----------------------------------------------------------------------------- ! ! !IROUTINE: update_soil_moisture_pf2clm ! @@ -3301,29 +3330,28 @@ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifil ) ! call VecGetArrayReadF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%effporosity_clms, effporo_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%soilpsi_clms, soilpsi_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(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 - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. + 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 + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering #endif do j = 1, nlevgrnd @@ -3371,14 +3399,14 @@ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifil enddo call VecRestoreArrayReadF90(clm_pf_idata%soillsat_clms, sat_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%effporosity_clms, effporo_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%soilpsi_clms, soilpsi_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) endif end associate @@ -3434,21 +3462,20 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i ! call VecGetArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr) - CHKERRQ(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 - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. + 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 + if (mapped_gcount_skip(gcount+1)) cycle ! skip inactive grid, but not numbering #endif do j = 1, nlevgrnd @@ -3473,7 +3500,29 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i enddo call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clms_loc, ierr) - CHKERRQ(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 + ! define frost table as first frozen layer with unfrozen layer above it @@ -3541,7 +3590,7 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) 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 + character(len=32) :: subname = 'update_bcflow_pf2clm' ! subroutine name !----------------------------------------------------------------------- @@ -3567,29 +3616,28 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) ! from PF==>CLM call VecGetArrayReadF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr) - CHKERRQ(ierr) - - do fc = 1, filters(ifilter)%num_soilc + 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 = col_pp%gridcell(c) + g = cgridcell%gridcell(c) + #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. + 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 + 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' @@ -3617,13 +3665,13 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) call VecRestoreArrayReadF90(clm_pf_idata%area_top_face_clms, area_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%qinfl_subsurf_clms,qinfl_subsurf_clm_loc,ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%qsurf_subsurf_clms,qsurf_subsurf_clm_loc,ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%qflux_subbase_clms,qflux_subbase_clm_loc,ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) end associate end subroutine update_bcflow_pf2clm @@ -3706,7 +3754,7 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) 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_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 , & @@ -3725,61 +3773,59 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) ! clm-pf interface data updated call VecGetArrayReadF90(clm_pf_idata%decomp_cpools_vr_clms, decomp_cpools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%decomp_npools_vr_clms, decomp_npools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%accextrno3_vr_clms, accextrno3_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecGetArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecGetArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecGetArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) endif - ! soil C/N pool increments, and actual plant N uptake, gross N mineralization and immobilization - do fc = 1,filters(ifilter)%num_soilc ! only operating on soil column, which then back to CLM-CN + ! operating via 'filters' + gcount = -1 + do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = col_pp%gridcell(c) + g = cgridcell(c) #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. + 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 + 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 @@ -3800,7 +3846,7 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) 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 ) !!/dtime !!wgs: decomp_cpools_delta_vr=> clm_interface_data%decomp_cpools_sourcesink_col + * clm_pf_idata%C_molecular_weight ) !!/dtime !!wgs: 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) & @@ -3896,44 +3942,44 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) call VecRestoreArrayReadF90(clm_pf_idata%decomp_cpools_vr_clms, decomp_cpools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%decomp_npools_vr_clms, decomp_npools_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%smin_no3_vr_clms, smin_no3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%smin_nh4_vr_clms, smin_nh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%smin_nh4sorb_vr_clms, smin_nh4sorb_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%accextrnh4_vr_clms, accextrnh4_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%accextrno3_vr_clms, accextrno3_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) if(clm_pf_idata%ispec_nmin>0) then call VecRestoreArrayReadF90(clm_pf_idata%acctotnmin_vr_clms, accnmin_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecRestoreArrayReadF90(clm_pf_idata%accnmin_vr_clms, accnmin_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecRestoreArrayReadF90(clm_pf_idata%accnimmp_vr_clms, accnimmp_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecRestoreArrayReadF90(clm_pf_idata%accnimm_vr_clms, accnimm_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) endif ! update bgc gas losses @@ -3987,7 +4033,7 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil 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(1:filters(ifilter)%num_soilc) ! toppest soil layer that little air space for air flow into deep soil (-1: no, 0: ground, >0: soil layer) + 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 @@ -4031,7 +4077,6 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil 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 & ) @@ -4041,83 +4086,83 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil ! 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%gn2_vr_clms, gn2_vr_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%gn2o_vr_clms, gn2o_vr_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%gco2_vr_clmp, gco2_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecGetArrayReadF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr) - CHKERRQ(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) - CHKERRQ(ierr) ! PF evolved 'soilt' + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soilt' else call VecGetArrayReadF90(clm_pf_idata%soilt_clmp, soilt_clm_loc, ierr) - CHKERRQ(ierr) ! CLM evolved 'soilt' - for CLM, MPI vecs and Seq. vecs should be same + 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) - CHKERRQ(ierr) ! PF evolved 'soil ice saturation' + 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) - CHKERRQ(ierr) ! PF evolved 'soil liq. saturation' + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil liq. saturation' call VecGetArrayReadF90(clm_pf_idata%press_clms, soilpress_clm_loc, ierr) - CHKERRQ(ierr) ! PF evolved 'soil liq. saturation' + 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) - CHKERRQ(ierr)! CLM evolved 'soilt liq. saturation' + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)! CLM evolved 'soilt liq. saturation' call VecGetArrayReadF90(clm_pf_idata%press_clmp, soilpress_clm_loc, ierr) - CHKERRQ(ierr)! CLM evolved 'soilt liq. saturation' + 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' - CHKERRQ(ierr) + 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 = col_pp%gridcell(c) + g = cgridcell(c) #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. + 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 + 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(c)+ frac_h2osfc(c))>=0.90_r8) then + if((frac_sno_eff(c)+ frac_h2osfc(c))>=0.95_r8) then lair_barrier(c) = 0 endif @@ -4243,58 +4288,58 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil enddo !! do fc = 1,filters(ifilter)%num_soilc call VecRestoreArrayReadF90(clm_pf_idata%gco2_vr_clms, gco2_vr_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%gn2_vr_clms, gn2_vr_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%gn2o_vr_clms, gn2o_vr_clms_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%gco2_vr_clmp, gco2_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%gn2_vr_clmp, gn2_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayF90(clm_pf_idata%gn2o_vr_clmp, gn2o_vr_clmp_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) if(clm_pf_idata%ispec_hrimm>0) then call VecRestoreArrayReadF90(clm_pf_idata%acctothr_vr_clms, acchr_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecRestoreArrayReadF90(clm_pf_idata%acchr_vr_clms, acchr_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) endif call VecRestoreArrayReadF90(clm_pf_idata%accngasmin_vr_clms, accngasmin_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%accngasnitr_vr_clms, accngasnitr_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%accngasdeni_vr_clms, accngasdeni_vr_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) if (pf_tmode) then call VecRestoreArrayReadF90(clm_pf_idata%soilt_clms, soilt_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) else call VecRestoreArrayReadF90(clm_pf_idata%soilt_clmp, soilt_clm_loc, ierr) - CHKERRQ(ierr) ! for CLM, MPI vecs and Seq. vecs should be same + 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) - CHKERRQ(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) - CHKERRQ(ierr) ! PF evolved 'soil liq. saturation' + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! PF evolved 'soil liq. saturation' call VecRestoreArrayReadF90(clm_pf_idata%press_clms, soilpress_clm_loc, ierr) - CHKERRQ(ierr) ! PF evolved 'soil liq. saturation' + 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) - CHKERRQ(ierr)! CLM evolved 'soil liq. saturation' + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__)! CLM evolved 'soil liq. saturation' call VecRestoreArrayReadF90(clm_pf_idata%press_clmp, soilpress_clm_loc, ierr) - CHKERRQ(ierr)! CLM evolved 'soil liq. saturation' + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) ! need to reset the PF's internal gas concentration (CLM ==> PF) call pflotranModelUpdateAqGasesfromCLM(pflotran_m) @@ -4354,36 +4399,36 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter 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) + 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) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%f_no3_subsurf_clms, f_no3_subsurf_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%f_nh4_subbase_clms, f_nh4_subbase_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecGetArrayReadF90(clm_pf_idata%f_no3_subbase_clms, f_no3_subbase_clm_loc, ierr) - CHKERRQ(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 = col_pp%gridcell(c) + g = cgridcell(c) + #ifdef COLUMN_MODE - gcount = c - bounds%begc ! 0-based - gcount = gcount + filters_colcount_beg(ifilter) - ! this means that skip prior clumps in 'clm_pf_idata%..._clms' vectors, - ! when assigning values from 'filters(nc)%soilc(fc)'. - ! NOTE: if 'nc' greater than 1, 'soilc(fc)' is a segement of '_clms' vector. + 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 + 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 @@ -4409,17 +4454,59 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter enddo !! do fc = 1,filters(ifilter)%num_soilc call VecRestoreArrayReadF90(clm_pf_idata%f_nh4_subsurf_clms, f_nh4_subsurf_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%f_no3_subsurf_clms, f_no3_subsurf_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%f_nh4_subbase_clms, f_nh4_subbase_clm_loc, ierr) - CHKERRQ(ierr) + call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) call VecRestoreArrayReadF90(clm_pf_idata%f_no3_subbase_clms, f_no3_subbase_clm_loc, ierr) - CHKERRQ(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) diff --git a/components/clm/src/main/clm_interface_thType.F90 b/components/clm/src/main/clm_interface_thType.F90 index e435e3f6c5f7..4877d6ad910d 100644 --- a/components/clm/src/main/clm_interface_thType.F90 +++ b/components/clm/src/main/clm_interface_thType.F90 @@ -62,8 +62,14 @@ module clm_interface_thType 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_not_downscaled_grc (:) ! downscaled atm pressure (Pa) + real(r8), pointer :: forc_pbot_grc (:) ! grid atm pressure (Pa) contains procedure , public :: Init @@ -119,6 +125,7 @@ subroutine InitAllocate(this, bounds) ! 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: @@ -151,7 +158,13 @@ subroutine InitAllocate(this, bounds) allocate( this%eflx_rnet_soil_col (begc:endc)) ; this%eflx_rnet_soil_col (:) = ival ! atm2lnd: - allocate(this%forc_pbot_not_downscaled_grc (begg:endg)) ; this%forc_pbot_not_downscaled_grc (:) = ival + 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 !!------------------------------------------------------------------------------------------------- diff --git a/components/clm/src/main/filterMod.F90 b/components/clm/src/main/filterMod.F90 index 859bd884196d..e6784ecadce0 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%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 From f3ec3435c44d449970810446d8a772f70d8ec3f3 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Wed, 14 Jun 2017 16:06:45 -0400 Subject: [PATCH 09/35] Migrating CLM-PFLOTRAN TH-MODE - Step 4. Manually edit/clean-up codes. By this commit, BGC coupling runs correctly with hyrolog-coupled codes. --- components/clm/src/biogeochem/CNDecompMod.F90 | 158 ++++++++---------- .../src/main/clm_interface_pflotranMod.F90 | 8 - 2 files changed, 74 insertions(+), 92 deletions(-) diff --git a/components/clm/src/biogeochem/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90 index ed0ef51b8246..fd1754c1b785 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 @@ -721,104 +721,94 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so dt = real( get_step_size(), 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) - 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) + ! 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 - 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(c) = 1.0_r8 - end if - 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 do - end if + 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, & + ! 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) - end if !!if(use_clm_interface.and.use_pflotran.and.pf_cmode) + end if !!if(use_clm_interface.and.use_pflotran.and.pf_cmode) !!------------------------------------------------------------------ ! phase-3 Allocation for plants diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 149f63e43e96..2ccf9623f577 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -123,7 +123,6 @@ module clm_interface_pflotranMod private :: update_soil_moisture_pf2clm private :: update_bcflow_pf2clm - #endif contains @@ -1159,10 +1158,8 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) endif -#ifdef PF_THMODE ! (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 @@ -1170,14 +1167,12 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (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 -#endif ! (4) if (pf_cmode) then @@ -1220,7 +1215,6 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (6) update CLM variables from PFLOTRAN -#ifdef PF_THMODE if (pf_hmode) then call pflotranModelGetSaturationFromPF( pflotran_m ) ! hydrological states @@ -1229,7 +1223,6 @@ subroutine pflotran_run_onestep(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 @@ -1240,7 +1233,6 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) call update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, ifilter) endif -#endif if (pf_cmode) then call pflotranModelGetBgcVariablesFromPF( pflotran_m) ! bgc variables From 81af67effed0e5a3fba345e7146ead445fd7c41a Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Wed, 14 Jun 2017 16:15:32 -0400 Subject: [PATCH 10/35] Migrating CLM-PFLOTRAN TH-MODE - Step 4. Manually edit/clean-up codes. By this commit, BGC coupling runs correctly with hyrolog-coupled codes. --- .../clm/src/biogeochem/CNBalanceCheckMod.F90 | 2 +- .../src/biogeochem/CNPrecisionControlMod.F90 | 6 +++--- .../clm/src/main/clm_interface_bgcType.F90 | 1 - components/clm/src/main/controlMod.F90 | 20 ++++++++++--------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 index 65a8f77145ac..ecc5074aa785 100644 --- a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 +++ b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 @@ -291,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) 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/main/clm_interface_bgcType.F90 b/components/clm/src/main/clm_interface_bgcType.F90 index 941e44f257fb..563508fdbcae 100644 --- a/components/clm/src/main/clm_interface_bgcType.F90 +++ b/components/clm/src/main/clm_interface_bgcType.F90 @@ -201,7 +201,6 @@ module clm_interface_bgcType end type clm_interface_bgc_datatype !!------------------------------------------------------------------------------------------------- -!! type(clm_interface_bgc_datatype) , public, target , save :: clm_bgc_data contains diff --git a/components/clm/src/main/controlMod.F90 b/components/clm/src/main/controlMod.F90 index 15110b284636..ba77c0d34751 100644 --- a/components/clm/src/main/controlMod.F90 +++ b/components/clm/src/main/controlMod.F90 @@ -404,18 +404,20 @@ subroutine control_init( ) ! ---------------------------------------------------------------------- !! bgc & pflotran interface if(.not.use_clm_interface) then - use_clm_bgc = .true. + use_clm_bgc = .false. use_pflotran = .false. - end if + else - if (use_clm_bgc) then - 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. + 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 From c29135f6e6762b0db3ccf525c5526d348ad093ee Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Thu, 15 Jun 2017 15:09:20 -0400 Subject: [PATCH 11/35] enable clm_pf_finalize() call. --- components/clm/src/main/clm_driver.F90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index 62287d1edbed..0f6cf4707b5c 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -148,7 +148,7 @@ module clm_driver 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 + use clm_interface_pflotranMod , only : clm_pf_finalize !!---------------------------------------------------------------------------- ! @@ -1366,6 +1366,10 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) end if + if (nstep>=nestep) then + call clm_pf_finalize() + end if + end subroutine clm_drv !----------------------------------------------------------------------- From 6d3dad46b20cbdbddf3f6df39f1fda037bb27449 Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Tue, 20 Jun 2017 10:41:35 -0400 Subject: [PATCH 12/35] missing one 'use_pflotran' exclusion in 'clm_driver.F90'. --- components/clm/src/main/clm_driver.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index 0f6cf4707b5c..f5be01b8f21f 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -1366,7 +1366,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) end if - if (nstep>=nestep) then + if (use_pflotran .and. nstep>=nestep) then call clm_pf_finalize() end if From 1c1750313b3196f355cd44e7d3c90baa590da62a Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Thu, 22 Jun 2017 10:01:17 -0400 Subject: [PATCH 13/35] add an if...endif block to pass BFB lnd-developer tests when pflotran not coupled. --- .../clm/src/biogeochem/CNCarbonFluxType.F90 | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/components/clm/src/biogeochem/CNCarbonFluxType.F90 b/components/clm/src/biogeochem/CNCarbonFluxType.F90 index 5e223a8b0293..e66ddfade90a 100644 --- a/components/clm/src/biogeochem/CNCarbonFluxType.F90 +++ b/components/clm/src/biogeochem/CNCarbonFluxType.F90 @@ -4974,29 +4974,32 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil end if end do - ! add up all vertical transport tendency terms and calculate total som leaching loss as the sum of these - do l = 1, ndecomp_pools - do fc = 1,num_soilc - c = filter_soilc(fc) - this%decomp_cpools_leached_col(c,l) = 0._r8 - end do - do j = 1, nlev + 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) + & - this%decomp_cpools_transport_tendency_col(c,j,l) * dzsoi_decomp(j) + 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 + end if - endif + end if ! debug do fc = 1,num_soilc From 5f37372ec050c5cccba47db3135d118f4a36bd9b Mon Sep 17 00:00:00 2001 From: wanggangsheng Date: Thu, 22 Jun 2017 16:12:07 -0400 Subject: [PATCH 14/35] edit comments on clm_interface --- components/clm/src/main/clm_driver.F90 | 7 ------- components/clm/src/main/clm_interface_bgcType.F90 | 3 ++- components/clm/src/main/clm_interface_dataType.F90 | 3 ++- components/clm/src/main/clm_interface_funcsMod.F90 | 3 ++- components/clm/src/main/clm_interface_thType.F90 | 1 + 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index f5be01b8f21f..2ea0d660732e 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -849,9 +849,6 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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, & - !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, & @@ -881,10 +878,6 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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, & diff --git a/components/clm/src/main/clm_interface_bgcType.F90 b/components/clm/src/main/clm_interface_bgcType.F90 index 563508fdbcae..ce5647215a42 100644 --- a/components/clm/src/main/clm_interface_bgcType.F90 +++ b/components/clm/src/main/clm_interface_bgcType.F90 @@ -5,7 +5,8 @@ module clm_interface_bgcType ! Created by wgs @ ORNL ! ! date: 8/25/2015 -! update: 9/16/2016, 2/2/2017 +! update: 9/16/2016, 2/2/2017, May-2017 +! modifed by yfm, June-2017 !!================================================================================================= !! USES: use shr_log_mod , only : errMsg => shr_log_errMsg diff --git a/components/clm/src/main/clm_interface_dataType.F90 b/components/clm/src/main/clm_interface_dataType.F90 index 51fc3025dfc9..6f991a9c6d65 100644 --- a/components/clm/src/main/clm_interface_dataType.F90 +++ b/components/clm/src/main/clm_interface_dataType.F90 @@ -6,7 +6,8 @@ module clm_interface_dataType ! Created by wgs @ ORNL ! ! date: 8/25/2015 -! update: 9/16/2016, 2/2/2017 +! update: 9/16/2016, 2/2/2017, May-2017 +! modified by yfm, June-2017 !!================================================================================================= !! USES: use shr_log_mod , only : errMsg => shr_log_errMsg diff --git a/components/clm/src/main/clm_interface_funcsMod.F90 b/components/clm/src/main/clm_interface_funcsMod.F90 index 93f55e533e02..42097478df5b 100644 --- a/components/clm/src/main/clm_interface_funcsMod.F90 +++ b/components/clm/src/main/clm_interface_funcsMod.F90 @@ -5,12 +5,13 @@ module clm_interface_funcsMod ! Created by wgs @ ORNL ! ! date: 8/25/2015 +! modifed by yfm, June-2017 !!================================================================================================= #include "shr_assert.h" - !! MODULE: clm_interface_bgcMod + !! MODULE: clm_interface_funcsMod !!-------------------------------------------------------------------------------------- !! DESCRIPTION: !! Coupling of CLM with any specific Soil BGC module Consists of 3 STEPS: diff --git a/components/clm/src/main/clm_interface_thType.F90 b/components/clm/src/main/clm_interface_thType.F90 index 4877d6ad910d..f2681bf8d119 100644 --- a/components/clm/src/main/clm_interface_thType.F90 +++ b/components/clm/src/main/clm_interface_thType.F90 @@ -7,6 +7,7 @@ module clm_interface_thType ! ! date: 8/25/2015 ! update: 9/16/2016, 2/2/2017 +! modifed by yfm, June-2017 !!================================================================================================= !! USES: use shr_log_mod , only : errMsg => shr_log_errMsg From 6bfc077d532c49a4d8aed4f4b0e76daebeb08dff Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 22 Jun 2017 16:47:18 -0400 Subject: [PATCH 15/35] ensure that plant N/P uptake rate <= mineral N/P pool size --- .../clm/src/biogeochem/CNAllocationMod.F90 | 31 ++++++++++++++++--- .../clm/src/biogeochem/CNNStateUpdate3Mod.F90 | 16 +++++----- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index 5c149f7ecb29..a9eff988abc8 100755 --- a/components/clm/src/biogeochem/CNAllocationMod.F90 +++ b/components/clm/src/biogeochem/CNAllocationMod.F90 @@ -2969,6 +2969,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( & @@ -3133,12 +3134,18 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & allocation_froot => carbonflux_vars%allocation_froot , & xsmrpool_turnover => carbonflux_vars%xsmrpool_turnover_patch , & + smin_no3_vr => nitrogenstate_vars%smin_no3_vr_col , & + smin_nh4_vr => nitrogenstate_vars%smin_nh4_vr_col , & + solutionp_vr => phosphorusstate_vars%solutionp_vr_col , & !Input: [real(r8) (:,:) ] (gP/m3) soil mineral P + c13cf => c13_carbonflux_vars, & c14cf => c14_carbonflux_vars & ) ! ! !------------------------------------------------------------------- + ! set time steps + dt = real( get_step_size(), r8 ) ! debug do fc=1,num_soilc @@ -3883,8 +3890,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & else ! use_nitrif_denitrif - temp_sminn_to_plant = sminn_to_plant - temp_sminp_to_plant = sminp_to_plant + temp_sminn_to_plant(bounds%begc:bounds%endc) = sminn_to_plant(bounds%begc:bounds%endc) + temp_sminp_to_plant(bounds%begc:bounds%endc) = sminp_to_plant(bounds%begc:bounds%endc) call p2c(bounds,num_soilc,filter_soilc, & sminn_to_npool(bounds%begp:bounds%endp), & @@ -3902,6 +3909,10 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & sminn_to_plant_vr(c,j) = sminn_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_nh4_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_no3_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) + ! ensure that plant uptake rate isn't larger than soil N pool + smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) + smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) + sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) else sminn_to_plant_vr(c,j) = 0._r8 smin_nh4_to_plant_vr(c,j) = 0._r8 @@ -3910,6 +3921,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) + ! ensure that plant uptake rate isn't larger than soil P pool + sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -3961,8 +3974,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & .not.cnallocate_carbonnitrogen_only().and. & .not.cnallocate_carbon_only() )then - temp_sminn_to_plant = sminn_to_plant - temp_sminp_to_plant = sminp_to_plant + temp_sminn_to_plant(bounds%begc:bounds%endc) = sminn_to_plant(bounds%begc:bounds%endc) + temp_sminp_to_plant(bounds%begc:bounds%endc) = sminp_to_plant(bounds%begc:bounds%endc) call p2c(bounds,num_soilc,filter_soilc, & sminn_to_npool(bounds%begp:bounds%endp), & @@ -3980,6 +3993,10 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & sminn_to_plant_vr(c,j) = sminn_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_nh4_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_no3_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) + ! ensure that plant uptake rate isn't larger than soil N pool + smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) + smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) + sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) else sminn_to_plant_vr(c,j) = 0._r8 smin_nh4_to_plant_vr(c,j) = 0._r8 @@ -3988,6 +4005,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) + ! ensure that plant uptake rate isn't larger than soil P pool + sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -3998,7 +4017,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if( cnallocate_carbonnitrogen_only() )then - temp_sminp_to_plant = sminp_to_plant + temp_sminp_to_plant(bounds%begc:bounds%endc) = sminp_to_plant(bounds%begc:bounds%endc) call p2c(bounds,num_soilc,filter_soilc, & sminp_to_ppool(bounds%begp:bounds%endp), & @@ -4011,6 +4030,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) + ! ensure that plant uptake rate isn't larger than soil P pool + sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif diff --git a/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 b/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 index acf29d33da75..afd5cc09e11a 100644 --- a/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 +++ b/components/clm/src/biogeochem/CNNStateUpdate3Mod.F90 @@ -80,14 +80,14 @@ subroutine NStateUpdate3(num_soilc, filter_soilc, num_soilp, filter_soilp, & end if 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 + ! 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 From eb004d0a1dc04d007b9ce40665033f8465ebfba6 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 22 Jun 2017 16:57:28 -0400 Subject: [PATCH 16/35] ensure plant N/P uptake rate <= mineral N/P pool size --- components/clm/src/biogeochem/CNAllocationMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index a9eff988abc8..226a5f3390c6 100755 --- a/components/clm/src/biogeochem/CNAllocationMod.F90 +++ b/components/clm/src/biogeochem/CNAllocationMod.F90 @@ -2914,7 +2914,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & use clm_varpar , only: nlevdecomp !!nlevsoi, 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 From 57f0a5c9c3989b3dd67b4bc9d67f774132e56919 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 22 Jun 2017 18:52:58 -0400 Subject: [PATCH 17/35] add pflotran balance check --- .../clm/src/biogeochem/CNAllocationMod.F90 | 18 +- .../clm/src/main/clm_interface_bgcType.F90 | 14 + .../src/main/clm_interface_pflotranMod.F90 | 400 ++++++++++++++++++ 3 files changed, 423 insertions(+), 9 deletions(-) diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index 226a5f3390c6..e6f893e78628 100755 --- a/components/clm/src/biogeochem/CNAllocationMod.F90 +++ b/components/clm/src/biogeochem/CNAllocationMod.F90 @@ -3910,9 +3910,9 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & smin_nh4_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_no3_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) ! ensure that plant uptake rate isn't larger than soil N pool - smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) - smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) - sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) +! smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) +! smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) +! sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) else sminn_to_plant_vr(c,j) = 0._r8 smin_nh4_to_plant_vr(c,j) = 0._r8 @@ -3922,7 +3922,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) ! ensure that plant uptake rate isn't larger than soil P pool - sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) +! sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -3994,9 +3994,9 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & smin_nh4_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_no3_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) ! ensure that plant uptake rate isn't larger than soil N pool - smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) - smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) - sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) +! smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) +! smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) +! sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) else sminn_to_plant_vr(c,j) = 0._r8 smin_nh4_to_plant_vr(c,j) = 0._r8 @@ -4006,7 +4006,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) ! ensure that plant uptake rate isn't larger than soil P pool - sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) +! sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -4031,7 +4031,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) ! ensure that plant uptake rate isn't larger than soil P pool - sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) +! sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif diff --git a/components/clm/src/main/clm_interface_bgcType.F90 b/components/clm/src/main/clm_interface_bgcType.F90 index ce5647215a42..4248a00d407d 100644 --- a/components/clm/src/main/clm_interface_bgcType.F90 +++ b/components/clm/src/main/clm_interface_bgcType.F90 @@ -190,6 +190,13 @@ module clm_interface_bgcType real(r8), pointer :: forc_pco2_grc (:) ! CO2 partial pressure (Pa) real(r8), pointer :: forc_pch4_grc (:) ! CH4 partial pressure (Pa) + !! 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 !!------------------------------------------------------------------------------------------ @@ -408,6 +415,13 @@ subroutine InitAllocate(this, bounds) ! atm2lnd: allocate(this%forc_pco2_grc (begg:endg)) ; this%forc_pco2_grc (:) = ival allocate(this%forc_pch4_grc (begg:endg)) ; this%forc_pch4_grc (:) = ival + + ! 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 !!------------------------------------------------------------------------------------------ diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 2ccf9623f577..faf372937f90 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -90,6 +90,13 @@ module clm_interface_pflotranMod public :: clm_pf_write_restart public :: clm_pf_finalize + !! pflotran mass balance check + public :: clm_pf_BeginCBalance + public :: clm_pf_BeginNBalance + public :: clm_pf_CBalanceCheck + public :: clm_pf_NBalanceCheck + + private :: pflotran_not_available #ifdef CLM_PFLOTRAN @@ -346,7 +353,400 @@ subroutine clm_pf_finalize() end subroutine clm_pf_finalize +!!-------------------------------------------------------------------------------------- + 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 + real(r8) :: pf_cinputs, pf_coutputs, pf_cdelta,pf_errcb, pf_cbeg, pf_cend ! balance check varialbes + !----------------------------------------------------------------------- + + 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 = soil_begcb(c) + pf_cend = 0._r8 + pf_errcb = 0._r8 + + pf_cinputs = 0._r8 + pf_coutputs = 0._r8 + pf_cdelta = 0._r8 + + do j = 1, nlevdecomp_full + pf_coutputs = pf_coutputs + hr_vr(c,j)*dzsoi_decomp(j) + do l = 1, ndecomp_pools + pf_cinputs = pf_cinputs + externalc(c,j,l)*dzsoi_decomp(j) + pf_cdelta = pf_cdelta + decomp_cpools_delta_vr(c,j,l)*dzsoi_decomp(j) + end do + end do + + pf_cend = pf_cbeg + pf_cdelta + pf_errcb = (pf_cinputs - pf_coutputs)*dtime - pf_cdelta + + ! check for significant errors + if (abs(pf_errcb) > 1e-8_r8) then + err_found = .true. + err_index = c + end if + end do + + if (.not. use_ed) then + if (err_found) then + write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:beg " + write(iulog,'(A35,I5,I15)')"Carbon Balance Error in Column = ",err_index, get_nstep() + write(iulog,'(10A15)')"errcb", "C_in-out", "Cdelta","Cinputs","Coutputs","Cbeg","Cend" + write(iulog,'(10E15.6)')pf_errcb, (pf_cinputs - pf_coutputs)*dtime, pf_cdelta, & + pf_cinputs*dtime,pf_coutputs*dtime,pf_cbeg,pf_cend + 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, pf_noutputs, pf_ndelta,pf_errnb !! _errnb: mass balance error; _ndelta: difference in pool sizes between end & beginning + real(r8) :: pf_noutputs_gas, pf_noutputs_veg !! _gas:nitrogen gases; _veg:plant uptake of NO3/NH4 + real(r8) :: pf_noutputs_nit, pf_noutputs_denit !! _gas = _nit + _denit + real(r8) :: pf_ninputs_org, pf_ninputs_min, pf_ndelta_org,pf_ndelta_min !! _org:organic; _min:mineral nitrogen + real(r8) :: pf_nbeg, pf_nbeg_org, pf_nbeg_min !! _nbeg: Nitrogen mass at the beginning of time-step + real(r8) :: pf_nend, pf_nend_org, pf_nend_min !! _end: Nitrogen mass at the end of time-step + real(r8) :: pf_nend_no3, pf_nend_nh4, pf_nend_nh4sorb !! 3 mineral N pools at the end of time-step + real(r8) :: plant_ndemand, potential_immob, actual_immob, gross_nmin !! _immob: N immobilization; _nmin: N mineralization + real(r8) :: pf_ngas_dec, pf_ngas_min, pf_errnb_org, pf_errnb_min !! _ngas_dec: N gas from decomposition-mineralization; _ngas_min: N gas from nitrification & denitrification + + !----------------------------------------------------------------------- + + 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 = soil_begnb_org(c) + pf_nbeg_min = soil_begnb_min(c) + pf_nbeg = soil_begnb(c) + + pf_nend_org = 0._r8 + pf_nend_min = 0._r8 + pf_nend_no3 = 0._r8 + pf_nend_nh4 = 0._r8 + pf_nend_nh4sorb = 0._r8 + pf_nend = 0._r8 + + pf_ninputs_org = 0._r8 + pf_ninputs_min = 0._r8 + pf_ninputs = 0._r8 + + pf_noutputs_nit = 0._r8 + pf_noutputs_denit = 0._r8 + pf_noutputs_gas = 0._r8 + pf_noutputs_veg = 0._r8 + pf_noutputs = 0._r8 + + pf_ndelta_org = 0._r8 + pf_ndelta_min = 0._r8 + pf_ndelta = 0._r8 + + plant_ndemand = 0._r8 + potential_immob = 0._r8 + actual_immob = 0._r8 + gross_nmin = 0._r8 + + pf_ngas_dec = 0._r8 + pf_ngas_min = 0._r8 + pf_errnb_org = 0._r8 + pf_errnb_min = 0._r8 + + do j = 1, nlev + !! sminn_vr(c,j) has been calculated above + pf_nend_no3 = pf_nend_no3 + smin_no3_vr(c,j)*dzsoi_decomp(j) + pf_nend_nh4 = pf_nend_nh4 + smin_nh4_vr(c,j)*dzsoi_decomp(j) + pf_nend_nh4sorb = pf_nend_nh4sorb + smin_nh4sorb_vr(c,j)*dzsoi_decomp(j) + + pf_ninputs_min = pf_ninputs_min + externaln_to_nh4_vr(c,j)*dzsoi_decomp(j) & + + externaln_to_no3_vr(c,j)*dzsoi_decomp(j) + + pf_noutputs_nit = pf_noutputs_nit + f_ngas_decomp_vr(c,j)*dzsoi_decomp(j) & + + f_ngas_nitri_vr(c,j)*dzsoi_decomp(j) + pf_noutputs_denit = pf_noutputs_denit + f_ngas_denit_vr(c,j)*dzsoi_decomp(j) + pf_noutputs_veg = pf_noutputs_veg + sminn_to_plant_vr(c,j)*dzsoi_decomp(j) + + pf_ngas_dec = pf_ngas_dec + f_ngas_decomp_vr(c,j)*dzsoi_decomp(j) + pf_ngas_min = pf_ngas_min + 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 = pf_ndelta_org + decomp_npools_delta_vr(c,j,l)*dzsoi_decomp(j) + pf_ninputs_org = pf_ninputs_org + externaln_to_decomp_npools(c,j,l)*dzsoi_decomp(j) + end do + + plant_ndemand = plant_ndemand + plant_ndemand_vr(c,j)*dzsoi_decomp(j) + potential_immob = potential_immob + potential_immob_vr(c,j)*dzsoi_decomp(j) + actual_immob = actual_immob + actual_immob_vr(c,j)*dzsoi_decomp(j) + gross_nmin = gross_nmin + gross_nmin_vr(c,j)*dzsoi_decomp(j) + end do !!j = 1, nlevdecomp + + + !! check SON balance at each layer + pf_errnb_org_vr(:) = 0._r8 + pf_ndelta_org_vr(:) = 0._r8 + pf_ninputs_org_vr(:) = 0._r8 + do j = 1, nlev + + do l = 1, ndecomp_pools + pf_ndelta_org_vr(j) = pf_ndelta_org_vr(j) + decomp_npools_delta_vr(c,j,l) + pf_ninputs_org_vr(j) = pf_ninputs_org_vr(j) + externaln_to_decomp_npools(c,j,l) + end do + pf_errnb_org_vr(j) = (pf_ninputs_org_vr(j) & !!- f_ngas_decomp_vr(c,j) + - gross_nmin_vr(c,j) + actual_immob_vr(c,j))*dtime & + - pf_ndelta_org_vr(j) + pf_errnb_org_vr(j) = pf_errnb_org_vr(j)*dzsoi_decomp(j) + end do + + pf_nend_org = pf_nbeg_org + pf_ndelta_org !!pf_ndelta_org has been calculated + pf_nend_min = pf_nend_no3 + pf_nend_nh4 + pf_nend_nh4sorb + pf_nend = pf_nend_org + pf_nend_min + pf_ndelta_min = pf_nend_min - pf_nbeg_min + pf_ndelta = pf_nend - pf_nbeg !!pf_ndelta_org + pf_ndelta_min + pf_ninputs = pf_ninputs_org + pf_ninputs_min + pf_noutputs_gas = pf_noutputs_nit + pf_noutputs_denit + pf_noutputs = pf_noutputs_gas + pf_noutputs_veg + pf_errnb = (pf_ninputs - pf_noutputs)*dtime - pf_ndelta +!write(iulog,*)'>>>DEBUG | pflotran nbalance error = ', pf_errnb, c, get_nstep() + + pf_errnb_org = (pf_ninputs_org & + - gross_nmin + actual_immob)*dtime & + - pf_ndelta_org + pf_errnb_min = (pf_ninputs_min - pf_ngas_min - pf_ngas_dec & + + gross_nmin - actual_immob - pf_noutputs_veg)*dtime & + - pf_ndelta_min + ! check for significant errors + if (abs(pf_errnb) > 1e-8_r8) then + err_found = .true. + err_index = c + end if + end do + + if (.not. use_ed) then + if (err_found) then + write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:beg " + write(iulog,'(A35,I5,I15)')"Nitrogen Balance Error in Column = ",err_index, get_nstep() + write(iulog,'(10A15)') "errnb", "N_in-out", "Ndelta", & + "Ninputs","Noutputs", "Nbeg","Nend" + write(iulog,'(10E15.6)')pf_errnb, (pf_ninputs - pf_noutputs)*dtime, pf_ndelta, & + pf_ninputs*dtime,pf_noutputs*dtime,pf_nbeg,pf_nend + 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,pf_ndelta_org,pf_nbeg_org,pf_nend_org, & + gross_nmin*dtime,actual_immob*dtime,potential_immob*dtime + write(iulog,*) + write(iulog,'(10A15)') "errnb_min","Ndelta_min","Nbeg_min","Nend_min", & + "Nend_no3","Nend_nh4", "Nend_nh4sorb","Ngas_dec","Ngas_min" + write(iulog,'(10E15.6)')pf_errnb_min, pf_ndelta_min,pf_nbeg_min,pf_nend_min, & + pf_nend_no3,pf_nend_nh4,pf_nend_nh4sorb,pf_ngas_dec*dtime,pf_ngas_min*dtime + write(iulog,*) + write(iulog,'(10A15)') "Ninputs_org","Ninputs_min", & + "Noutputs_nit","Noutputs_denit", & + "Noutputs_gas","Noutputs_veg","plant_Ndemand" + write(iulog,'(10E15.6)')pf_ninputs_org*dtime,pf_ninputs_min*dtime, & + pf_noutputs_nit*dtime,pf_noutputs_denit*dtime, & + pf_noutputs_gas*dtime,pf_noutputs_veg*dtime, plant_ndemand*dtime + +! write(iulog,*) +! write(iulog,'(A10,20A15)') "Layer","errbn_org","ndelta_org","ninputs","gross_nmin","actual_immob" !!"ngas", +! do j = 1, nlevdecomp_full +! write(iulog,'(I10,15E15.6)')j,pf_errnb_org_vr(j), & +! pf_ndelta_org_vr(j)*dzsoi_decomp(j), & +! pf_ninputs_org_vr(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 +!!-------------------------------------------------------------------------------------- + + +#ifdef CLM_PFLOTRAN !************************************************************************************! From e85a705e44b95e6e45ea5fb56a797ea131818815 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 22 Jun 2017 19:01:57 -0400 Subject: [PATCH 18/35] correct errors in pflotran mass balance check --- components/clm/src/main/clm_interface_pflotranMod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index faf372937f90..d409636d1e8b 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -564,6 +564,9 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) real(r8) :: plant_ndemand, potential_immob, actual_immob, gross_nmin !! _immob: N immobilization; _nmin: N mineralization real(r8) :: pf_ngas_dec, pf_ngas_min, pf_errnb_org, pf_errnb_min !! _ngas_dec: N gas from decomposition-mineralization; _ngas_min: N gas from nitrification & denitrification + real(r8) :: pf_errnb_org_vr(1:nlevdecomp_full) + real(r8) :: pf_ndelta_org_vr(1:nlevdecomp_full) + real(r8) :: pf_ninputs_org_vr(1:nlevdecomp_full) !----------------------------------------------------------------------- associate( & @@ -752,8 +755,7 @@ end subroutine clm_pf_NBalanceCheck !************************************************************************************! ! (BEGIN) ! Private interface subroutines, requiring explicit coupling between CLM and PFLOTRAN -! -#ifdef CLM_PFLOTRAN + !==================================================================================================== ! ! From 30826a198af8f2067c8048b50ed1f7093789107b Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Fri, 23 Jun 2017 15:54:08 -0400 Subject: [PATCH 19/35] alm-pflotran: clean comments & unused variables --- .../clm/src/biogeochem/CNAllocationMod.F90 | 44 ++----- components/clm/src/biogeochem/CNDecompMod.F90 | 111 +++++++++--------- components/clm/src/main/clm_driver.F90 | 12 +- .../clm/src/main/clm_interface_funcsMod.F90 | 43 +++---- .../src/main/clm_interface_pflotranMod.F90 | 16 +-- components/clm/src/main/controlMod.F90 | 4 +- 6 files changed, 98 insertions(+), 132 deletions(-) diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index e6f893e78628..ab13916c885a 100755 --- a/components/clm/src/biogeochem/CNAllocationMod.F90 +++ b/components/clm/src/biogeochem/CNAllocationMod.F90 @@ -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 @@ -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 @@ -3134,10 +3128,6 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & allocation_froot => carbonflux_vars%allocation_froot , & xsmrpool_turnover => carbonflux_vars%xsmrpool_turnover_patch , & - smin_no3_vr => nitrogenstate_vars%smin_no3_vr_col , & - smin_nh4_vr => nitrogenstate_vars%smin_nh4_vr_col , & - solutionp_vr => phosphorusstate_vars%solutionp_vr_col , & !Input: [real(r8) (:,:) ] (gP/m3) soil mineral P - c13cf => c13_carbonflux_vars, & c14cf => c14_carbonflux_vars & ) @@ -3890,8 +3880,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & else ! use_nitrif_denitrif - temp_sminn_to_plant(bounds%begc:bounds%endc) = sminn_to_plant(bounds%begc:bounds%endc) - temp_sminp_to_plant(bounds%begc:bounds%endc) = sminp_to_plant(bounds%begc:bounds%endc) + temp_sminn_to_plant = sminn_to_plant + temp_sminp_to_plant = sminp_to_plant call p2c(bounds,num_soilc,filter_soilc, & sminn_to_npool(bounds%begp:bounds%endp), & @@ -3909,10 +3899,6 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & sminn_to_plant_vr(c,j) = sminn_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_nh4_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_no3_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) - ! ensure that plant uptake rate isn't larger than soil N pool -! smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) -! smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) -! sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) else sminn_to_plant_vr(c,j) = 0._r8 smin_nh4_to_plant_vr(c,j) = 0._r8 @@ -3921,8 +3907,6 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) - ! ensure that plant uptake rate isn't larger than soil P pool -! sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -3974,8 +3958,8 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & .not.cnallocate_carbonnitrogen_only().and. & .not.cnallocate_carbon_only() )then - temp_sminn_to_plant(bounds%begc:bounds%endc) = sminn_to_plant(bounds%begc:bounds%endc) - temp_sminp_to_plant(bounds%begc:bounds%endc) = sminp_to_plant(bounds%begc:bounds%endc) + temp_sminn_to_plant = sminn_to_plant + temp_sminp_to_plant = sminp_to_plant call p2c(bounds,num_soilc,filter_soilc, & sminn_to_npool(bounds%begp:bounds%endp), & @@ -3993,10 +3977,6 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & sminn_to_plant_vr(c,j) = sminn_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_nh4_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) smin_no3_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) * ( sminn_to_plant(c)/temp_sminn_to_plant(c) ) - ! ensure that plant uptake rate isn't larger than soil N pool -! smin_nh4_to_plant_vr(c,j) = min(smin_nh4_to_plant_vr(c,j), smin_nh4_vr(c,j) / dt ) -! smin_no3_to_plant_vr(c,j) = min(smin_no3_to_plant_vr(c,j), smin_no3_vr(c,j) / dt ) -! sminn_to_plant_vr(c,j) = smin_nh4_to_plant_vr(c,j) + smin_no3_to_plant_vr(c,j) else sminn_to_plant_vr(c,j) = 0._r8 smin_nh4_to_plant_vr(c,j) = 0._r8 @@ -4005,8 +3985,6 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) - ! ensure that plant uptake rate isn't larger than soil P pool -! sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -4017,7 +3995,7 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if( cnallocate_carbonnitrogen_only() )then - temp_sminp_to_plant(bounds%begc:bounds%endc) = sminp_to_plant(bounds%begc:bounds%endc) + temp_sminp_to_plant = sminp_to_plant call p2c(bounds,num_soilc,filter_soilc, & sminp_to_ppool(bounds%begp:bounds%endp), & @@ -4030,8 +4008,6 @@ subroutine CNAllocation3_PlantCNPAlloc (bounds , & if ( temp_sminp_to_plant(c) > 0._r8) then sminp_to_plant_vr(c,j) = sminp_to_plant_vr(c,j) * ( sminp_to_plant(c)/temp_sminp_to_plant(c) ) - ! ensure that plant uptake rate isn't larger than soil P pool -! sminp_to_plant_vr(c,j) = min(sminp_to_plant_vr(c,j), solutionp_vr(c,j) / dt ) else sminp_to_plant_vr(c,j) = 0._r8 endif @@ -4117,8 +4093,7 @@ subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitr else nuptake_prof(c,j) = nfixation_prof(c,j) end if - !! 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 do end do @@ -4149,7 +4124,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 ) @@ -4176,8 +4151,7 @@ subroutine calc_puptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, phos else 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/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90 index fd1754c1b785..775938a96146 100644 --- a/components/clm/src/biogeochem/CNDecompMod.F90 +++ b/components/clm/src/biogeochem/CNDecompMod.F90 @@ -213,7 +213,7 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, & ) !!------------------------------------------------------------------------------------------------- - ! calculate decomposition rates (originally called in CNEcosystemDynNoLeaching1) + ! call decomp_rate_constants_bgc() or decomp_rate_constants_cn(): now called in CNEcosystemDynNoLeaching1 !!------------------------------------------------------------------------------------------------- ! set initial values for potential C and N fluxes @@ -385,11 +385,8 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, & !!------------------------------------------------------------------------------------------------- -!! '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 @@ -417,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 + !!------------------------------------------------------------------------------------------------- + !! [wgs,6/22/2017]: 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 @@ -675,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) @@ -703,6 +660,10 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so 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) (:,:) ] @@ -714,11 +675,20 @@ 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 if(use_clm_interface.and.use_pflotran.and.pf_cmode) then @@ -808,6 +778,15 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so 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 !!if(use_clm_interface.and.use_pflotran.and.pf_cmode) !!------------------------------------------------------------------ @@ -823,7 +802,29 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so call t_stopf('CNAllocation - phase-3') !!------------------------------------------------------------------ + if(use_pflotran.and.pf_cmode) then +!! wgs: 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) diff --git a/components/clm/src/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index 2ea0d660732e..1600f916e275 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -839,13 +839,13 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) ! ------------------------------------------------------------------------- ! 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: (1) pass data from clm_interface_data to pflotran !! STEP-2: (2) run pflotran - !! STEP-2: (3) update clm_bgc_data from pflotran + !! STEP-2: (3) update clm_interface_data from pflotran ! ------------------------------------------------------------------------- call clm_pf_run(clm_interface_data, bounds_clump, filter, nc) - !! STEP-3: update CLM from clm_bgc_data + !! 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, & @@ -860,9 +860,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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: (1) pass data from clm_interface_data to CNDecompAlloc !! STEP-2: (2) run CNDecompAlloc - !! STEP-2: (3) update clm_bgc_data from CNDecompAlloc + !! STEP-2: (3) update clm_interface_data from CNDecompAlloc ! ------------------------------------------------------------------------- call clm_bgc_run(clm_interface_data, bounds_clump, & filter(nc)%num_soilc, filter(nc)%soilc, & @@ -874,7 +874,7 @@ 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 + !! 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, & diff --git a/components/clm/src/main/clm_interface_funcsMod.F90 b/components/clm/src/main/clm_interface_funcsMod.F90 index 42097478df5b..749b5ef238f5 100644 --- a/components/clm/src/main/clm_interface_funcsMod.F90 +++ b/components/clm/src/main/clm_interface_funcsMod.F90 @@ -15,12 +15,12 @@ module clm_interface_funcsMod !!-------------------------------------------------------------------------------------- !! DESCRIPTION: !! Coupling of CLM with any specific Soil BGC module Consists of 3 STEPS: - !! STEP-1: clm vars -> clm_bgc_data (i.e. clm_interface_bgc_datatype) ; 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 + !! 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_bgc_data - !! STEP-3: clm_bgc_data -> clm vars + !! 2.3: soil bgc module -> clm_interface_data + !! STEP-3: clm_interface_data -> clm vars !!-------------------------------------------------------------------------------------- @@ -88,16 +88,16 @@ module clm_interface_funcsMod !!-------------------------------------------------------------------------------------- !! (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_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 + !! 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, + !! 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 @@ -114,16 +114,16 @@ module clm_interface_funcsMod !! (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_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 + 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_bgc_data -> clm vars ; called in clm_driver - !! STEP-2: see 'clm_pf_run' in clm_pflotran_interfaceMod + 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 !!-------------------------------------------------------------------------------------- @@ -1701,10 +1701,6 @@ 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, & @@ -1720,13 +1716,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 diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index d409636d1e8b..0af079907939 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -719,24 +719,26 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) gross_nmin*dtime,actual_immob*dtime,potential_immob*dtime write(iulog,*) write(iulog,'(10A15)') "errnb_min","Ndelta_min","Nbeg_min","Nend_min", & - "Nend_no3","Nend_nh4", "Nend_nh4sorb","Ngas_dec","Ngas_min" + "Nend_no3","Nend_nh4", "Nend_nh4sorb" write(iulog,'(10E15.6)')pf_errnb_min, pf_ndelta_min,pf_nbeg_min,pf_nend_min, & - pf_nend_no3,pf_nend_nh4,pf_nend_nh4sorb,pf_ngas_dec*dtime,pf_ngas_min*dtime + pf_nend_no3,pf_nend_nh4,pf_nend_nh4sorb write(iulog,*) write(iulog,'(10A15)') "Ninputs_org","Ninputs_min", & "Noutputs_nit","Noutputs_denit", & - "Noutputs_gas","Noutputs_veg","plant_Ndemand" + "Noutputs_gas","Noutputs_veg", & + "plant_Ndemand","Ngas_dec","Ngas_min" write(iulog,'(10E15.6)')pf_ninputs_org*dtime,pf_ninputs_min*dtime, & pf_noutputs_nit*dtime,pf_noutputs_denit*dtime, & - pf_noutputs_gas*dtime,pf_noutputs_veg*dtime, plant_ndemand*dtime + pf_noutputs_gas*dtime,pf_noutputs_veg*dtime, & + plant_ndemand*dtime,pf_ngas_dec*dtime,pf_ngas_min*dtime ! write(iulog,*) -! write(iulog,'(A10,20A15)') "Layer","errbn_org","ndelta_org","ninputs","gross_nmin","actual_immob" !!"ngas", -! do j = 1, nlevdecomp_full +! 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(j), & ! pf_ndelta_org_vr(j)*dzsoi_decomp(j), & ! pf_ninputs_org_vr(j)*dtime*dzsoi_decomp(j), & -!! f_ngas_decomp_vr(c,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) diff --git a/components/clm/src/main/controlMod.F90 b/components/clm/src/main/controlMod.F90 index ba77c0d34751..5bb7248aae81 100644 --- a/components/clm/src/main/controlMod.F90 +++ b/components/clm/src/main/controlMod.F90 @@ -407,7 +407,7 @@ subroutine control_init( ) use_clm_bgc = .false. use_pflotran = .false. else - + !! use_clm_interface if (use_clm_bgc) then use_pflotran = .false. end if @@ -416,7 +416,7 @@ subroutine control_init( ) use_clm_bgc = .false. !! enable 'use_nitrif_denitrif' to initilize Nh4 & NO3 pools, !! but NOT to implement 'nitrif_denitrif' - use_nitrif_denitrif = .true. + use_nitrif_denitrif = .true. end if end if From babbe1a60933648942539399e1b3ff5ab515b124 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Fri, 23 Jun 2017 18:01:29 -0400 Subject: [PATCH 20/35] use array in pflotran mass balance check --- .../src/main/clm_interface_pflotranMod.F90 | 240 ++++++++++-------- 1 file changed, 134 insertions(+), 106 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 0af079907939..c1bf1fd223c7 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -474,7 +474,13 @@ subroutine clm_pf_CBalanceCheck(clm_interface_data,bounds, filters, ifilter) real(r8) :: dtime ! land model time step (sec) integer :: err_index ! indices logical :: err_found ! error flag - real(r8) :: pf_cinputs, pf_coutputs, pf_cdelta,pf_errcb, pf_cbeg, pf_cend ! balance check varialbes + ! 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( & @@ -490,39 +496,40 @@ subroutine clm_pf_CBalanceCheck(clm_interface_data,bounds, filters, ifilter) err_found = .false. do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - pf_cbeg = soil_begcb(c) - pf_cend = 0._r8 - pf_errcb = 0._r8 + pf_cbeg(fc) = soil_begcb(c) + pf_cend(fc) = 0._r8 + pf_errcb(fc) = 0._r8 - pf_cinputs = 0._r8 - pf_coutputs = 0._r8 - pf_cdelta = 0._r8 + pf_cinputs(fc) = 0._r8 + pf_coutputs(fc) = 0._r8 + pf_cdelta(fc) = 0._r8 do j = 1, nlevdecomp_full - pf_coutputs = pf_coutputs + hr_vr(c,j)*dzsoi_decomp(j) + pf_coutputs(fc) = pf_coutputs(fc) + hr_vr(c,j)*dzsoi_decomp(j) do l = 1, ndecomp_pools - pf_cinputs = pf_cinputs + externalc(c,j,l)*dzsoi_decomp(j) - pf_cdelta = pf_cdelta + decomp_cpools_delta_vr(c,j,l)*dzsoi_decomp(j) + 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 = pf_cbeg + pf_cdelta - pf_errcb = (pf_cinputs - pf_coutputs)*dtime - pf_cdelta + 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) > 1e-8_r8) then + if (abs(pf_errcb(fc)) > 1e-8_r8) then err_found = .true. - err_index = c + 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,I5,I15)')"Carbon Balance Error in Column = ",err_index, get_nstep() + 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, (pf_cinputs - pf_coutputs)*dtime, pf_cdelta, & - pf_cinputs*dtime,pf_coutputs*dtime,pf_cbeg,pf_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) @@ -554,15 +561,35 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) integer :: err_index ! indices logical :: err_found ! error flag - real(r8) :: pf_ninputs, pf_noutputs, pf_ndelta,pf_errnb !! _errnb: mass balance error; _ndelta: difference in pool sizes between end & beginning - real(r8) :: pf_noutputs_gas, pf_noutputs_veg !! _gas:nitrogen gases; _veg:plant uptake of NO3/NH4 - real(r8) :: pf_noutputs_nit, pf_noutputs_denit !! _gas = _nit + _denit - real(r8) :: pf_ninputs_org, pf_ninputs_min, pf_ndelta_org,pf_ndelta_min !! _org:organic; _min:mineral nitrogen - real(r8) :: pf_nbeg, pf_nbeg_org, pf_nbeg_min !! _nbeg: Nitrogen mass at the beginning of time-step - real(r8) :: pf_nend, pf_nend_org, pf_nend_min !! _end: Nitrogen mass at the end of time-step - real(r8) :: pf_nend_no3, pf_nend_nh4, pf_nend_nh4sorb !! 3 mineral N pools at the end of time-step - real(r8) :: plant_ndemand, potential_immob, actual_immob, gross_nmin !! _immob: N immobilization; _nmin: N mineralization - real(r8) :: pf_ngas_dec, pf_ngas_min, pf_errnb_org, pf_errnb_min !! _ngas_dec: N gas from decomposition-mineralization; _ngas_min: N gas from nitrification & denitrification + 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:nlevdecomp_full) real(r8) :: pf_ndelta_org_vr(1:nlevdecomp_full) @@ -600,67 +627,67 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) err_found = .false. do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - pf_nbeg_org = soil_begnb_org(c) - pf_nbeg_min = soil_begnb_min(c) - pf_nbeg = soil_begnb(c) - - pf_nend_org = 0._r8 - pf_nend_min = 0._r8 - pf_nend_no3 = 0._r8 - pf_nend_nh4 = 0._r8 - pf_nend_nh4sorb = 0._r8 - pf_nend = 0._r8 - - pf_ninputs_org = 0._r8 - pf_ninputs_min = 0._r8 - pf_ninputs = 0._r8 - - pf_noutputs_nit = 0._r8 - pf_noutputs_denit = 0._r8 - pf_noutputs_gas = 0._r8 - pf_noutputs_veg = 0._r8 - pf_noutputs = 0._r8 - - pf_ndelta_org = 0._r8 - pf_ndelta_min = 0._r8 - pf_ndelta = 0._r8 - - plant_ndemand = 0._r8 - potential_immob = 0._r8 - actual_immob = 0._r8 - gross_nmin = 0._r8 - - pf_ngas_dec = 0._r8 - pf_ngas_min = 0._r8 - pf_errnb_org = 0._r8 - pf_errnb_min = 0._r8 + 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 = pf_nend_no3 + smin_no3_vr(c,j)*dzsoi_decomp(j) - pf_nend_nh4 = pf_nend_nh4 + smin_nh4_vr(c,j)*dzsoi_decomp(j) - pf_nend_nh4sorb = pf_nend_nh4sorb + smin_nh4sorb_vr(c,j)*dzsoi_decomp(j) + 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 = pf_ninputs_min + externaln_to_nh4_vr(c,j)*dzsoi_decomp(j) & - + externaln_to_no3_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 = pf_noutputs_nit + f_ngas_decomp_vr(c,j)*dzsoi_decomp(j) & - + f_ngas_nitri_vr(c,j)*dzsoi_decomp(j) - pf_noutputs_denit = pf_noutputs_denit + f_ngas_denit_vr(c,j)*dzsoi_decomp(j) - pf_noutputs_veg = pf_noutputs_veg + sminn_to_plant_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 = pf_ngas_dec + f_ngas_decomp_vr(c,j)*dzsoi_decomp(j) - pf_ngas_min = pf_ngas_min + f_ngas_denit_vr(c,j)*dzsoi_decomp(j) & - + f_ngas_nitri_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 = pf_ndelta_org + decomp_npools_delta_vr(c,j,l)*dzsoi_decomp(j) - pf_ninputs_org = pf_ninputs_org + externaln_to_decomp_npools(c,j,l)*dzsoi_decomp(j) + 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 = plant_ndemand + plant_ndemand_vr(c,j)*dzsoi_decomp(j) - potential_immob = potential_immob + potential_immob_vr(c,j)*dzsoi_decomp(j) - actual_immob = actual_immob + actual_immob_vr(c,j)*dzsoi_decomp(j) - gross_nmin = gross_nmin + gross_nmin_vr(c,j)*dzsoi_decomp(j) + 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 @@ -680,57 +707,58 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) pf_errnb_org_vr(j) = pf_errnb_org_vr(j)*dzsoi_decomp(j) end do - pf_nend_org = pf_nbeg_org + pf_ndelta_org !!pf_ndelta_org has been calculated - pf_nend_min = pf_nend_no3 + pf_nend_nh4 + pf_nend_nh4sorb - pf_nend = pf_nend_org + pf_nend_min - pf_ndelta_min = pf_nend_min - pf_nbeg_min - pf_ndelta = pf_nend - pf_nbeg !!pf_ndelta_org + pf_ndelta_min - pf_ninputs = pf_ninputs_org + pf_ninputs_min - pf_noutputs_gas = pf_noutputs_nit + pf_noutputs_denit - pf_noutputs = pf_noutputs_gas + pf_noutputs_veg - pf_errnb = (pf_ninputs - pf_noutputs)*dtime - pf_ndelta + 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) !write(iulog,*)'>>>DEBUG | pflotran nbalance error = ', pf_errnb, c, get_nstep() - pf_errnb_org = (pf_ninputs_org & - - gross_nmin + actual_immob)*dtime & - - pf_ndelta_org - pf_errnb_min = (pf_ninputs_min - pf_ngas_min - pf_ngas_dec & - + gross_nmin - actual_immob - pf_noutputs_veg)*dtime & - - pf_ndelta_min + 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) > 1e-8_r8) then + if (abs(pf_errnb(fc)) > 1e-8_r8) then err_found = .true. - err_index = c + 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,I5,I15)')"Nitrogen Balance Error in Column = ",err_index, get_nstep() + 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, (pf_ninputs - pf_noutputs)*dtime, pf_ndelta, & - pf_ninputs*dtime,pf_noutputs*dtime,pf_nbeg,pf_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,pf_ndelta_org,pf_nbeg_org,pf_nend_org, & - gross_nmin*dtime,actual_immob*dtime,potential_immob*dtime + 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, pf_ndelta_min,pf_nbeg_min,pf_nend_min, & - pf_nend_no3,pf_nend_nh4,pf_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*dtime,pf_ninputs_min*dtime, & - pf_noutputs_nit*dtime,pf_noutputs_denit*dtime, & - pf_noutputs_gas*dtime,pf_noutputs_veg*dtime, & - plant_ndemand*dtime,pf_ngas_dec*dtime,pf_ngas_min*dtime + 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 ! write(iulog,*) ! write(iulog,'(A10,20A15)') "Layer","errbn_org","ndelta_org","ninputs","gross_nmin","actual_immob" From d3a4e3f59cfcc338105fa562223ddb3a6ead3be0 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Fri, 23 Jun 2017 20:22:32 -0400 Subject: [PATCH 21/35] improve pflotran mass balance check --- .../src/main/clm_interface_pflotranMod.F90 | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index c1bf1fd223c7..3b3c331b76bc 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -591,9 +591,9 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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:nlevdecomp_full) - real(r8) :: pf_ndelta_org_vr(1:nlevdecomp_full) - real(r8) :: pf_ninputs_org_vr(1:nlevdecomp_full) + 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( & @@ -690,23 +690,6 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) gross_nmin(fc) = gross_nmin(fc) + gross_nmin_vr(c,j)*dzsoi_decomp(j) end do !!j = 1, nlevdecomp - - !! check SON balance at each layer - pf_errnb_org_vr(:) = 0._r8 - pf_ndelta_org_vr(:) = 0._r8 - pf_ninputs_org_vr(:) = 0._r8 - do j = 1, nlev - - do l = 1, ndecomp_pools - pf_ndelta_org_vr(j) = pf_ndelta_org_vr(j) + decomp_npools_delta_vr(c,j,l) - pf_ninputs_org_vr(j) = pf_ninputs_org_vr(j) + externaln_to_decomp_npools(c,j,l) - end do - pf_errnb_org_vr(j) = (pf_ninputs_org_vr(j) & !!- f_ngas_decomp_vr(c,j) - - gross_nmin_vr(c,j) + actual_immob_vr(c,j))*dtime & - - pf_ndelta_org_vr(j) - pf_errnb_org_vr(j) = pf_errnb_org_vr(j)*dzsoi_decomp(j) - end do - 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) @@ -716,7 +699,6 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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) -!write(iulog,*)'>>>DEBUG | pflotran nbalance error = ', pf_errnb, c, get_nstep() pf_errnb_org(fc) = (pf_ninputs_org(fc) & - gross_nmin(fc) + actual_immob(fc))*dtime & @@ -729,6 +711,21 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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 @@ -759,15 +756,15 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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(j), & -! pf_ndelta_org_vr(j)*dzsoi_decomp(j), & -! pf_ninputs_org_vr(j)*dtime*dzsoi_decomp(j), & -! f_ngas_decomp_vr(c,j)*dtime*dzsoi_decomp(j), & -! gross_nmin_vr(c,j)*dtime*dzsoi_decomp(j), & +! 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 From 83d72749c32eb60a35d3ca7a944ec29a02490303 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Tue, 27 Jun 2017 12:21:15 -0400 Subject: [PATCH 22/35] edit output for "err_found" in plfotran mass balance check --- components/clm/src/main/clm_interface_pflotranMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 3b3c331b76bc..78a2f96e0b8d 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -526,7 +526,7 @@ subroutine clm_pf_CBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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,'(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) @@ -732,7 +732,7 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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,'(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), & From 8c8315256df363beedb360abe4f425d139f816b6 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Wed, 28 Jun 2017 11:16:32 -0400 Subject: [PATCH 23/35] comment out "initialization to 0" for net and gross mineralization fluxes --- components/clm/src/biogeochem/CNDecompMod.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/clm/src/biogeochem/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90 index 775938a96146..5f684dc5dda1 100644 --- a/components/clm/src/biogeochem/CNDecompMod.F90 +++ b/components/clm/src/biogeochem/CNDecompMod.F90 @@ -818,13 +818,13 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so 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 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) From 0a08490a4c063947e1523d4c639528fbde358691 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Wed, 28 Jun 2017 18:14:03 -0400 Subject: [PATCH 24/35] change pflotran mass balance check functions from public to private --- .../src/main/clm_interface_pflotranMod.F90 | 466 +----------------- 1 file changed, 25 insertions(+), 441 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 78a2f96e0b8d..3dd89881e81a 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -91,10 +91,10 @@ module clm_interface_pflotranMod public :: clm_pf_finalize !! pflotran mass balance check - public :: clm_pf_BeginCBalance - public :: clm_pf_BeginNBalance - public :: clm_pf_CBalanceCheck - public :: clm_pf_NBalanceCheck + private :: clm_pf_BeginCBalance + private :: clm_pf_BeginNBalance + private :: clm_pf_CBalanceCheck + private :: clm_pf_NBalanceCheck private :: pflotran_not_available @@ -353,436 +353,14 @@ subroutine clm_pf_finalize() end subroutine clm_pf_finalize -!!-------------------------------------------------------------------------------------- - 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 -!!-------------------------------------------------------------------------------------- - - -#ifdef CLM_PFLOTRAN !************************************************************************************! ! (BEGIN) ! Private interface subroutines, requiring explicit coupling between CLM and PFLOTRAN - +! +#ifdef CLM_PFLOTRAN !==================================================================================================== ! ! @@ -804,8 +382,8 @@ subroutine interface_init(bounds) ! !USES: use clm_varctl , only : iulog use GridcellType , only : grc - use LandunitType , only : lun_pp - use ColumnType , only : col_pp + use LandunitType , only : lun + use ColumnType , only : col use landunit_varcon , only : istsoil, istcrop use decompMod , only : get_proc_global, get_proc_clumps, ldecomp use spmdMod , only : mpicom, masterproc, iam, npes @@ -877,14 +455,13 @@ subroutine interface_init(bounds) 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 + ltype => lun%itype , & ! [integer (:)] landunit type index + lgridcell => lun%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 - + cgridcell => col%gridcell , & ! [integer (:)] gridcell index of column + clandunit => col%landunit , & ! [integer (:)] landunit index of column + cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell) + cactive => col%active & ! [logic (:)] column active or not ) @@ -1067,8 +644,17 @@ subroutine interface_init(bounds) ! (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 + 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 + + ) !(2a) domain/decompose clm_pf_idata%nzclm_mapped = nlevgrnd ! the soil layer no. mapped btw CLM and PF for data-passing @@ -4928,7 +4514,6 @@ subroutine clm_pf_checkerr(ierr, subname, filename, line) end subroutine clm_pf_checkerr - !!-------------------------------------------------------------------------------------- subroutine clm_pf_BeginCBalance(clm_interface_data, bounds, filters, ifilter) ! @@ -4993,7 +4578,6 @@ subroutine clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter) 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 , & From 260a7ff6e705329849777f17c6e57ed96e5c7fde Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 29 Jun 2017 11:46:15 -0400 Subject: [PATCH 25/35] move private functions (mass balance) into #ifdef CLM_PFLOTRAN --- components/clm/src/main/clm_interface_pflotranMod.F90 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 3dd89881e81a..b612c6853797 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -90,13 +90,6 @@ module clm_interface_pflotranMod public :: clm_pf_write_restart public :: clm_pf_finalize - !! pflotran mass balance check - private :: clm_pf_BeginCBalance - private :: clm_pf_BeginNBalance - private :: clm_pf_CBalanceCheck - private :: clm_pf_NBalanceCheck - - private :: pflotran_not_available #ifdef CLM_PFLOTRAN From d497bae61918080779249818d170725902b7b9a4 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 29 Jun 2017 13:07:05 -0400 Subject: [PATCH 26/35] initialize local variables to 0: smin_nh4/no3_to_plant_vr_loc --- components/clm/src/biogeochem/CNDecompMod.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/clm/src/biogeochem/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90 index 5f684dc5dda1..775938a96146 100644 --- a/components/clm/src/biogeochem/CNDecompMod.F90 +++ b/components/clm/src/biogeochem/CNDecompMod.F90 @@ -818,13 +818,13 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so 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 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) From b3a0fde5bc6716b818f1fd828d42da070cad8f2e Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Sat, 15 Jul 2017 12:39:05 -0400 Subject: [PATCH 27/35] change col to col_pp --- components/clm/src/main/clm_interface_pflotranMod.F90 | 8 ++++---- components/clm/src/main/filterMod.F90 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index b612c6853797..00f2e0b1db24 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -1879,7 +1879,7 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) l = clandunit(c) if ( (ltype(l)==istsoil .or. ltype(l)==istcrop) .and. & - (col%active(c) .and. cwtgcell(c)>0._r8) ) then ! skip inactive or zero-weighted column (may be not needed, but in case) + (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 @@ -2933,7 +2933,7 @@ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) !------------------------------------------------------------------------------------------ ! associate ( & - cgridcell => col%gridcell , & ! column's gridcell + 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 , & @@ -3423,7 +3423,7 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i ! ! ! !USES: - use ColumnType , only : col + use ColumnType , only : col_pp use clm_varpar , only : nlevgrnd use clm_varcon , only : tfrz @@ -3562,7 +3562,7 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) ! 'mass_balance' retrieving from PFLOTRAN ! ! !USES: - use ColumnType , only : col + use ColumnType , only : col_pp use clm_varpar , only : nlevgrnd use clm_varcon , only : tfrz, denh2o use landunit_varcon , only : istsoil, istcrop diff --git a/components/clm/src/main/filterMod.F90 b/components/clm/src/main/filterMod.F90 index e6784ecadce0..2b73636c3434 100644 --- a/components/clm/src/main/filterMod.F90 +++ b/components/clm/src/main/filterMod.F90 @@ -377,7 +377,7 @@ subroutine setFiltersOneGroup(bounds, this_filter, include_inactive, icemask_grc f = f + 1 this_filter(nc)%hydrologyc(f) = c - if (col%itype(c) == icol_road_perv) then + if (col_pp%itype(c) == icol_road_perv) then fn = fn + 1 this_filter(nc)%hydrononsoic(fn) = c end if From e14ed7aa12e0c6d8393129a01ff927d31243eb79 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Tue, 18 Jul 2017 13:06:12 -0400 Subject: [PATCH 28/35] change grc/lun/col to grc_pp/lun_pp/col_pp --- .../src/main/clm_interface_pflotranMod.F90 | 108 +++++------------- 1 file changed, 31 insertions(+), 77 deletions(-) diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 00f2e0b1db24..787639589fce 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -293,7 +293,6 @@ subroutine clm_pf_run(clm_interface_data, bounds, filters, ifilter) 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) @@ -305,7 +304,6 @@ subroutine clm_pf_run(clm_interface_data, bounds, filters, ifilter) 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 @@ -374,9 +372,9 @@ subroutine interface_init(bounds) ! ! !USES: use clm_varctl , only : iulog - use GridcellType , only : grc - use LandunitType , only : lun - use ColumnType , only : col + 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 @@ -448,13 +446,13 @@ subroutine interface_init(bounds) associate( & ! Assign local pointers to derived subtypes components (landunit-level) - ltype => lun%itype , & ! [integer (:)] landunit type index - lgridcell => lun%gridcell , & ! [integer (:)] gridcell index of landunit + 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%gridcell , & ! [integer (:)] gridcell index of column - clandunit => col%landunit , & ! [integer (:)] landunit index of column - cwtgcell => col%wtgcell , & ! [real(r8) (:)] weight (relative to gridcell) - cactive => col%active & ! [logic (:)] column active or not + 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 ) @@ -602,7 +600,7 @@ subroutine interface_init(bounds) if( (ltype(l)==istsoil .or. ltype(l)==istcrop) .and. & (cactive(c) .and. cwtgcell(c)>0._r8) ) then - mapped_gid(gcount) = grc%gindex(g) ! this is the globally grid-index, i.e. 'an' in its original calculation + 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 @@ -637,17 +635,8 @@ subroutine interface_init(bounds) ! (1) Initialize PETSc vector for data transfer between CLM and PFLOTRAN call CLMPFLOTRANIDataInit() - 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 - - ) + !---------------------------------------------------------------------------------------- + ! (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 @@ -1170,7 +1159,6 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) 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 @@ -1224,7 +1212,6 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (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) @@ -1237,9 +1224,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) 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 @@ -1329,7 +1314,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! get soil column dimension to PFLOTRAN ! ! !USES: - use GridcellType , only : grc + use GridcellType , only : grc_pp use LandunitType , only : lun_pp use ColumnType , only : col_pp @@ -1404,7 +1389,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) lelev => ldomain%topo , & ! [real(r8) (:)] larea => ldomain%area , & ! [real(r8) (:)] ! landunit - ltype => lun%itype , & ! [integer (:)] landunit type index + 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 @@ -1414,7 +1399,6 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) 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) - ) @@ -1557,11 +1541,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) do j = 1, clm_pf_idata%nzclm_mapped if (j <= nlevgrnd) then - ! note that filters%soilc includes 'istsoil' and 'istcrop' - ! (TODO: checking col_pp%itype and lun%itype - appears not match with each other, and col_pp%itype IS messy) - if (ltype(l)==istsoil .or. ltype(l)==istcrop) then - gcount = gcount + 1 ! actually is the active soil column count - cellcount = (gcount-1)*clm_pf_idata%nzclm_mapped + j ! 1-based + cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based xsoil_clm_loc(cellcount) = lonc(g) ysoil_clm_loc(cellcount) = latc(g) @@ -1615,7 +1595,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) cellcount = gcount*clm_pf_idata%nzclm_mapped + j ! 1-based - cellid_clm_loc(cellcount) = (grc%gindex(g)-1)*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) @@ -1743,7 +1723,6 @@ subroutine get_clm_soil_properties(clm_interface_data, bounds, filters) ! 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 @@ -2294,7 +2273,6 @@ end subroutine get_clm_iceadj_porosity !----------------------------------------------------------------------------- !BOP - ! ! !IROUTINE: get_clm_bcwflx ! @@ -2375,7 +2353,6 @@ subroutine get_clm_bcwflx(clm_interface_data, bounds, filters, ifilter) 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) @@ -2743,7 +2720,6 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) 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) @@ -2885,6 +2861,7 @@ subroutine get_clm_bceflx(clm_interface_data, bounds, filters, ifilter) end associate end subroutine get_clm_bceflx + ! !----------------------------------------------------------------------------- ! ! @@ -2978,7 +2955,7 @@ subroutine get_clm_bgc_conc(clm_interface_data, bounds, filters, ifilter) gcount = -1 do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = col_pp%gridcell(c) + g = cgridcell(c) #ifdef COLUMN_MODE if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering) @@ -3101,7 +3078,6 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) ! 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 @@ -3156,9 +3132,8 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) ! operating via 'filters' gcount = -1 do fc = 1,filters(ifilter)%num_soilc - c = filters(ifilter)%soilc(fc) - g = col_pp%gridcell(c) + g = cgridcell(c) #ifdef COLUMN_MODE if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering) @@ -3321,12 +3296,14 @@ subroutine update_soil_moisture_pf2clm(clm_interface_data, bounds, filters, ifil !----------------------------------------------------------------------- associate ( & cgridcell => col_pp%gridcell , & ! column's gridcell - dz => clm_interface_data%dz , & ! layer thickness depth (m) - watsat => clm_interface_data%watsat_col , & ! volumetric soil water at saturation (porosity) (nlevgrnd) - soilpsi => clm_interface_data%soilpsi_col , & ! soil water matric potential in each soil layer (MPa) - h2osoi_liq => clm_interface_data%h2osoi_liq_col, & ! liquid water (kg/m2) - h2osoi_ice => clm_interface_data%h2osoi_ice_col, & ! ice lens (kg/m2) - h2osoi_vol => clm_interface_data%h2osoi_vol_col & ! volumetric soil water (0<=h2osoi_vol<=watsat) [m3/m3] + 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) @@ -3503,28 +3480,6 @@ subroutine update_soil_temperature_pf2clm(clm_interface_data, bounds, filters, i 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 - - - ! define frost table as first frozen layer with unfrozen layer above it do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) @@ -3629,8 +3584,7 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) gcount = -1 do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) - g = cgridcell%gridcell(c) - + g = cgridcell(c) #ifdef COLUMN_MODE if (mapped_gcount_skip(c-bounds%begc+1)) cycle ! skip inactive column (and following numbering) @@ -3655,7 +3609,6 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) 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) & @@ -3676,7 +3629,6 @@ subroutine update_bcflow_pf2clm(clm_interface_data, bounds, filters, ifilter) end associate end subroutine update_bcflow_pf2clm - ! !----------------------------------------------------------------------------- ! @@ -4422,7 +4374,6 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter 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 @@ -4571,6 +4522,7 @@ subroutine clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter) 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 , & @@ -4937,4 +4889,6 @@ end subroutine clm_pf_NBalanceCheck ! (END) !************************************************************************************! + end module clm_interface_pflotranMod + From 0ef15183eab33d4a2bd0776c33b90cf405c3c8d2 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Tue, 18 Jul 2017 13:09:16 -0400 Subject: [PATCH 29/35] configure machines/compilers for ALM-PFLOTRAN coupling --- cime/config/acme/machines/config_compilers.xml | 12 ++++++++++++ cime/config/acme/machines/config_machines.xml | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/cime/config/acme/machines/config_compilers.xml b/cime/config/acme/machines/config_compilers.xml index 7abe72709771..1e7362e9c8d0 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 + From 7ce71719a43ba0da4f63a061e89eb4805ebd12c1 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Tue, 18 Jul 2017 13:12:22 -0400 Subject: [PATCH 30/35] Makefile: update "PETSC_LIB"-"variables" dir for petsc-git-version 1a9d3c3 --- cime/config/acme/machines/Makefile | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cime/config/acme/machines/Makefile b/cime/config/acme/machines/Makefile index 75b11dd70f48..76692158fc14 100644 --- a/cime/config/acme/machines/Makefile +++ b/cime/config/acme/machines/Makefile @@ -251,8 +251,13 @@ 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 + # (UPDATED: 2017-May-19) + # include $(PETSC_PATH)/conf/variables + # 1) petsc-git-version: 1a9d3c3c50abf60098813fdf7291fe3540415115 + # 2) in this petsc package, "PETSC_LIB" contains "-L$LIB_PETSC" + include $(PETSC_PATH)/lib/petsc/conf/variables + endif # Set Trilinos info if it is being used @@ -542,7 +547,10 @@ endif # Add PETSc libraries ifeq ($(strip $(USE_PETSC)), TRUE) - SLIBS += -L${LIB_PETSC} ${PETSC_LIB} + # SLIBS += -L${LIB_PETSC} ${PETSC_LIB} + # 1) petsc-git-version: 1a9d3c3c50abf60098813fdf7291fe3540415115 + # 2) in this petsc package, "PETSC_LIB" contains "-L$LIB_PETSC" + SLIBS += ${PETSC_LIB} endif # Add trilinos libraries; too be safe, we include all libraries included in the trilinos build, @@ -877,7 +885,7 @@ cleanrof: $(RM) -fr $(EXEROOT)/rof/obj cleanlnd: - $(RM) -f $(LIBROOT)/liblnd.a + $(RM) -f $(LIBROOT)/$(LNDLIB) $(RM) -fr $(EXEROOT)/lnd/obj cleancsmshare: From 9c48dba4ee2fea37ffce2e9df4003cc682fa2218 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Thu, 20 Jul 2017 11:44:23 -0400 Subject: [PATCH 31/35] config_machines: delete space in PFLOTRAN configuration for mach 'cades' --- cime/config/acme/machines/config_machines.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cime/config/acme/machines/config_machines.xml b/cime/config/acme/machines/config_machines.xml index 25ae6cf896a9..c7ac0f539246 100644 --- a/cime/config/acme/machines/config_machines.xml +++ b/cime/config/acme/machines/config_machines.xml @@ -1717,12 +1717,12 @@ - /software/user_tools/current/cades-ccsi/petsc4pf/openmpi-1.10-gcc-5.3 + /software/user_tools/current/cades-ccsi/petsc4pf/openmpi-1.10-gcc-5.3 - FALSE - FALSE + FALSE + FALSE - /lustre/or-hydra/cades-ccsi/$USER/models/pflotran-interface/src/clm-pflotran + /lustre/or-hydra/cades-ccsi/$USER/models/pflotran-interface/src/clm-pflotran From ed927ce7e8cab8f88006db39b605c9c789a3059d Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Tue, 25 Jul 2017 11:45:55 -0400 Subject: [PATCH 32/35] Makefile: delete comments. Update 'PETSC_LIB' dir for petsc-git-version 1a9d3c3. In this version, "PETSC_LIB" contains "-L$LIB_PETSC" --- cime/config/acme/machines/Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cime/config/acme/machines/Makefile b/cime/config/acme/machines/Makefile index 76692158fc14..ed0eb60e47ab 100644 --- a/cime/config/acme/machines/Makefile +++ b/cime/config/acme/machines/Makefile @@ -252,10 +252,6 @@ ifeq ($(strip $(USE_PETSC)), TRUE) endif # Get the "PETSC_LIB" list an env var - # (UPDATED: 2017-May-19) - # include $(PETSC_PATH)/conf/variables - # 1) petsc-git-version: 1a9d3c3c50abf60098813fdf7291fe3540415115 - # 2) in this petsc package, "PETSC_LIB" contains "-L$LIB_PETSC" include $(PETSC_PATH)/lib/petsc/conf/variables endif @@ -547,9 +543,6 @@ endif # Add PETSc libraries ifeq ($(strip $(USE_PETSC)), TRUE) - # SLIBS += -L${LIB_PETSC} ${PETSC_LIB} - # 1) petsc-git-version: 1a9d3c3c50abf60098813fdf7291fe3540415115 - # 2) in this petsc package, "PETSC_LIB" contains "-L$LIB_PETSC" SLIBS += ${PETSC_LIB} endif From ecadec72b376b268fcd2b99fcdd5a31c40aec144 Mon Sep 17 00:00:00 2001 From: Gangsheng Wang Date: Tue, 25 Jul 2017 12:56:38 -0400 Subject: [PATCH 33/35] format or delete comments --- .../clm/src/biogeochem/CNAllocationMod.F90 | 58 ++-- .../clm/src/biogeochem/CNBalanceCheckMod.F90 | 2 +- .../clm/src/biogeochem/CNCStateUpdate3Mod.F90 | 4 +- .../clm/src/biogeochem/CNCarbonFluxType.F90 | 46 +--- .../src/biogeochem/CNDecompCascadeBGCMod.F90 | 6 +- .../src/biogeochem/CNDecompCascadeCNMod.F90 | 6 +- components/clm/src/biogeochem/CNDecompMod.F90 | 102 +++---- .../clm/src/biogeochem/CNEcosystemDynMod.F90 | 63 +++-- .../clm/src/biogeochem/CNNStateUpdate1Mod.F90 | 2 +- .../clm/src/biogeochem/CNNStateUpdate2Mod.F90 | 2 +- .../clm/src/biogeochem/CNNStateUpdate3Mod.F90 | 6 +- .../clm/src/biogeochem/CNNitrogenFluxType.F90 | 61 ++--- .../clm/src/biogeochem/PStateUpdate1Mod.F90 | 2 +- .../clm/src/biogeochem/PStateUpdate2Mod.F90 | 2 +- .../clm/src/biogeochem/PStateUpdate3Mod.F90 | 2 +- .../clm/src/biogeochem/PhosphorusFluxType.F90 | 50 ++-- components/clm/src/main/clm_driver.F90 | 56 ++-- components/clm/src/main/clm_initializeMod.F90 | 4 +- components/clm/src/main/clm_instMod.F90 | 1 - .../clm/src/main/clm_interface_bgcType.F90 | 60 ++--- .../clm/src/main/clm_interface_dataType.F90 | 32 +-- .../clm/src/main/clm_interface_funcsMod.F90 | 253 +++++++++--------- .../src/main/clm_interface_pflotranMod.F90 | 131 +++++---- .../clm/src/main/clm_interface_thType.F90 | 36 ++- components/clm/src/main/controlMod.F90 | 8 +- components/clm/src/main/surfrdMod.F90 | 26 +- components/clm/src/utils/clm_time_manager.F90 | 6 +- components/clm/src/utils/domainMod.F90 | 12 +- 28 files changed, 484 insertions(+), 555 deletions(-) diff --git a/components/clm/src/biogeochem/CNAllocationMod.F90 b/components/clm/src/biogeochem/CNAllocationMod.F90 index ab13916c885a..7a971b4730b2 100755 --- a/components/clm/src/biogeochem/CNAllocationMod.F90 +++ b/components/clm/src/biogeochem/CNAllocationMod.F90 @@ -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,& @@ -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 @@ -1156,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) @@ -1271,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 @@ -1299,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) @@ -2887,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 , & @@ -2895,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: @@ -2906,7 +2906,7 @@ 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 @@ -2932,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) @@ -4026,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: @@ -4075,7 +4074,7 @@ subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitr 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) !!original: if (use_nitrif_denitrif): sminn_tot(c) = sminn_tot(c) + (smin_no3_vr(c,j) + smin_nh4_vr(c,j)) * dzsoi_decomp(j) + sminn_tot(c) = sminn_tot(c) + sminn_vr_loc(c,j) * dzsoi_decomp(j) end if end do end do @@ -4088,7 +4087,7 @@ subroutine calc_nuptake_prof(bounds, num_soilc, filter_soilc, cnstate_vars, nitr 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) + 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) @@ -4101,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: @@ -4149,7 +4147,7 @@ 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 end do diff --git a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 index ecc5074aa785..ba46eeade070 100644 --- a/components/clm/src/biogeochem/CNBalanceCheckMod.F90 +++ b/components/clm/src/biogeochem/CNBalanceCheckMod.F90 @@ -441,7 +441,7 @@ 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( & diff --git a/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 b/components/clm/src/biogeochem/CNCStateUpdate3Mod.F90 index 4d51ce5599fa..6bf0742505e5 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 @@ -72,7 +72,7 @@ subroutine CStateUpdate3( num_soilc, filter_soilc, num_soilp, filter_soilp, & 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)) + 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 e66ddfade90a..3c1aae8100be 100644 --- a/components/clm/src/biogeochem/CNCarbonFluxType.F90 +++ b/components/clm/src/biogeochem/CNCarbonFluxType.F90 @@ -4819,7 +4819,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil 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 @@ -4949,7 +4949,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil c = filter_soilc(fc) this%litterc_loss_col(c) = this%lithr_col(c) end do - end if !!(.not.(use_pflotran .and. pf_cmode)) + end if !(.not.(use_pflotran .and. pf_cmode)) do l = 1, ndecomp_pools if ( is_litter(l) ) then @@ -5029,12 +5029,12 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil 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 ! @@ -5054,10 +5054,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,7 +5066,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc) ) dtime = get_step_size() -!!--------------------------------------------------------------------------------------------------- +!--------------------------------------------------------------------------------------------------- ! total heterotrophic respiration (HR) this%hr_col(:) = 0._r8 do j = 1,nlevdecomp_full @@ -5159,9 +5156,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc) + 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%m_c_to_litr_met_fire_col(c,j) elseif (l==i_cel_lit) then this%externalc_to_decomp_cpools_col(c,j,l) = & @@ -5170,9 +5165,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc) + 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%m_c_to_litr_cel_fire_col(c,j) elseif (l==i_lig_lit) then this%externalc_to_decomp_cpools_col(c,j,l) = & @@ -5181,9 +5174,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc) + 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%m_c_to_litr_lig_fire_col(c,j) ! for cwd elseif (l==i_cwd) then @@ -5193,18 +5184,7 @@ subroutine CSummary_interface(this, bounds, num_soilc, filter_soilc) + 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 - !! wgs:2017 -! 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%fire_mortality_c_to_cwdc_col(c,j) end if @@ -5231,7 +5211,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) @@ -5337,8 +5317,8 @@ subroutine summary_cflux_for_ch4( this, bounds, num_soilp, filter_soilp, num_soi this%lithr_col(c) = 0._r8 this%decomp_cascade_hr_col(c,1:ndecomp_cascade_transitions)= 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 + ! 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 diff --git a/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90 b/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90 index 236f2038a4e1..4c0ff8a6c8e3 100644 --- a/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90 +++ b/components/clm/src/biogeochem/CNDecompCascadeBGCMod.F90 @@ -685,7 +685,7 @@ subroutine decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, & 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_pools => decomp_cascade_con%decomp_k_pools & !(0: ndecomp_pools) !! pflotran (0 for atm. co2) + decomp_k_pools => decomp_cascade_con%decomp_k_pools & !(0: ndecomp_pools) ! pflotran (0 for atm. co2) ) mino2lim = CNParamsShareInst%mino2lim @@ -753,7 +753,7 @@ 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 + ! 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 @@ -761,7 +761,7 @@ subroutine decomp_rate_constants_bgc(bounds, num_soilc, filter_soilc, & decomp_k_pools(i_soil1) = k_s1 decomp_k_pools(i_soil2) = k_s2 decomp_k_pools(i_soil3) = k_s3 - !! pflotran:end + ! pflotran:end ! The following code implements the acceleration part of the AD spinup algorithm if ( spinup_state .eq. 1 ) then diff --git a/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90 b/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90 index e1697958cf28..3d6a9ecdecf3 100644 --- a/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90 +++ b/components/clm/src/biogeochem/CNDecompCascadeCNMod.F90 @@ -695,7 +695,7 @@ subroutine decomp_rate_constants_cn(bounds, & 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_pools => decomp_cascade_con%decomp_k_pools & !(0: ndecomp_pools) !! pflotran (0 for atm. co2) + decomp_k_pools => decomp_cascade_con%decomp_k_pools & !(0: ndecomp_pools) ! pflotran (0 for atm. co2) ) mino2lim = CNParamsShareInst%mino2lim @@ -760,7 +760,7 @@ 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 + ! 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 @@ -769,7 +769,7 @@ subroutine decomp_rate_constants_cn(bounds, & 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 + ! 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. diff --git a/components/clm/src/biogeochem/CNDecompMod.F90 b/components/clm/src/biogeochem/CNDecompMod.F90 index 775938a96146..96228d6c30b8 100644 --- a/components/clm/src/biogeochem/CNDecompMod.F90 +++ b/components/clm/src/biogeochem/CNDecompMod.F90 @@ -35,7 +35,7 @@ module CNDecompMod use WaterStateType , only : waterstate_type use ch4Mod , only : ch4_type use cropType , only : crop_type - !! clm interface & pflotran: + ! clm interface & pflotran: use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode ! implicit none @@ -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,9 +212,9 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, & actual_immob_p_vr => phosphorusflux_vars%actual_immob_p_vr_col & ) -!!------------------------------------------------------------------------------------------------- + !------------------------------------------------------------------------------------------------- ! 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 @@ -384,10 +384,10 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, & end do -!!------------------------------------------------------------------------------------------------- -!! '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 -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- +! '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, & @@ -415,9 +415,9 @@ subroutine CNDecompAlloc (bounds, num_soilc, filter_soilc, & ! resolution of plant/heterotroph competition for mineral N - !!------------------------------------------------------------------------------------------------- - !! [wgs,6/22/2017]: delete c:n,c:p ratios calculation, they have been calculated at the beginning of this subroutine - !!------------------------------------------------------------------------------------------------- + !------------------------------------------------------------------------------------------------- + ! 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. @@ -579,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, & @@ -587,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 @@ -683,11 +683,11 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so ! 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 + !------------------------------------------------------------------ + ! '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 @@ -778,7 +778,7 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so carbonflux_vars, nitrogenflux_vars, & phosphorusstate_vars, phosphorusflux_vars) - !! save variables before updating + ! save variables before updating do fc = 1,num_soilc c = filter_soilc(fc) do j = 1,nlevdecomp @@ -787,9 +787,9 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so end do end do - end if !!if(use_clm_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 , & @@ -800,12 +800,12 @@ 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 -!! wgs: 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) + ! 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 @@ -815,8 +815,8 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so smin_nh4_vr(c,j) = max(0._r8, smin_nh4_vr(c,j)) end do end do - end if !!(use_pflotran.and.pf_cmode) -!!------------------------------------------------------------------ + 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) @@ -838,7 +838,7 @@ subroutine CNDecompAlloc2 (bounds, num_soilc, filter_soilc, num_soilp, filter_so end associate end subroutine CNDecompAlloc2 -!!------------------------------------------------------------------------------------------------- + !------------------------------------------------------------------------------------------------- ! subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, & carbonflux_vars, nitrogenflux_vars, phosphorusstate_vars,phosphorusflux_vars) @@ -902,9 +902,9 @@ subroutine CNvariables_nan4pf (bounds, num_soilc, filter_soilc, num_soilp, filte num_column=num_soilc, filter_column=filter_soilc, value_column=0._r8 ) end if - end associate - end subroutine CNvariables_nan4pf + 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 279b5d73674d..a5bd39446028 100755 --- a/components/clm/src/biogeochem/CNEcosystemDynMod.F90 +++ b/components/clm/src/biogeochem/CNEcosystemDynMod.F90 @@ -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 !----------------------------------------------------------------------- @@ -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,8 +428,8 @@ subroutine CNEcosystemDynNoLeaching1(bounds, & atm2lnd_vars, phosphorusflux_vars) call t_stopf('PDeposition') -!!------------------------------------------------------------------------------------------------- -!! plfotran: 'decomp_rate_constants' must be calculated before entering "clm_interface" + !------------------------------------------------------------------------------------------------- + ! 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) @@ -439,15 +438,15 @@ subroutine CNEcosystemDynNoLeaching1(bounds, & 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 + !------------------------------------------------------------------------------------------------- + ! '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_clm_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 @@ -560,8 +559,8 @@ subroutine CNEcosystemDynNoLeaching2(bounds, & call t_startf('CNDecompAlloc') !---------------------------------------------------------------- if(.not.use_clm_interface) then - !! directly run clm-bgc - !! if (use_clm_interface & use_clm_bgc), then CNDecomAlloc is called in clm_driver + ! 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_clm_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 1ec30ff6ab12..129a3c12bf5a 100644 --- a/components/clm/src/biogeochem/CNNStateUpdate1Mod.F90 +++ b/components/clm/src/biogeochem/CNNStateUpdate1Mod.F90 @@ -17,7 +17,7 @@ module CNNStateUpdate1Mod use CNNitrogenFluxType , only : nitrogenflux_type use CNNitrogenStateType , only : nitrogenstate_type use VegetationType , only : veg_pp - !! 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 07af3c68e016..1e8a55c26903 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 afd5cc09e11a..8409c360dff4 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,7 +74,7 @@ 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 !!wgs:2017 + 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 @@ -88,7 +88,7 @@ subroutine NStateUpdate3(num_soilc, filter_soilc, num_soilp, filter_soilp, & 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 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 3a4f5ce3fa83..65c176f53119 100644 --- a/components/clm/src/biogeochem/CNNitrogenFluxType.F90 +++ b/components/clm/src/biogeochem/CNNitrogenFluxType.F90 @@ -13,7 +13,7 @@ module CNNitrogenFluxType use LandunitType , only : lun_pp use ColumnType , only : col_pp use VegetationType , only : veg_pp - !! bgc interface & pflotran: + ! bgc interface & pflotran: use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc ! ! !PUBLIC TYPES: @@ -341,7 +341,7 @@ module CNNitrogenFluxType ! 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) @@ -1910,8 +1910,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', & @@ -1952,7 +1952,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', & @@ -1982,8 +1982,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 !----------------------------------------------------------------------- @@ -2259,7 +2259,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 @@ -2570,7 +2570,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 @@ -3087,12 +3087,12 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil !---------------------------------------------------------------- end subroutine Summary -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- ! !INTERFACE: subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) ! ! !DESCRIPTION: -!! bgc interface & pflotran: +! bgc interface & pflotran: ! On the radiation time step, perform column-level nitrogen ! summary calculations, which mainly from PFLOTRAN bgc coupling ! @@ -3113,8 +3113,6 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) ! !CALLED FROM: ! 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 @@ -3125,9 +3123,9 @@ 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) -!! wgs:beg------------------------------------------------ -!! NOT used currently + ! 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 @@ -3145,7 +3143,7 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) this%denit_col(c) = this%f_denit_col(c) end do -!! wgs:end------------------------------------------------ + !end------------------------------------------------ ! the following are from pflotran bgc, and vertically down to 'nlevdecomp_full' do fc = 1,num_soilc @@ -3197,13 +3195,13 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) 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 + 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) - end do !!fc = 1,num_soilc + end do !fc = 1,num_soilc ! summarize at column-level vertically-resolved littering/removal for PFLOTRAN bgc input needs @@ -3241,8 +3239,7 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) + 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%m_n_to_litr_met_fire_col(c,j) elseif (l==i_cel_lit) then this%externaln_to_decomp_npools_col(c,j,l) = & @@ -3251,8 +3248,7 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) + 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%m_n_to_litr_cel_fire_col(c,j) elseif (l==i_lig_lit) then this%externaln_to_decomp_npools_col(c,j,l) = & @@ -3261,8 +3257,7 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) + 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%m_n_to_litr_lig_fire_col(c,j) ! for cwd elseif (l==i_cwd) then @@ -3274,12 +3269,6 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) + 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) - end if ! the following is the net changes of plant N to decompible N poools between time-step @@ -3294,9 +3283,9 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) this%externaln_to_decomp_npools_col(c,j,l) = 0._r8 end if - end do !!l = 1, ndecomp_pools - end do !!j = 1, nlevdecomp_full - end do !!fc = 1,num_soilc + 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: @@ -3320,10 +3309,10 @@ subroutine NSummary_interface(this,bounds,num_soilc, filter_soilc) this%externaln_to_decomp_delta_col(c) = -this%externaln_to_decomp_delta_col(c) end do - end if !! if (use_pflotran .and. pf_cmode) + end if ! if (use_pflotran .and. pf_cmode) end subroutine NSummary_interface -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- end module CNNitrogenFluxType diff --git a/components/clm/src/biogeochem/PStateUpdate1Mod.F90 b/components/clm/src/biogeochem/PStateUpdate1Mod.F90 index 8f71a6be3341..f33697be721e 100644 --- a/components/clm/src/biogeochem/PStateUpdate1Mod.F90 +++ b/components/clm/src/biogeochem/PStateUpdate1Mod.F90 @@ -18,7 +18,7 @@ module PStateUpdate1Mod use PhosphorusFluxType , only : phosphorusflux_type use PhosphorusStateType , only : phosphorusstate_type use VegetationType , only : veg_pp - !! 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 b8564a78593a..3da2a3a3c1ee 100644 --- a/components/clm/src/biogeochem/PStateUpdate2Mod.F90 +++ b/components/clm/src/biogeochem/PStateUpdate2Mod.F90 @@ -14,7 +14,7 @@ module PStateUpdate2Mod use PhosphorusFLuxType , only : phosphorusflux_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/PStateUpdate3Mod.F90 b/components/clm/src/biogeochem/PStateUpdate3Mod.F90 index 02c7d68ca2bb..7bea9f9be53f 100644 --- a/components/clm/src/biogeochem/PStateUpdate3Mod.F90 +++ b/components/clm/src/biogeochem/PStateUpdate3Mod.F90 @@ -17,7 +17,7 @@ module PStateUpdate3Mod use PhosphorusStateType , only : phosphorusstate_type use PhosphorusFLuxType , only : phosphorusflux_type use soilorder_varcon , only : smax,ks_sorption - !! 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 cc4c9582194f..4f6622cbb261 100755 --- a/components/clm/src/biogeochem/PhosphorusFluxType.F90 +++ b/components/clm/src/biogeochem/PhosphorusFluxType.F90 @@ -13,7 +13,7 @@ module PhosphorusFluxType use LandunitType , only : lun_pp use ColumnType , only : col_pp use VegetationType , only : veg_pp - !! bgc interface & pflotran: + ! bgc interface & pflotran: use clm_varctl , only : use_clm_interface, use_pflotran, pf_cmode, pf_hmode, use_vertsoilc ! ! !PUBLIC TYPES: @@ -321,7 +321,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 @@ -1487,7 +1487,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', & @@ -1733,7 +1733,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 @@ -1986,7 +1986,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 @@ -2213,7 +2213,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 @@ -2397,7 +2397,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil end do end do - !! bgc interface & pflotran: + ! bgc interface & pflotran: !---------------------------------------------------------------- if (use_clm_interface) then call PSummary_interface(this, bounds, num_soilc, filter_soilc) @@ -2406,12 +2406,12 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil 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 ! @@ -2428,10 +2428,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 @@ -2440,7 +2437,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 @@ -2484,9 +2481,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) = & @@ -2494,9 +2489,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) = & @@ -2504,9 +2497,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 @@ -2515,14 +2506,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 @@ -2548,7 +2532,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) @@ -2563,7 +2547,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/main/clm_driver.F90 b/components/clm/src/main/clm_driver.F90 index 1600f916e275..7b110d7d8aab 100644 --- a/components/clm/src/main/clm_driver.F90 +++ b/components/clm/src/main/clm_driver.F90 @@ -50,7 +50,7 @@ module clm_driver !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 @@ -135,21 +135,21 @@ module clm_driver use shr_sys_mod , only : shr_sys_flush use shr_log_mod , only : errMsg => shr_log_errMsg - !!---------------------------------------------------------------------------- - !! bgc interface & pflotran: + !---------------------------------------------------------------------------- + ! 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 + ! (1) clm_bgc through interface use clm_varctl , only : use_clm_bgc use clm_interface_funcsMod , only : clm_bgc_run, update_bgc_data_clm2clm - !! (2) pflotran + ! (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: @@ -802,11 +802,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_interface: 'CNEcosystemDynNoLeaching' is divided into 2 subroutines (1 & 2): BEGIN - !! CNEcosystemDynNoLeaching1 is called before clm_interface - !! CNEcosystemDynNoLeaching2 is called after clm_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, & @@ -819,9 +819,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) ch4_vars, photosyns_vars, & phosphorusflux_vars,phosphorusstate_vars) - !!-------------------------------------------------------------------------------- + !-------------------------------------------------------------------------------- if (use_clm_interface) then - !! STEP-1: pass data from CLM to clm_interface_data (INTERFACE DATA TYPE) + ! 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, & @@ -839,13 +839,13 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) ! ------------------------------------------------------------------------- ! PFLOTRAN calling for solving below-ground and ground-surface processes, ! including thermal, hydrological and biogeochemical processes - !! 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 + ! 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_interface_data, bounds_clump, filter, nc) - !! STEP-3: update CLM from clm_interface_data + ! 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, & @@ -859,10 +859,10 @@ 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_interface_data to CNDecompAlloc - !! STEP-2: (2) run CNDecompAlloc - !! STEP-2: (3) update clm_interface_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_interface_data, bounds_clump, & filter(nc)%num_soilc, filter(nc)%soilc, & @@ -874,7 +874,7 @@ 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_interface_data + ! 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, & @@ -883,9 +883,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate) 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_clm_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, & @@ -900,9 +900,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_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, & diff --git a/components/clm/src/main/clm_initializeMod.F90 b/components/clm/src/main/clm_initializeMod.F90 index 8d2939e51cbc..f600542abc88 100644 --- a/components/clm/src/main/clm_initializeMod.F90 +++ b/components/clm/src/main/clm_initializeMod.F90 @@ -398,7 +398,7 @@ subroutine initialize2( ) use lnd2glcMod , only : lnd2glc_type use SoilWaterRetentionCurveFactoryMod , only : create_soil_water_retention_curve use clm_varctl , only : use_clm_interface, use_pflotran - use clm_interface_pflotranMod , only : clm_pf_interface_init !!, clm_pf_set_restart_stamp + use clm_interface_pflotranMod , only : clm_pf_interface_init !, clm_pf_set_restart_stamp use betr_initializeMod , only : betr_initialize use betr_initializeMod , only : betrtracer_vars, tracerstate_vars, tracerflux_vars, tracercoeff_vars use betr_initializeMod , only : bgc_reaction @@ -891,7 +891,7 @@ subroutine initialize2( ) deallocate(topo_glc_mec) !------------------------------------------------------------ - !! initialize clm_bgc_interface_data_type + ! 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) diff --git a/components/clm/src/main/clm_instMod.F90 b/components/clm/src/main/clm_instMod.F90 index f5bf24abf411..93f044a57a14 100644 --- a/components/clm/src/main/clm_instMod.F90 +++ b/components/clm/src/main/clm_instMod.F90 @@ -48,7 +48,6 @@ 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 diff --git a/components/clm/src/main/clm_interface_bgcType.F90 b/components/clm/src/main/clm_interface_bgcType.F90 index 4248a00d407d..04c4998e5bae 100644 --- a/components/clm/src/main/clm_interface_bgcType.F90 +++ b/components/clm/src/main/clm_interface_bgcType.F90 @@ -1,14 +1,10 @@ module clm_interface_bgcType -!!================================================================================================= +!================================================================================================= ! CLM BioGeoChemistry (BGC) Interface: Data Type (Variables) -! -! Created by wgs @ ORNL -! -! date: 8/25/2015 -! update: 9/16/2016, 2/2/2017, May-2017 -! modifed by yfm, June-2017 -!!================================================================================================= - !! 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(=) @@ -152,9 +148,9 @@ module clm_interface_bgcType 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 @@ -190,30 +186,30 @@ module clm_interface_bgcType real(r8), pointer :: forc_pco2_grc (:) ! CO2 partial pressure (Pa) real(r8), pointer :: forc_pch4_grc (:) ! CH4 partial pressure (Pa) - !! mass balance check: - !! summary of layer 1:nlevdecomp_full + ! 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 - !!------------------------------------------------------------------------------------------ + !------------------------------------------------------------------------------------------ + ! pflotran variables: END + !------------------------------------------------------------------------------------------ -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- contains procedure , public :: Init procedure , private :: InitAllocate end type clm_interface_bgc_datatype -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- contains -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- subroutine Init(this, bounds) use decompMod , only : bounds_type class(clm_interface_bgc_datatype) :: this @@ -221,23 +217,23 @@ subroutine Init(this, 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_interface_bgc_datatype) :: this type(bounds_type), intent(in) :: bounds - !! LOCAL VARIABLES: + ! LOCAL VARIABLES: integer :: begg, endg integer :: begc, endc integer :: begp, endp @@ -379,9 +375,9 @@ 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 @@ -422,11 +418,11 @@ subroutine InitAllocate(this, bounds) 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 - !!------------------------------------------------------------------------------------------ + !------------------------------------------------------------------------------------------ + ! pflotran variables: END + !------------------------------------------------------------------------------------------ end subroutine InitAllocate -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- 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 index 6f991a9c6d65..0fa87a4429c0 100644 --- a/components/clm/src/main/clm_interface_dataType.F90 +++ b/components/clm/src/main/clm_interface_dataType.F90 @@ -1,15 +1,11 @@ module clm_interface_dataType -!!================================================================================================= +!================================================================================================= ! ALM Thermal(T)-Hydrology (H) & BioGeoChemistry (BGC) Interface: Data Type (Variables) -! -! Created by wgs @ ORNL -! -! date: 8/25/2015 -! update: 9/16/2016, 2/2/2017, May-2017 -! modified by yfm, June-2017 -!!================================================================================================= - !! 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(=) @@ -21,7 +17,7 @@ module clm_interface_dataType private -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- type, public :: clm_interface_data_type ! col dimension @@ -59,12 +55,12 @@ module clm_interface_dataType 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 @@ -77,22 +73,22 @@ subroutine Init(this, bounds) call this%bgc%Init(bounds) end subroutine Init -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- subroutine InitAllocate(this, bounds) - !! USES + ! USES use clm_varpar , only : nlevsno, nlevgrnd use clm_varcon , only : spval use decompMod , only : bounds_type - !! ARGUMENTS: + ! ARGUMENTS: real(r8) :: ival = 0.0_r8 ! initial value class(clm_interface_data_type) :: this type(bounds_type), intent(in) :: bounds - !! LOCAL VARIABLES: + ! LOCAL VARIABLES: integer :: begg, endg integer :: begc, endc integer :: begp, endp @@ -126,6 +122,6 @@ subroutine InitAllocate(this, bounds) 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_interface_funcsMod.F90 b/components/clm/src/main/clm_interface_funcsMod.F90 index 749b5ef238f5..9244698bc0c1 100644 --- a/components/clm/src/main/clm_interface_funcsMod.F90 +++ b/components/clm/src/main/clm_interface_funcsMod.F90 @@ -1,30 +1,27 @@ module clm_interface_funcsMod -!!================================================================================================= +!================================================================================================= ! CLM Theraml-Hydrology (TH) & BioGeoChemistry (BGC) Interface: Modules -! -! Created by wgs @ ORNL -! -! date: 8/25/2015 -! modifed by yfm, June-2017 -!!================================================================================================= +! created: 8/25/2015 +! updated: June-2017 +!================================================================================================= #include "shr_assert.h" - !! 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 - !!-------------------------------------------------------------------------------------- + ! 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 @@ -32,7 +29,7 @@ module clm_interface_funcsMod 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 @@ -74,7 +71,7 @@ module clm_interface_funcsMod ! misc. use abortutils , only : endrun - !!-------------------------------------------------------------------------------------- + !-------------------------------------------------------------------------------------- implicit none @@ -82,24 +79,24 @@ module clm_interface_funcsMod 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_data !! STEP-1: clm vars -> clm_interface_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_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 + ! 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_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 + ! 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 @@ -110,28 +107,28 @@ module clm_interface_funcsMod 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_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 + !-------------------------------------------------------------------------------------- + ! (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_data(clm_idata, & bounds, num_soilc, filter_soilc, & num_soilp, filter_soilp, & @@ -212,9 +209,9 @@ subroutine get_clm_data(clm_idata, & end associate end subroutine get_clm_data -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine get_clm_soil_property(clm_idata, & bounds, num_soilc, filter_soilc, & soilstate_vars, cnstate_vars) @@ -281,7 +278,7 @@ subroutine get_clm_soil_property(clm_idata, & ) !------------------------------------------------------------------------------------- - !! constants: + ! 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(:) @@ -324,9 +321,9 @@ subroutine get_clm_soil_property(clm_idata, & end associate end subroutine get_clm_soil_property -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine get_clm_soil_th_state(clm_idata_th, & bounds, num_soilc, filter_soilc, & atm2lnd_vars, soilstate_vars, & @@ -377,8 +374,7 @@ subroutine get_clm_soil_th_state(clm_idata_th, & !-------------------------------------------------------------------------------------- -! - !! grid: + ! grid: clm_idata_th%forc_pbot_grc = forc_pbot do fc = 1,num_soilc @@ -406,9 +402,9 @@ subroutine get_clm_soil_th_state(clm_idata_th, & end associate end subroutine get_clm_soil_th_state -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine get_clm_soil_th_flux(clm_idata_th, & bounds, num_soilc, filter_soilc, & waterflux_vars, energyflux_vars) @@ -488,10 +484,10 @@ subroutine get_clm_soil_th_flux(clm_idata_th, & end associate end subroutine get_clm_soil_th_flux -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine get_clm_bgc_state(clm_bgc_data, & bounds, num_soilc, filter_soilc, & atm2lnd_vars, soilstate_vars, & @@ -499,7 +495,7 @@ subroutine get_clm_bgc_state(clm_bgc_data, & phosphorusstate_vars, & ch4_vars) - !! get clm bgc state variables + ! get clm bgc state variables implicit none type(bounds_type) , intent(in) :: bounds @@ -587,9 +583,9 @@ subroutine get_clm_bgc_state(clm_bgc_data, & 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, & @@ -598,7 +594,7 @@ subroutine get_clm_bgc_flux(clm_bgc_data, & ! ! !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_curr_date @@ -731,18 +727,18 @@ subroutine get_clm_bgc_flux(clm_bgc_data, & 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%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 do ! fc = 1,num_soilc end associate end subroutine get_clm_bgc_flux -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine update_soil_moisture(clm_idata_th, & bounds, num_soilc, filter_soilc, & soilstate_vars, waterstate_vars) @@ -789,9 +785,9 @@ subroutine update_soil_moisture(clm_idata_th, & end associate end subroutine update_soil_moisture -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine update_soil_temperature(clm_idata_th, & bounds, num_soilc, filter_soilc, & temperature_vars) @@ -827,15 +823,15 @@ subroutine update_soil_temperature(clm_idata_th, & 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 + ! USES use clm_varctl , only : use_pflotran, pf_tmode, pf_hmode implicit none @@ -870,10 +866,10 @@ subroutine update_th_data_pf2clm(clm_idata_th, & 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, & @@ -916,9 +912,9 @@ subroutine update_bgc_state_decomp(clm_bgc_data, & 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) @@ -976,9 +972,9 @@ subroutine update_bgc_state_smin(clm_bgc_data, & 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, & @@ -1017,9 +1013,9 @@ subroutine update_bgc_flux_decomp_sourcesink(clm_bgc_data, & 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, & @@ -1076,9 +1072,9 @@ subroutine update_bgc_flux_decomp_cascade(clm_bgc_data, & 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, & @@ -1182,14 +1178,14 @@ subroutine update_bgc_flux_smin(clm_bgc_data, & 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 + 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, & nitrogenflux_vars, phosphorusflux_vars) @@ -1229,9 +1225,9 @@ subroutine update_bgc_flux_nitdenit(clm_bgc_data, & end do end associate end subroutine update_bgc_flux_nitdenit -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine update_bgc_flux_gas_pf(clm_bgc_data, & bounds, num_soilc, filter_soilc, & carbonflux_vars, nitrogenflux_vars) @@ -1277,9 +1273,9 @@ subroutine update_bgc_flux_gas_pf(clm_bgc_data, & ! 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, & @@ -1287,7 +1283,7 @@ subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, & nitrogenflux_vars, nitrogenstate_vars, & phosphorusflux_vars, phosphorusstate_vars, & ch4_vars) - !! USES + ! USES use clm_varctl , only : use_pflotran, pf_cmode implicit none @@ -1316,8 +1312,8 @@ subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, & 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, & @@ -1340,15 +1336,12 @@ subroutine update_bgc_data_pf2clm(clm_bgc_data, bounds, & end subroutine update_bgc_data_pf2clm -!!-------------------------------------------------------------------------------------- - -!!-------------------------------------------------------------------------------------- - +!-------------------------------------------------------------------------------------- -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- ! BEG of CLM-bgc through interface -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- ! !INTERFACE: subroutine clm_bgc_run(clm_interface_data, bounds, & num_soilc, filter_soilc, & @@ -1360,10 +1353,10 @@ subroutine clm_bgc_run(clm_interface_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 @@ -1384,8 +1377,8 @@ subroutine clm_bgc_run(clm_interface_data, bounds, & type(clm_interface_data_type) , intent(inout) :: clm_interface_data - !!------------------------------------------------------------- - !! STEP-2: (i) pass data from clm_bgc_data to CNDecompAlloc + !------------------------------------------------------------- + ! 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, & @@ -1395,7 +1388,7 @@ subroutine clm_bgc_run(clm_interface_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, & @@ -1405,18 +1398,18 @@ subroutine clm_bgc_run(clm_interface_data, bounds, & nitrogenstate_vars, nitrogenflux_vars, & phosphorusstate_vars,phosphorusflux_vars) - !! STEP-2: (iii) update clm_bgc_data from CNDecompAlloc + ! 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 + ! 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, & @@ -1426,10 +1419,10 @@ subroutine clm_bgc_get_data(clm_interface_data, & 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 @@ -1448,7 +1441,7 @@ subroutine clm_bgc_get_data(clm_interface_data, & type(clm_interface_data_type), intent(in) :: clm_interface_data - !! LOCAL VARIABLES: + ! LOCAL VARIABLES: integer :: fc, c, j, k !----------------------------------------------------------------------- @@ -1496,7 +1489,7 @@ subroutine clm_bgc_get_data(clm_interface_data, & 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) @@ -1528,7 +1521,7 @@ subroutine clm_bgc_get_data(clm_interface_data, & end do - !!state variables + !state variables do fc = 1, num_soilc c = filter_soilc(fc) do k = 1, ndecomp_pools @@ -1551,19 +1544,19 @@ subroutine clm_bgc_get_data(clm_interface_data, & 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 @@ -1575,7 +1568,7 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, & type(clm_interface_bgc_datatype) , intent(inout) :: clm_bgc_data - !! LOCAL VARIABLES: + ! LOCAL VARIABLES: integer :: fc, c, j, k !----------------------------------------------------------------------- @@ -1623,7 +1616,7 @@ subroutine clm_bgc_update_data(clm_bgc_data, bounds, & 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) (:,:) ] @@ -1679,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 @@ -1695,9 +1688,9 @@ 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, & @@ -1705,7 +1698,7 @@ subroutine update_bgc_data_clm2clm(clm_bgc_data,bounds, & nitrogenflux_vars, nitrogenstate_vars, & phosphorusflux_vars, phosphorusstate_vars, & ch4_vars) - !! USES + ! USES implicit none @@ -1732,8 +1725,8 @@ subroutine update_bgc_data_clm2clm(clm_bgc_data,bounds, & 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, & @@ -1749,9 +1742,9 @@ 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_interface_funcsMod diff --git a/components/clm/src/main/clm_interface_pflotranMod.F90 b/components/clm/src/main/clm_interface_pflotranMod.F90 index 787639589fce..59a81f449880 100644 --- a/components/clm/src/main/clm_interface_pflotranMod.F90 +++ b/components/clm/src/main/clm_interface_pflotranMod.F90 @@ -22,7 +22,7 @@ module clm_interface_pflotranMod ! ! date: 2012 - 2017 ! -! Modified by Gangsheng Wang @ ORNL based on clm_bgc_interfaceMod.F90: 8/28/2015, 2/2/2017 +! modified by Gangsheng Wang @ ORNL based on clm_interface: 8/28/2015, 2/2/2017 ! ! yfm: Added Thermal-Hydrology coupling subroutines: 04/2017 !---------------------------------------------------------------------------------------------- @@ -50,7 +50,7 @@ module clm_interface_pflotranMod ! use landunit_varcon , only : istsoil, istcrop ! (dummy) variable definitions - !! (wgs,8/28/2015): ALM types/variables are replaced by clm_interface_data + ! ALM types/variables are replaced by clm_interface_data use clm_interface_dataType, only : clm_interface_data_type @@ -111,7 +111,7 @@ module clm_interface_pflotranMod private :: get_clm_bgc_rate private :: update_soil_bgc_pf2clm private :: update_bgc_gaslosses_pf2clm - !! pflotran mass balance check + ! pflotran mass balance check private :: clm_pf_BeginCBalance private :: clm_pf_BeginNBalance private :: clm_pf_CBalanceCheck @@ -440,8 +440,8 @@ subroutine interface_init(bounds) 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 + real(r8):: lon0, lat0 !origin of longitude/latitude + integer :: nv ! number of vertices class(realization_subsurface_type), pointer :: realization associate( & @@ -456,11 +456,11 @@ subroutine interface_init(bounds) ) - !!wgs:beg---------------------------------------------------------------- - !! wgs: ACME-v2: add lon0/lat0 to ldomain + ! beg---------------------------------------------------------------- + ! lon0/lat0 have been added to ldomain lon0 = ldomain%lon0 lat0 = ldomain%lat0 - !!wgs:end---------------------------------------------------------------- + ! end---------------------------------------------------------------- ! (0) determines Total grids/columns and ids to be mapped between CLM and PFLOTRAN @@ -1099,7 +1099,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) !----------------------------------------------------------------------- - nstep = get_nstep() - pf_clmnstep0 !!nsstep + nstep = get_nstep() - pf_clmnstep0 !nsstep dtime = get_step_size() if (is_first_step() .or. is_first_restart_step()) then @@ -1111,14 +1111,14 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! (0) if (isinitpf) then - call calc_nestep() !! nestep - total_clmstep = nestep - pf_clmnstep0!!nestep - nsstep + 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) - !! wgs:beg------------------------------------------------ - !! wgs: move from 'interface_init' + ! beg------------------------------------------------ + ! move from 'interface_init' ! force CLM soil domain into PFLOTRAN subsurface grids call get_clm_soil_dimension(clm_interface_data, bounds) @@ -1128,7 +1128,7 @@ subroutine pflotran_run_onestep(clm_interface_data, bounds, filters, ifilter) ! Get top surface area of 3-D pflotran subsurface domain call pflotranModelGetTopFaceArea(pflotran_m) - !! wgs:end------------------------------------------------ + ! 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) @@ -1382,7 +1382,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) ! 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/lonv missing in ACME1 latv => ldomain%latv , & ! [real(r8) (:,:)] lonv => ldomain%lonv , & ! [real(r8) (:,:)] @@ -1457,7 +1457,7 @@ subroutine get_clm_soil_dimension(clm_interface_data, bounds) p2 = 0._r8 n1 = 0 n2 = 0 - do v = 1, ldomain%nv !!wgs: ldomain%nv missing in ACME1 + do v = 1, ldomain%nv ! ldomain%nv missing in ACME1 if (lonv(g,v) 0, sucmin < 0, sucsat & sucmin have units of mm - !! psitmp = psitmp0, as denh2o*1.e-3_r8 = 1.0 + ! 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 + psitmp = min(max(psitmp,sucmin_pa),0._r8) !Pa else sattmp = h2osoi_liq(c,j) / (watsat(c,j)*dz(c,j)*denh2o) @@ -2115,7 +2114,7 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, psitmp = min(max(psitmp,sucmin_pa),0._r8) endif - endif !!if(.not.pf_frzmode) + endif !if(.not.pf_frzmode) soillsat_clmp_loc(cellcount) = sattmp soilpsi_clmp_loc(cellcount) = psitmp @@ -2126,7 +2125,7 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, soilvwc_clmp_loc(cellcount) = h2osoi_vol(c,j) - endif !!if (initpfhmode) then + endif !if (initpfhmode) then if (initpftmode) then soilt_clmp_loc(cellcount)=t_soisno(c,j)-tfrz @@ -2137,10 +2136,10 @@ subroutine get_clm_soil_th(clm_interface_data,initpftmode, initpfhmode, bounds, call endrun(trim(subname) // ": ERROR: CLM-PF mapped soil layer numbers is greater than " // & " 'clm_varpar%nlevgrnd'. Please check") - endif !!if (j<=nlevgrnd) then + endif !if (j<=nlevgrnd) then - enddo !!do j = 1, clm_pf_idata%nzclm_mapped - enddo !!do fc = 1,filters(ifilter)%num_soilc + 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__) @@ -3027,7 +3026,7 @@ end subroutine get_clm_bgc_conc ! ! !INTERFACE: subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) -!! TODO: add phosphorus vars +! TODO: add phosphorus vars ! ! !DESCRIPTION: ! @@ -3151,7 +3150,7 @@ subroutine get_clm_bgc_rate(clm_interface_data, bounds, filters, ifilter) ! (nlevdecomp_full = nlevgrnd) if(j <= nlevdecomp_full) then - !! just in case, we need to do some checking first (actually already done before) + ! 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) = & @@ -3643,7 +3642,7 @@ end subroutine update_bcflow_pf2clm ! and the 'CNSoilLittVertTranspMod.F90' after 'update1'. ! subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) -!! TODO: add phosphorus vars +! TODO: add phosphorus vars use ColumnType , only : col_pp use clm_varctl , only : iulog, use_ed use CNDecompCascadeConType , only : decomp_cascade_con @@ -3798,12 +3797,12 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) 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 ) !!/dtime !!wgs: decomp_cpools_delta_vr=> clm_bgc_data%decomp_cpools_sourcesink_col + * 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 + * 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 @@ -3851,8 +3850,8 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) * clm_pf_idata%N_molecular_weight)/dtime endif -!! wgs-beg:-------------------------------------------------------------------------------- -!! directly update the 'smin' N pools (SO, must bypass the 'CNNStateUpdate1,2,3' relevant to soil N) + ! 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 @@ -3863,9 +3862,9 @@ subroutine update_soil_bgc_pf2clm(clm_interface_data, bounds, filters, ifilter) 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) -!! wgs-end:-------------------------------------------------------------------------------- + ! end:-------------------------------------------------------------------------------- - !! flows or changes + ! 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) & @@ -4236,8 +4235,8 @@ subroutine update_bgc_gaslosses_pf2clm(clm_interface_data, bounds, filters, ifil f_ngas_denit_vr(c,j) = 0._r8 endif - enddo !! do j = 1, nlevdecomp_full - enddo !! do fc = 1,filters(ifilter)%num_soilc + enddo ! do j = 1, nlevdecomp_full + enddo ! do fc = 1,filters(ifilter)%num_soilc call VecRestoreArrayReadF90(clm_pf_idata%gco2_vr_clms, gco2_vr_clms_loc, ierr) call clm_pf_checkerr(ierr, subname, __FILE__, __LINE__) @@ -4402,7 +4401,7 @@ subroutine update_bgc_bcflux_pf2clm(clm_interface_data, bounds, filters, ifilter ! (TODO) not yet considering lateral transport (although data structure is here) - enddo !! do fc = 1,filters(ifilter)%num_soilc + 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__) @@ -4458,7 +4457,7 @@ subroutine clm_pf_checkerr(ierr, subname, filename, line) end subroutine clm_pf_checkerr -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine clm_pf_BeginCBalance(clm_interface_data, bounds, filters, ifilter) ! ! !DESCRIPTION: @@ -4499,7 +4498,7 @@ subroutine clm_pf_BeginCBalance(clm_interface_data, bounds, filters, ifilter) end subroutine clm_pf_BeginCBalance -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter) ! @@ -4541,7 +4540,7 @@ subroutine clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter) 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 + !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) @@ -4549,13 +4548,13 @@ subroutine clm_pf_BeginNBalance(clm_interface_data, bounds, filters, ifilter) soil_begnb_org(c) = soil_begnb_org(c) & + decomp_npools_vr(c,j,l)*dzsoi_decomp(j) end do - end do !!j = 1, nlevdecomp + 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) ! @@ -4597,7 +4596,7 @@ subroutine clm_pf_CBalanceCheck(clm_interface_data,bounds, filters, ifilter) ! ------------------------------------------------------------------------ dtime = real( get_step_size(), r8 ) - !! pflotran mass blance check-Carbon + ! pflotran mass blance check-Carbon err_found = .false. do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) @@ -4637,10 +4636,10 @@ subroutine clm_pf_CBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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 if !(.not. use_ed) end associate end subroutine clm_pf_CBalanceCheck -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) ! @@ -4668,31 +4667,31 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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_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_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_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(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(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_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) :: 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) @@ -4728,7 +4727,7 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) ! ------------------------------------------------------------------------ dtime = real( get_step_size(), r8 ) nlev = nlevdecomp_full - !! pflotran mass blance check-Carbon + ! pflotran mass blance check-Carbon err_found = .false. do fc = 1,filters(ifilter)%num_soilc c = filters(ifilter)%soilc(fc) @@ -4768,7 +4767,7 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) pf_errnb_min(fc) = 0._r8 do j = 1, nlev - !! sminn_vr(c,j) has been calculated above + ! 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) @@ -4793,13 +4792,13 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) 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 + 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_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_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) @@ -4817,7 +4816,7 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) err_index = fc end if - !! check SON balance at each layer, + ! 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 @@ -4875,10 +4874,10 @@ subroutine clm_pf_NBalanceCheck(clm_interface_data,bounds, filters, ifilter) ! end do write(iulog,'(A,70(1h-))')">>>-------- PFLOTRAN Mass Balance Check:end " end if - end if !!(.not. use_ed) + end if !(.not. use_ed) end associate end subroutine clm_pf_NBalanceCheck -!!-------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------- !----------------------------------------------------------------------------- diff --git a/components/clm/src/main/clm_interface_thType.F90 b/components/clm/src/main/clm_interface_thType.F90 index f2681bf8d119..6b76a3f01c7a 100644 --- a/components/clm/src/main/clm_interface_thType.F90 +++ b/components/clm/src/main/clm_interface_thType.F90 @@ -1,15 +1,11 @@ module clm_interface_thType -!!================================================================================================= +!================================================================================================= ! ALM Thermal(T)-Hydrology (H) Interface: Data Type (Variables) -! -! Created by wgs @ ORNL -! -! date: 8/25/2015 -! update: 9/16/2016, 2/2/2017 -! modifed by yfm, June-2017 -!!================================================================================================= - !! USES: +! 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(=) @@ -76,12 +72,12 @@ module clm_interface_thType 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 @@ -89,22 +85,22 @@ subroutine Init(this, bounds) call this%InitAllocate (bounds) end subroutine Init -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- -!!------------------------------------------------------------------------------------------------- +!------------------------------------------------------------------------------------------------- subroutine InitAllocate(this, bounds) - !! USES + ! USES use clm_varpar , only : nlevsno, nlevgrnd use clm_varcon , only : spval use decompMod , only : bounds_type - !! ARGUMENTS: + ! ARGUMENTS: real(r8) :: ival = 0.0_r8 ! initial value class(clm_interface_th_datatype) :: this type(bounds_type), intent(in) :: bounds - !! LOCAL VARIABLES: + ! LOCAL VARIABLES: integer :: begg, endg integer :: begc, endc integer :: begp, endp @@ -132,9 +128,9 @@ subroutine InitAllocate(this, bounds) ! canopystate_vars: allocate(this%alt_indx_col (begc:endc)) ; this%alt_indx_col (:) = huge(1) - !!------------------------------------------------------------------------------------------ - !! pflotran variables: BEGIN - !!------------------------------------------------------------------------------------------ + !------------------------------------------------------------------------------------------ + ! 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 @@ -168,6 +164,6 @@ subroutine InitAllocate(this, bounds) 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/controlMod.F90 b/components/clm/src/main/controlMod.F90 index 5bb7248aae81..6efae10dc472 100644 --- a/components/clm/src/main/controlMod.F90 +++ b/components/clm/src/main/controlMod.F90 @@ -402,20 +402,20 @@ subroutine control_init( ) end if ! ---------------------------------------------------------------------- - !! bgc & pflotran interface + ! bgc & pflotran interface if(.not.use_clm_interface) then use_clm_bgc = .false. use_pflotran = .false. else - !! use_clm_interface + ! 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' + ! enable 'use_nitrif_denitrif' to initilize Nh4 & NO3 pools, + ! but NOT to implement 'nitrif_denitrif' use_nitrif_denitrif = .true. end if end if diff --git a/components/clm/src/main/surfrdMod.F90 b/components/clm/src/main/surfrdMod.F90 index a90eb842274c..11f8155f8c84 100644 --- a/components/clm/src/main/surfrdMod.F90 +++ b/components/clm/src/main/surfrdMod.F90 @@ -161,16 +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 + 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----------------------------- + ! pflotran:beg----------------------------- integer :: j, np, nv - !! pflotran:end----------------------------- + ! pflotran:end----------------------------- character(len=32) :: subname = 'surfrd_get_grid' ! subroutine name !----------------------------------------------------------------------- @@ -187,14 +187,14 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) ! Determine dimensions call ncd_inqfdims(ncid, isgrid2d, ni, nj, ns) - !! pflotran:beg----------------------------------------------- + ! pflotran:beg----------------------------------------------- call ncd_inqdlen(ncid, dimid, nv, 'nv') if (nv>0) then ldomain%nv = nv else ldomain%nv = 0 endif - !! pflotran:end----------------------------------------------- + ! pflotran:end----------------------------------------------- ! Determine isgrid2d flag for domain call domain_init(ldomain, isgrid2d=isgrid2d, ni=ni, nj=nj, nbeg=begg, nend=endg) @@ -223,7 +223,7 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) dim1name=grlnd, readvar=readvar) if (.not. readvar) call endrun( msg=' ERROR: yc NOT on file'//errMsg(__FILE__, __LINE__)) - !! pflotran:beg----------------------------------------------- + ! 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 @@ -236,7 +236,7 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) if (.not. readvar) call endrun( msg=trim(subname)//' ERROR: yv NOT on file'//errMsg(__FILE__, __LINE__)) end if - !! pflotran:end----------------------------------------------- + ! pflotran:end----------------------------------------------- else call ncd_io(ncid=ncid, varname= 'AREA', flag='read', data=ldomain%area, & dim1name=grlnd, readvar=readvar) @@ -250,7 +250,7 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) dim1name=grlnd, readvar=readvar) if (.not. readvar) call endrun( msg=' ERROR: LATIXY NOT on file'//errMsg(__FILE__, __LINE__)) - !! pflotran:beg----------------------------------------------- + ! 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 @@ -264,11 +264,11 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) if (.not. readvar) call endrun( msg=trim(subname)//' ERROR: LATIV NOT on file'//errMsg(__FILE__, __LINE__)) end if - !! pflotran:end----------------------------------------------- + ! pflotran:end----------------------------------------------- end if - !! let lat1d/lon1d data available for all grid-types, if coupled with PFLOTRAN. + ! 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 @@ -287,7 +287,7 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) lat1d(:) = rdata2d(1,:) deallocate(rdata2d) - !! pflotran:beg----------------------------------------------- + ! pflotran:beg----------------------------------------------- ! find the origin of ldomain, if vertices of first grid known if (use_pflotran) then ldomain%lon0 = -9999._r8 @@ -357,8 +357,8 @@ subroutine surfrd_get_grid(begg, endg, ldomain, filename, glcfilename) deallocate(rdata3d) end if end if - !! pflotran:end----------------------------------------------- - end if !! if (isgrid2d .or. use_pflotran) + ! pflotran:end----------------------------------------------- + end if ! if (isgrid2d .or. use_pflotran) diff --git a/components/clm/src/utils/clm_time_manager.F90 b/components/clm/src/utils/clm_time_manager.F90 index 78c380d75bcb..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 @@ -113,7 +113,7 @@ module clm_time_manager private :: init_calendar private :: init_clock ! private :: calc_nestep - public :: calc_nestep !!pflotran + public :: calc_nestep !pflotran private :: timemgr_print private :: TimeGetymd @@ -633,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 c259713ebf06..b82f97321e19 100644 --- a/components/clm/src/utils/domainMod.F90 +++ b/components/clm/src/utils/domainMod.F90 @@ -41,14 +41,14 @@ module domainMod character*16 :: set ! flag to check if domain is set logical :: decomped ! decomposed locally or global copy - !! pflotran:beg----------------------------------------------------- + ! 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----------------------------------------------------- + ! pflotran:end----------------------------------------------------- end type domain_type type(domain_type) , public :: ldomain @@ -124,7 +124,7 @@ 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----------------------------------------------------- + ! 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 @@ -140,7 +140,7 @@ subroutine domain_init(domain,isgrid2d,ni,nj,nbeg,nend,clmlevel) domain%latv = nan endif end if - !! pflotran:end----------------------------------------------------- + ! pflotran:end----------------------------------------------------- if (present(clmlevel)) then domain%clmlevel = clmlevel @@ -207,7 +207,7 @@ subroutine domain_clean(domain) call shr_sys_abort('domain_clean ERROR: deallocate mask, frac, lat, lon, area ') endif - !! pflotran:beg----------------------------------------------------- + ! 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 @@ -224,7 +224,7 @@ subroutine domain_clean(domain) nullify(domain%latv) endif endif - !! pflotran:beg----------------------------------------------------- + ! pflotran:beg----------------------------------------------------- else if (masterproc) then From ff93994efd03a2e80584d28f19720f82c1391414 Mon Sep 17 00:00:00 2001 From: Junqi Yin Date: Fri, 28 Jul 2017 10:00:54 -0400 Subject: [PATCH 34/35] Add a new test for ALM-PFLOTRAN's bgc interface [BFB] --- .../acme/testmods_dirs/allactive/clm/bgcinterface/user_nl_clm | 2 ++ cime/scripts/lib/update_acme_tests.py | 1 + 2 files changed, 3 insertions(+) create mode 100644 cime/config/acme/testmods_dirs/allactive/clm/bgcinterface/user_nl_clm 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 082af66a0fa6..1c62d194ff5a 100644 --- a/cime/scripts/lib/update_acme_tests.py +++ b/cime/scripts/lib/update_acme_tests.py @@ -72,6 +72,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") ), From 2adbce11abf01d92498c4cc417565d989c6ec78c Mon Sep 17 00:00:00 2001 From: Junqi Yin Date: Fri, 28 Jul 2017 10:05:54 -0400 Subject: [PATCH 35/35] Change clm-interface's zi dimension to be consistent with ALM [BFB] --- components/clm/src/main/clm_interface_dataType.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/clm/src/main/clm_interface_dataType.F90 b/components/clm/src/main/clm_interface_dataType.F90 index 0fa87a4429c0..88df65bbcf7b 100644 --- a/components/clm/src/main/clm_interface_dataType.F90 +++ b/components/clm/src/main/clm_interface_dataType.F90 @@ -99,7 +99,7 @@ subroutine InitAllocate(this, bounds) ! col: allocate(this%z (begc:endc,-nlevsno+1:nlevgrnd)) ; this%z (:,:) = nan - allocate(this%zi (begc:endc,-nlevsno+1:nlevgrnd)) ; this%zi (:,:) = 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: