Skip to content

Commit

Permalink
Merge tag 'sci.1.80.6_api.37.0.0' into landuse_fixes-deconflict
Browse files Browse the repository at this point in the history
Bug fix for issue NGEET#1301

Corrects when the fraction of burnt fuel is zero'd and how the litter
mass is updated based on that fraction.
  • Loading branch information
glemieux committed Jan 4, 2025
2 parents 6f4f3f6 + 1689466 commit 73838b3
Show file tree
Hide file tree
Showing 54 changed files with 3,486 additions and 863 deletions.
27 changes: 16 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.4)

list(APPEND CMAKE_MODULE_PATH ${CIME_CMAKE_MODULE_DIRECTORY})
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../share/cmake")

FIND_PATH(NETCDFC_FOUND libnetcdf.a ${NETCDF_C_DIR}/lib)
FIND_PATH(NETCDFF_FOUND libnetcdff.a ${NETCDF_FORTRAN_DIR}/lib)
Expand Down Expand Up @@ -29,7 +30,10 @@ add_subdirectory(${HLM_ROOT}/src/fates/biogeophys fates_biogeophys)
add_subdirectory(${HLM_ROOT}/src/fates/parteh fates_parteh)
add_subdirectory(${HLM_ROOT}/src/fates/fire fates_fire)
add_subdirectory(${HLM_ROOT}/src/fates/radiation fates_radiation)

# Testing directories
add_subdirectory(${HLM_ROOT}/src/fates/testing/testing_shr test_share)
add_subdirectory(${HLM_ROOT}/src/fates/testing/functional_testing/fire/shr fire_share)

# Remove shr_mpi_mod from share_sources.
# This is needed because we want to use the mock shr_mpi_mod in place of the real one
Expand All @@ -45,23 +49,21 @@ foreach (sourcefile ${share_sources})
endforeach()

# Remove shr_cal_mod from share_sources.
#
# shr_cal_mod depends on ESMF (or the lightweight esmf wrf timemgr, at
# least). Since CTSM doesn't currently use shr_cal_mod, we're avoiding
# the extra overhead of including esmf_wrf_timemgr sources in this
# build.
#
# TODO: like above, this should be moved into a general-purpose function
# in Sourcelist_utils. Then this block of code could be replaced with a
# single call, like: remove_source_file(${share_sources}
# "shr_cal_mod.F90")
foreach (sourcefile ${share_sources})
string(REGEX MATCH "shr_cal_mod.F90" match_found ${sourcefile})
if(match_found)
list(REMOVE_ITEM share_sources ${sourcefile})
endif()
endforeach()

# Remove shr_pio_mod from share_sources.
foreach (sourcefile ${share_sources})
string(REGEX MATCH "shr_pio_mod.F90" match_found ${sourcefile})
if(match_found)
list(REMOVE_ITEM share_sources ${sourcefile})
endif()
endforeach()

# Build libraries containing stuff needed for the unit tests.
# Eventually, these add_library calls should probably be distributed into the correct location, rather than being in this top-level CMakeLists.txt file.
add_library(csm_share ${share_sources})
Expand All @@ -81,10 +83,13 @@ include_directories(${NETCDF_C_DIR}/include
${NETCDF_FORTRAN_DIR}/include)
link_directories(${NETCDF_C_DIR}/lib
${NETCDF_FORTRAN_DIR}/lib)


# Tell cmake to look for libraries & mod files here, because this is where we built libraries
include_directories(${CMAKE_CURRENT_BINARY_DIR})
link_directories(${CMAKE_CURRENT_BINARY_DIR})

# Directories and libraries to include in the link step
link_directories(${CMAKE_CURRENT_BINARY_DIR})

# Add the main test directory
add_subdirectory(${HLM_ROOT}/src/fates/testing)
18 changes: 11 additions & 7 deletions biogeochem/EDCohortDynamicsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1067,20 +1067,24 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in)
nextc%n*nextc%gpp_acc)/newn
currentCohort%npp_acc = (currentCohort%n*currentCohort%npp_acc + &
nextc%n*nextc%npp_acc)/newn
currentCohort%resp_acc = (currentCohort%n*currentCohort%resp_acc + &
nextc%n*nextc%resp_acc)/newn
currentCohort%resp_acc_hold = &
(currentCohort%n*currentCohort%resp_acc_hold + &
nextc%n*nextc%resp_acc_hold)/newn
currentCohort%resp_m_acc = (currentCohort%n*currentCohort%resp_m_acc + &
nextc%n*nextc%resp_m_acc)/newn
currentCohort%resp_m_acc_hold = &
(currentCohort%n*currentCohort%resp_m_acc_hold + &
nextc%n*nextc%resp_m_acc_hold)/newn
currentCohort%resp_g_acc_hold = &
(currentCohort%n*currentCohort%resp_g_acc_hold + &
nextc%n*nextc%resp_g_acc_hold)/newn
currentCohort%npp_acc_hold = &
(currentCohort%n*currentCohort%npp_acc_hold + &
nextc%n*nextc%npp_acc_hold)/newn
currentCohort%gpp_acc_hold = &
(currentCohort%n*currentCohort%gpp_acc_hold + &
nextc%n*nextc%gpp_acc_hold)/newn

currentCohort%resp_excess = (currentCohort%n*currentCohort%resp_excess + &
nextc%n*nextc%resp_excess)/newn
currentCohort%resp_excess_hold = &
(currentCohort%n*currentCohort%resp_excess_hold + &
nextc%n*nextc%resp_excess_hold)/newn

currentCohort%dmort = (currentCohort%n*currentCohort%dmort + &
nextc%n*nextc%dmort)/newn
Expand Down
45 changes: 21 additions & 24 deletions biogeochem/EDLoggingMortalityMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ module EDLoggingMortalityMod
use FatesConstantsMod , only : hlm_harvest_area_fraction
use FatesConstantsMod , only : hlm_harvest_carbon
use FatesConstantsMod, only : fates_check_param_set
use FatesConstantsMod, only : fates_no_harvest_debt, fates_with_harvest_debt, fates_bypass_harvest_debt

use FatesInterfaceTypesMod , only : numpft
use FatesLandUseChangeMod, only : GetInitLanduseHarvestRate
use FatesLandUseChangeMod, only : GetLUHStatedata
Expand Down Expand Up @@ -234,9 +236,6 @@ subroutine LoggingMortality_frac( currentSite, bc_in, pft_i, dbh, canopy_layer,
integer, intent(out) :: harvest_tag(:) ! tag to record the harvest status
! for the calculation of harvest debt in C-based
! harvest mode
! 0 - successful;
! 1 - unsuccessful since not enough carbon
! 2 - not applicable

! Local variables
integer :: cur_harvest_tag ! the harvest tag of the cohort today
Expand Down Expand Up @@ -277,10 +276,11 @@ subroutine LoggingMortality_frac( currentSite, bc_in, pft_i, dbh, canopy_layer,
harvest_rate = 0._r8
endif

! For area-based harvest, harvest_tag shall always be 2 (not applicable).
harvest_tag = 2
cur_harvest_tag = 2
elseif (logging_time) then
! For area-based harvest, harvest_tag shall always be fates_bypass_harvest_debt (not applicable).
harvest_tag = fates_bypass_harvest_debt
cur_harvest_tag = fates_bypass_harvest_debt

elseif (logging_time) then

! Pass logging rates to cohort level

Expand Down Expand Up @@ -316,8 +316,8 @@ subroutine LoggingMortality_frac( currentSite, bc_in, pft_i, dbh, canopy_layer,
hlm_harvest_rates, current_fates_landuse_state_vector, secondary_young_fraction, secondary_age, harvest_rate)

! For area-based harvest, harvest_tag shall always be 2 (not applicable).
harvest_tag = 2
cur_harvest_tag = 2
harvest_tag = fates_bypass_harvest_debt
cur_harvest_tag = fates_bypass_harvest_debt

if (fates_global_verbose()) then
write(fates_log(), *) 'Successfully Read Harvest Rate from HLM.', hlm_harvest_rates(:), harvest_rate
Expand All @@ -340,14 +340,14 @@ subroutine LoggingMortality_frac( currentSite, bc_in, pft_i, dbh, canopy_layer,
else
harvest_rate = 0._r8
! For area-based harvest, harvest_tag shall always be 2 (not applicable).
harvest_tag = 2
cur_harvest_tag = 2
harvest_tag = fates_bypass_harvest_debt
cur_harvest_tag = fates_bypass_harvest_debt
endif

! transfer of area to secondary land is based on overall area affected, not just logged crown area
! l_degrad accounts for the affected area between logged crowns
if(prt_params%woody(pft_i) == itrue)then ! only set logging rates for trees
if (cur_harvest_tag == 0) then
if (cur_harvest_tag == fates_no_harvest_debt .or. cur_harvest_tag == fates_bypass_harvest_debt) then
! direct logging rates, based on dbh min and max criteria
if (dbh >= logging_dbhmin .and. .not. &
((logging_dbhmax < fates_check_param_set) .and. (dbh >= logging_dbhmax )) ) then
Expand Down Expand Up @@ -640,10 +640,7 @@ subroutine get_harvest_rate_carbon (patch_land_use_label, hlm_harvest_catnames,
real(r8), intent(in) :: secondary_age ! patch level age_since_anthro_disturbance
real(r8), intent(in) :: harvestable_forest_c(:) ! site level forest c matching criteria available for harvest, kgC site-1
real(r8), intent(out) :: harvest_rate ! area fraction
integer, intent(inout) :: harvest_tag(:) ! 0. normal harvest; 1. current site does not have enough C but
! can perform harvest by ignoring criteria; 2. current site does
! not have enough carbon
! This harvest tag shall be a patch level variable but since all
integer, intent(inout) :: harvest_tag(:) ! This harvest tag can be raused to patch level but since all
! logging functions happen within cohort loop we can only put the
! calculation here. Can think about optimizing the logging calculation
! in the future.
Expand All @@ -663,7 +660,7 @@ subroutine get_harvest_rate_carbon (patch_land_use_label, hlm_harvest_catnames,
harvest_rate = 0._r8
harvest_rate_c = 0._r8
harvest_rate_supply = 0._r8
harvest_tag(:) = 2
harvest_tag(:) = fates_bypass_harvest_debt

! Since we have five harvest categories from forcing data but in FATES non-forest harvest
! is merged with forest harvest, we only have three logging type in FATES (primary, secondary
Expand Down Expand Up @@ -696,29 +693,29 @@ subroutine get_harvest_rate_carbon (patch_land_use_label, hlm_harvest_catnames,
if(hlm_harvest_catnames(h_index) .eq. "HARVEST_VH1" ) then
if(harvestable_forest_c(h_index) >= harvest_rate_c) then
harvest_rate_supply = harvest_rate_supply + harvestable_forest_c(h_index)
harvest_tag(h_index) = 0
harvest_tag(h_index) = fates_no_harvest_debt
else
harvest_tag(h_index) = 1
harvest_tag(h_index) = fates_with_harvest_debt
end if
end if
else if (patch_land_use_label .eq. secondaryland .and. &
secondary_age >= secondary_age_threshold) then
if(hlm_harvest_catnames(h_index) .eq. "HARVEST_SH1" ) then
if(harvestable_forest_c(h_index) >= harvest_rate_c) then
harvest_rate_supply = harvest_rate_supply + harvestable_forest_c(h_index)
harvest_tag(h_index) = 0
harvest_tag(h_index) = fates_no_harvest_debt
else
harvest_tag(h_index) = 1
harvest_tag(h_index) = fates_with_harvest_debt
end if
end if
else if (patch_land_use_label .eq. secondaryland .and. &
secondary_age < secondary_age_threshold) then
if(hlm_harvest_catnames(h_index) .eq. "HARVEST_SH2" ) then
if(harvestable_forest_c(h_index) >= harvest_rate_c) then
harvest_rate_supply = harvest_rate_supply + harvestable_forest_c(h_index)
harvest_tag(h_index) = 0
harvest_tag(h_index) = fates_no_harvest_debt
else
harvest_tag(h_index) = 1
harvest_tag(h_index) = fates_with_harvest_debt
end if
end if
end if
Expand Down Expand Up @@ -1284,7 +1281,7 @@ subroutine get_harvest_debt(site_in, bc_in, harvest_tag)
end do
! Next we get the harvest debt through the harvest tag
do h_index = 1, hlm_num_lu_harvest_cats
if (harvest_tag(h_index) .eq. 1) then
if (harvest_tag(h_index) .eq. fates_with_harvest_debt) then
if(bc_in%hlm_harvest_catnames(h_index) .eq. "HARVEST_VH1") then
site_in%resources_management%harvest_debt = site_in%resources_management%harvest_debt + &
harvest_debt_pri
Expand Down
Loading

0 comments on commit 73838b3

Please sign in to comment.