Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
cmake_minimum_required(VERSION 3.10)

# Determine HLM_ROOT path (compatible with CMake 3.10+)
if (NOT DEFINED HLM_ROOT)
if (NOT "$ENV{HLM_ROOT}" STREQUAL "")
set(HLM_ROOT "$ENV{HLM_ROOT}")
else()
set(HLM_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../")
endif()
endif()
get_filename_component(HLM_ROOT "${HLM_ROOT}" ABSOLUTE)
list(APPEND CMAKE_MODULE_PATH ${CIME_CMAKE_MODULE_DIRECTORY})
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../share/cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../components/cmeps/cmake")
list(APPEND CMAKE_MODULE_PATH "${HLM_ROOT}/share/cmake")
list(APPEND CMAKE_MODULE_PATH "${HLM_ROOT}/components/cmeps/cmake")

FIND_PATH(NETCDFC_FOUND libnetcdf.a ${NETCDF_C_DIR}/lib)
FIND_PATH(NETCDFF_FOUND libnetcdff.a ${NETCDF_FORTRAN_DIR}/lib)
Expand All @@ -18,8 +27,6 @@ project(FATES_tests Fortran C)

include(CIME_utils)

set(HLM_ROOT "../../")

if (DEFINED ENV{ESMF_ROOT})
list(APPEND CMAKE_MODULE_PATH $ENV{ESMF_ROOT}/cmake)
endif()
Expand All @@ -42,16 +49,16 @@ add_subdirectory(${HLM_ROOT}/share/src csm_share)
add_subdirectory(${HLM_ROOT}/share/unit_test_stubs/util csm_share_stubs)

# Add FATES source directories
add_subdirectory(${HLM_ROOT}/src/fates/main fates_main)
add_subdirectory(${HLM_ROOT}/src/fates/biogeochem fates_biogeochem)
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)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/main fates_main)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/biogeochem fates_biogeochem)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/biogeophys fates_biogeophys)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/parteh fates_parteh)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/fire fates_fire)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/radiation fates_radiation)

# Testing directories
add_subdirectory(${HLM_ROOT}/src/fates/testing/tests/fortran_shr test_share)
add_subdirectory(${HLM_ROOT}/src/fates/testing/tests/functional/fire/shr fire_share)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/testing/tests/fortran_shr test_share)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/testing/tests/functional/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 Down Expand Up @@ -111,4 +118,4 @@ link_directories(${CMAKE_CURRENT_BINARY_DIR})
link_libraries(esmf)

# Add the main test directory
add_subdirectory(${HLM_ROOT}/src/fates/testing)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/testing)
2 changes: 1 addition & 1 deletion main/EDParamsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ module EDParamsMod
! smooth2_campbell_type = 32
! tfs_type = 1
! van Genuchten 1980 model = 2
integer, protected,allocatable,public :: hydr_htftype_node(:)
integer, allocatable,public :: hydr_htftype_node(:) ! only non-protected for unit tests

real(r8),protected,public :: hydr_kmax_rsurf1 ! maximum conducitivity for unit root surface
! soil to root direction (kg water/m2 root area/Mpa/s)
Expand Down
7 changes: 5 additions & 2 deletions testing/tests/fortran_shr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ list(APPEND fates_sources
FatesArgumentUtils.F90
FatesFactoryMod.F90
SyntheticPatchTypes.F90
FatesUnitTestUtils.F90)
FatesUnitTestUtils.F90
EDPftvarconMockMod.F90
EDTypesMockMod.F90
FatesUnitTestPRTParametersMod.F90)

sourcelist_to_parent(fates_sources)
sourcelist_to_parent(fates_sources)
92 changes: 92 additions & 0 deletions testing/tests/fortran_shr/EDPftvarconMockMod.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
module EDPftvarconMockMod

use FatesConstantsMod, only: r8 => fates_r8
use EDPftvarcon, only: EDPftvarcon_inst
use FatesHydraulicsMemMod, only : n_plant_media

implicit none

contains

subroutine init_mock_edpftvarcon()
integer :: max_pft = 1
integer :: num_hydrorgan

num_hydrorgan = n_plant_media

if (.not. allocated(EDPftvarcon_inst%hydr_p_taper)) then
! 1D arrays
allocate(EDPftvarcon_inst%hydr_p_taper(max_pft))
allocate(EDPftvarcon_inst%hydr_rs2(max_pft))
allocate(EDPftvarcon_inst%hydr_srl(max_pft))
allocate(EDPftvarcon_inst%hydr_rfrac_stem(max_pft))
allocate(EDPftvarcon_inst%hydr_avuln_gs(max_pft))
allocate(EDPftvarcon_inst%hydr_p50_gs(max_pft))
allocate(EDPftvarcon_inst%hydr_k_lwp(max_pft))

allocate(EDPftvarcon_inst%damage_frac(max_pft))
allocate(EDPftvarcon_inst%vcmax25top(max_pft, 1))

! 2D arrays
allocate(EDPftvarcon_inst%hydr_vg_alpha_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_vg_m_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_vg_n_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_avuln_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_p50_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_epsil_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_pitlp_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_fcap_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_pinot_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_kmax_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_resid_node(max_pft,num_hydrorgan))
allocate(EDPftvarcon_inst%hydr_thetas_node(max_pft,num_hydrorgan))
end if

! Xylem tapering exponent [dimensionless] (ideal power-law conduit tapering along trunk length)
EDPftvarcon_inst%hydr_p_taper(:) = 0.5_r8
! Fine root radius [m] (standard fine absorbing root radius)
EDPftvarcon_inst%hydr_rs2(:) = 0.001_r8
! Specific root length [m/g] (standard root absorptive length per unit carbon mass)
EDPftvarcon_inst%hydr_srl(:) = 10.0_r8
! Stem resistance fraction [fraction] (splits stem hydraulic resistance equally between upper and lower segments)
EDPftvarcon_inst%hydr_rfrac_stem(:) = 0.5_r8
! Stomatal vulnerability exponent [dimensionless] (sigmoidal stomatal closure curve slope)
EDPftvarcon_inst%hydr_avuln_gs(:) = 2.0_r8
! Stomatal 50% closure water potential [MPa] (sensitivity threshold matching xylem p50)
EDPftvarcon_inst%hydr_p50_gs(:) = -2.0_r8
! Leaf water potential scaling factor [dimensionless] (unit scaling for stomatal conductance response)
EDPftvarcon_inst%hydr_k_lwp(:) = 1.0_r8

! Crown damage fraction [fraction] (baseline background canopy crown loss)
EDPftvarcon_inst%damage_frac(:) = 0.1_r8
! Top-of-canopy Vcmax25 [umol/m2/s] (baseline photosynthetic capacity for C3 trees)
EDPftvarcon_inst%vcmax25top(:,:) = 50.0_r8

! van Genuchten alpha parameter [1/mm] (air-entry pressure inverse length scale)
EDPftvarcon_inst%hydr_vg_alpha_node(:,:) = 0.01_r8
! van Genuchten m parameter [dimensionless] (satisfies m = 1 - 1/n physical soil water retention invariant)
EDPftvarcon_inst%hydr_vg_m_node(:,:) = 0.5_r8
! van Genuchten n parameter [dimensionless] (pore-size distribution index)
EDPftvarcon_inst%hydr_vg_n_node(:,:) = 2.0_r8
! Vulnerability curve exponent [dimensionless] (sigmoidal slope of xylem cavitation curve)
EDPftvarcon_inst%hydr_avuln_node(:,:) = 2.0_r8
! Xylem 50% loss water potential [MPa] (typical temperate tree cavitation resistance threshold)
EDPftvarcon_inst%hydr_p50_node(:,:) = -2.0_r8
! Elastic modulus [MPa] (typical cell wall elasticity of woody tissues)
EDPftvarcon_inst%hydr_epsil_node(:,:) = 10.0_r8
! Turgor loss point [MPa] (osmotic wilting potential threshold)
EDPftvarcon_inst%hydr_pitlp_node(:,:) = -1.5_r8
! Capillary fraction [fraction] (baseline elastic capillary storage volume)
EDPftvarcon_inst%hydr_fcap_node(:,:) = 0.1_r8
! Full turgor osmotic potential [MPa] (baseline solute potential at full hydration)
EDPftvarcon_inst%hydr_pinot_node(:,:) = -1.0_r8
! Maximum tissue hydraulic conductivity [kg/m/s/MPa] (intrinsic tissue permeability normalization)
EDPftvarcon_inst%hydr_kmax_node(:,:) = 1.0_r8
! Residual relative water content [m3/m3] (non-extractable bound water fraction)
EDPftvarcon_inst%hydr_resid_node(:,:) = 0.05_r8
! Saturated relative water content [m3/m3] (tissue porosity fraction)
EDPftvarcon_inst%hydr_thetas_node(:,:) = 0.5_r8

end subroutine init_mock_edpftvarcon

end module EDPftvarconMockMod
94 changes: 94 additions & 0 deletions testing/tests/fortran_shr/EDTypesMockMod.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
module EDTypesMockMod

use FatesConstantsMod, only: r8 => fates_r8
use EDTypesMod, only: ed_site_type
use FatesPatchMod, only: fates_patch_type
use FatesCohortMod, only: fates_cohort_type
use FatesHydraulicsMemMod, only : ed_site_hydr_type, ed_cohort_hydr_type
use PRTAllometricCarbonMod, only : InitPRTGlobalAllometricCarbon
use EDCohortDynamicsMod, only : InitPRTObject
use FatesInterfaceTypesMod, only : hlm_parteh_mode
use PRTGenericMod, only : carbon_only

implicit none

contains

subroutine init_mock_site(site)
type(ed_site_type), intent(inout), target :: site

if (.not. associated(site%si_hydr)) then
allocate(site%si_hydr)
end if

end subroutine init_mock_site

subroutine init_mock_site_patch_cohort(site, patch, cohort)
type(ed_site_type), pointer, intent(out) :: site
type(fates_patch_type), pointer, intent(out) :: patch
type(fates_cohort_type), pointer, intent(out) :: cohort

integer :: i

if (.not. associated(site)) then
allocate(site)
site%si_hydr => null()
end if
if (.not. associated(patch)) allocate(patch)
if (.not. associated(cohort)) then
allocate(cohort)
cohort%co_hydr => null()
end if

site%oldest_patch => patch
patch%tallest => cohort
patch%patchno = 1
patch%younger => null()
patch%nocomp_pft_label = 1 ! Avoid being treated as bare ground
cohort%shorter => null()

call init_mock_site(site)

! Initialize the PRT global state (can be called safely multiple times in tests)
hlm_parteh_mode = carbon_only
call InitPRTGlobalAllometricCarbon()

! Initialize PRT object for this cohort if not already associated (idempotent for multiple tests)
if (.not. associated(cohort%prt)) then
call InitPRTObject(cohort%prt)
end if


! Initialize all state variables to positive values to avoid crashes in hydraulics
if (allocated(cohort%prt%variables)) then
do i = 1, size(cohort%prt%variables)
if (associated(cohort%prt%variables(i)%val)) then
cohort%prt%variables(i)%val(:) = 10.0_r8
end if
end do
end if

if (.not. associated(cohort%co_hydr)) then
allocate(cohort%co_hydr)
end if

! Cohort density n = 10.0 indiv/m2 represents standard seedling/sapling canopy density
cohort%n = 10.0_r8
! DBH = 10.0 cm represents 10cm diameter sapling trunk
cohort%dbh = 10.0_r8
! Height = 10.0 m matches 10cm DBH allometry
cohort%height = 10.0_r8
! Crown damage fraction = 0.0 represents undamaged intact canopy
cohort%crowndamage = 0.0_r8
! Canopy trim fraction = 1.0 represents full untrimmed leaf canopy
cohort%canopy_trim = 1.0_r8
! Stem efficiency fraction = 1.0 represents undamaged full sapwood conduit capacity
cohort%efstem_coh = 1.0_r8
! Size class index = 1 selects smallest canopy size bin
cohort%size_class = 1



end subroutine init_mock_site_patch_cohort

end module EDTypesMockMod
Loading