Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6303f42
adding patch-level calls to photosynthesis for multithreading
rgknox Feb 6, 2026
9444ab3
refactored photosynthesis, conductance and maintenance respiration to…
rgknox Feb 7, 2026
d522019
finished first pass of making patch photosynthesis its own routine, c…
rgknox Feb 8, 2026
4e2439a
fixes to arguments in patch parallel photosynthesis
rgknox Feb 10, 2026
9cd2b5e
Merge branch 'main' into patch-parallel
rgknox Feb 10, 2026
84e07b9
added reminder text
rgknox Feb 11, 2026
050fb6a
changed memory usage in photosynthesis code
rgknox Feb 12, 2026
4c6b346
towards patch parallel radiation
rgknox Feb 16, 2026
1709666
first pass at patch parallel load balancing
rgknox Feb 19, 2026
7f02ad5
memory and algorithmic efficiency updates to photosynthesis
rgknox Feb 20, 2026
01ef41e
refactors for memory efficient photosynthesis
rgknox Feb 20, 2026
c05fe59
Multithreaded canopy radiation
rgknox Feb 21, 2026
bab2e63
refactors to photosynthesis code, memory usage, removed unused comput…
rgknox Feb 21, 2026
7eef75f
updated load-balancing algorithm
rgknox Feb 22, 2026
f3373fe
Merge branch 'main' into patch-parallel-lb
rgknox Feb 24, 2026
60e8a7b
removed dynamic patch memory for fnrt scratch space, stack is faster …
rgknox Feb 26, 2026
4445453
removing persistent scratch arrays for two-stream
rgknox Feb 26, 2026
a8d97ed
fixed commented out code
rgknox Feb 26, 2026
334e12c
efficiency updates, related to faster math and patch array pointers
rgknox Mar 2, 2026
a240a2f
fates photosynthesis speedups
rgknox Mar 4, 2026
c2da59f
More optimizations to psn
rgknox Mar 5, 2026
a0c8082
adding dedicated pointers and getter functions to plant organ states
rgknox Mar 5, 2026
053d1d0
b4b provisions
rgknox Mar 5, 2026
0250f5d
Merge branch 'patch-parallel-lbmathop' into patch-parallel-lbmathop-prt
rgknox Mar 5, 2026
411c1b5
working out scratch vectors for high frequency operations
rgknox Mar 6, 2026
a54f1be
scratch arrays for cohorts, part 1
rgknox Mar 6, 2026
efed123
Clean version of vector cohorts and optimized organ pointers
rgknox Mar 9, 2026
5c7c2f1
changes bprates to structure with arrays, instead of an array of stru…
rgknox Mar 9, 2026
c33a71d
used cache-friendly call to organ masses
rgknox Mar 10, 2026
2412370
fixes for optimizations
rgknox Mar 12, 2026
cef64a1
changed rdark to rdark_tstep
rgknox Mar 17, 2026
8774e6e
Converted more high-frequency respiration terms to the cohort arrays
rgknox Mar 17, 2026
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
294 changes: 263 additions & 31 deletions biogeochem/EDCanopyStructureMod.F90

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions biogeochem/EDPhysiologyMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2549,7 +2549,7 @@ subroutine recruitment(currentSite, currentPatch, bc_in)
height = EDPftvarcon_inst%hgt_min(ft)
stem_drop_fraction = prt_params%phen_stem_drop_fraction(ft)
fnrt_drop_fraction = prt_params%phen_fnrt_drop_fraction(ft)
l2fr = currentSite%rec_l2fr(ft, currentPatch%NCL_p)
l2fr = currentSite%rec_l2fr(ft, currentPatch%ncl)
crowndamage = 1 ! new recruits are undamaged

! calculate DBH from initial height
Expand Down Expand Up @@ -2782,7 +2782,7 @@ subroutine recruitment(currentSite, currentPatch, bc_in)
call create_cohort(currentSite, currentPatch, ft, cohort_n, &
height, 0.0_r8, dbh, prt, efleaf_coh, effnrt_coh, efstem_coh, &
leaf_status, recruitstatus, init_recruit_trim, 0.0_r8, &
currentPatch%NCL_p, crowndamage, currentSite%spread, bc_in)
currentPatch%ncl, crowndamage, currentSite%spread, bc_in)

! Note that if hydraulics is on, the number of cohorts may have
! changed due to hydraulic constraints.
Expand Down Expand Up @@ -3396,7 +3396,7 @@ subroutine UpdateRecruitStoich(csite)

cpatch => csite%youngest_patch
do while(associated(cpatch))
cl = cpatch%ncl_p
cl = cpatch%ncl

do ft = 1,numpft
rec_l2fr_pft = csite%rec_l2fr(ft,cl)
Expand Down
69 changes: 5 additions & 64 deletions biogeochem/FatesCohortMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,12 @@ module FatesCohortMod
real(r8) :: dbh ! diameter at breast height [cm]
real(r8) :: coage ! age [years]
real(r8) :: height ! height [m]
integer :: indexnumber ! unique number for each cohort (within clump?)
integer :: canopy_layer ! canopy status of cohort [1 = canopy, 2 = understorey, etc.]
real(r8) :: canopy_layer_yesterday ! recent canopy status of cohort [1 = canopy, 2 = understorey, etc.]
! real to be conservative during fusion
integer :: crowndamage ! crown damage class of the cohort [1 = undamaged, >1 = damaged]
real(r8) :: g_sb_laweight ! total conductance (stomata + boundary layer) of the cohort
! weighted by its leaf area [m/s]*[m2]
! weighted by its leaf area [m/s]*[m2] (NEEDED FOR RESTART)
real(r8) :: canopy_trim ! fraction of the maximum leaf biomass that we are targeting [0-1]
real(r8) :: leaf_cost ! how much does it cost to maintain leaves [kgC/m2/year]
real(r8) :: excl_weight ! how much of this cohort is demoted each year, as a proportion of all cohorts
Expand Down Expand Up @@ -141,19 +140,16 @@ module FatesCohortMod
! Units converted to a useful rate [kgC/indiv/yr]
! --------------------------------------------------------------------------

real(r8) :: gpp_tstep ! Gross Primary Production (see above *)
real(r8) :: gpp_acc
real(r8) :: gpp_acc_hold

real(r8) :: npp_acc
real(r8) :: npp_acc_hold

real(r8) :: resp_m_tstep ! Maintenance respiration (see above *)
real(r8) :: resp_m_acc
real(r8) :: resp_m_acc_hold
real(r8) :: resp_g_acc_hold

real(r8) :: c13disc_clm ! carbon 13 discrimination in new synthesized carbon at each indiv/timestep [ppm]
real(r8) :: c13disc_acc ! carbon 13 discrimination in new synthesized carbon at each indiv/day
! at the end of a day [ppm]

Expand All @@ -163,10 +159,8 @@ module FatesCohortMod

real(r8) :: vcmax25top ! maximum carboxylation at canopy top and 25degC [umol CO2/m2/s]
real(r8) :: jmax25top ! maximum electron transport rate at canopy top and 25degC [umol electrons/m2/s]
real(r8) :: tpu25top ! triose phosphate utilization rate at canopy top and 25degC [umol CO2/m2/s]
real(r8) :: kp25top ! initial slope of CO2 response curve (C4 plants) at 25C

real(r8) :: ts_net_uptake(nlevleaf) ! net uptake of leaf layers [kgC/m2/timestep]
real(r8) :: year_net_uptake(nlevleaf) ! net uptake of leaf layers [kgC/m2/year]

! used for CNP
Expand All @@ -185,7 +179,6 @@ module FatesCohortMod
! in soil [kgN/plant/day]

real(r8) :: sym_nfix_daily ! accumulated symbiotic N fixation from the roots [kgN/indiv/day]
real(r8) :: sym_nfix_tstep ! symbiotic N fixation from the roots for the time-step [kgN/indiv/timestep]

real(r8) :: daily_n_gain ! sum of fixation and uptake of mineralized NH4/NO3 in solution as well as
! symbiotic fixation
Expand Down Expand Up @@ -213,12 +206,6 @@ module FatesCohortMod
! to aid in reporting a more accurate sub-daily
! NEP

real(r8) :: rdark ! dark respiration [kgC/indiv/s]
real(r8) :: resp_m_unreduced ! diagnostic-only unreduced maintenance respiration [kgC/indiv/timestep]
real(r8) :: livestem_mr ! aboveground live stem maintenance respiration [kgC/indiv/s]
real(r8) :: livecroot_mr ! belowground live stem maintenance respiration [kgC/indiv/s]
real(r8) :: froot_mr ! live fine root maintenance respiration [kgC/indiv/s]

!---------------------------------------------------------------------------

! DAMAGE
Expand Down Expand Up @@ -361,7 +348,6 @@ subroutine NanValues(this)
this%dbh = nan
this%coage = nan
this%height = nan
this%indexnumber = fates_unset_int
this%canopy_layer = fates_unset_int
this%canopy_layer_yesterday = nan
this%crowndamage = fates_unset_int
Expand All @@ -386,23 +372,18 @@ subroutine NanValues(this)
this%size_class_lasttimestep = fates_unset_int

! CARBON AND NUTRIENT FLUXES
this%gpp_tstep = nan
this%gpp_acc = nan
this%gpp_acc_hold = nan
this%npp_acc = nan
this%npp_acc_hold = nan
this%resp_m_tstep = nan
this%resp_m_acc = nan
this%resp_m_acc_hold = nan
this%resp_g_acc_hold = nan
this%c13disc_clm = nan
this%c13disc_acc = nan
this%vcmax25top = nan
this%jmax25top = nan
this%tpu25top = nan
this%kp25top = nan
this%year_net_uptake(:) = nan
this%ts_net_uptake(:) = nan
this%cnp_limiter = fates_unset_int
this%cx_int = nan
this%ema_dcxdt = nan
Expand All @@ -412,7 +393,6 @@ subroutine NanValues(this)
this%daily_nh4_uptake = nan
this%daily_no3_uptake = nan
this%sym_nfix_daily = nan
this%sym_nfix_tstep = nan
this%daily_n_gain = nan
this%daily_p_gain = nan
this%daily_c_efflux = nan
Expand All @@ -423,12 +403,7 @@ subroutine NanValues(this)
this%seed_prod = nan

! RESPIRATION COMPONENTS
this%rdark = nan
this%resp_m_unreduced = nan
this%resp_excess_hold = nan
this%livestem_mr = nan
this%livecroot_mr = nan
this%froot_mr = nan

! DAMAGE
this%branch_frac = nan
Expand Down Expand Up @@ -476,8 +451,6 @@ subroutine ZeroValues(this)
! ARGUMENTS
class(fates_cohort_type), intent(inout) :: this

this%g_sb_laweight = 0._r8

this%leaf_cost = 0._r8
this%excl_weight = 0._r8
this%prom_weight = 0._r8
Expand All @@ -490,12 +463,11 @@ subroutine ZeroValues(this)
this%treesai = 0._r8
this%size_class = 1
this%coage_class = 1


this%g_sb_laweight = 0._r8
this%size_class_lasttimestep = 0
this%gpp_tstep = 0._r8
this%gpp_acc = 0._r8
this%npp_acc = 0._r8
this%resp_m_tstep = 0._r8
this%resp_m_acc = 0._r8

! do not zero these, they are not built
Expand All @@ -507,10 +479,8 @@ subroutine ZeroValues(this)
! this%resp_g_acc_hold = nan
! this%resp_excess_hold = nan

this%c13disc_clm = 0._r8
this%c13disc_acc = 0._r8

this%ts_net_uptake(:) = 0._r8
this%year_net_uptake(:) = 999._r8 ! this needs to be 999, or trimming of new cohorts will break.

this%daily_nh4_uptake = 0._r8
Expand All @@ -533,12 +503,7 @@ subroutine ZeroValues(this)
this%daily_n_demand = -9._r8
this%daily_p_demand = -9._r8
this%seed_prod = 0._r8
this%rdark = 0._r8
this%resp_m_unreduced = 0._r8
this%livestem_mr = 0._r8
this%livecroot_mr = 0._r8
this%froot_mr = 0._r8


this%dmort = 0._r8
this%lmort_direct = 0._r8
this%lmort_collateral = 0._r8
Expand Down Expand Up @@ -684,8 +649,6 @@ subroutine Copy(this, copyCohort)
class(fates_cohort_type), intent(in) :: this ! old cohort
class(fates_cohort_type), intent(inout) :: copyCohort ! new cohort

copyCohort%indexnumber = fates_unset_int

! POINTERS
copyCohort%taller => NULL()
copyCohort%shorter => NULL()
Expand Down Expand Up @@ -724,22 +687,17 @@ subroutine Copy(this, copyCohort)
copyCohort%size_class_lasttimestep = this%size_class_lasttimestep

! CARBON AND NUTRIENT FLUXES
copyCohort%gpp_tstep = this%gpp_tstep
copyCohort%gpp_acc = this%gpp_acc
copyCohort%gpp_acc_hold = this%gpp_acc_hold
copyCohort%npp_acc = this%npp_acc
copyCohort%npp_acc_hold = this%npp_acc_hold
copyCohort%resp_m_tstep = this%resp_m_tstep
copyCohort%resp_m_acc = this%resp_m_acc
copyCohort%resp_m_acc_hold = this%resp_m_acc_hold
copyCohort%resp_g_acc_hold = this%resp_g_acc_hold
copyCohort%c13disc_clm = this%c13disc_clm
copyCohort%c13disc_acc = this%c13disc_acc
copyCohort%vcmax25top = this%vcmax25top
copyCohort%jmax25top = this%jmax25top
copyCohort%tpu25top = this%tpu25top
copyCohort%kp25top = this%kp25top
copyCohort%ts_net_uptake = this%ts_net_uptake
copyCohort%year_net_uptake = this%year_net_uptake
copyCohort%cnp_limiter = this%cnp_limiter

Expand All @@ -753,7 +711,6 @@ subroutine Copy(this, copyCohort)
copyCohort%daily_nh4_uptake = this%daily_nh4_uptake
copyCohort%daily_no3_uptake = this%daily_no3_uptake
copyCohort%sym_nfix_daily = this%sym_nfix_daily
copyCohort%sym_nfix_tstep = this%sym_nfix_tstep
copyCohort%daily_n_gain = this%daily_n_gain
copyCohort%daily_p_gain = this%daily_p_gain
copyCohort%daily_c_efflux = this%daily_c_efflux
Expand All @@ -764,12 +721,7 @@ subroutine Copy(this, copyCohort)
copyCohort%seed_prod = this%seed_prod

! RESPIRATION COMPONENTS
copyCohort%rdark = this%rdark
copyCohort%resp_m_unreduced = this%resp_m_unreduced
copyCohort%resp_excess_hold = this%resp_excess_hold
copyCohort%livestem_mr = this%livestem_mr
copyCohort%livecroot_mr = this%livecroot_mr
copyCohort%froot_mr = this%froot_mr

! DAMAGE
copyCohort%branch_frac = this%branch_frac
Expand Down Expand Up @@ -974,24 +926,19 @@ subroutine UpdateCohortBioPhysRates(this)
this%jmax25top = sum(param_derived%jmax25top(ipft, 1:nleafage)* &
frac_leaf_aclass(1:nleafage))

this%tpu25top = sum(param_derived%tpu25top(ipft, 1:nleafage)* &
frac_leaf_aclass(1:nleafage))

this%kp25top = sum(param_derived%kp25top(ipft, 1:nleafage)* &
frac_leaf_aclass(1:nleafage))

else if (hlm_use_sp .eq. itrue) then

this%vcmax25top = EDPftvarcon_inst%vcmax25top(ipft, 1)
this%jmax25top = param_derived%jmax25top(ipft, 1)
this%tpu25top = param_derived%tpu25top(ipft, 1)
this%kp25top = param_derived%kp25top(ipft, 1)

else

this%vcmax25top = 0._r8
this%jmax25top = 0._r8
this%tpu25top = 0._r8
this%kp25top = 0._r8

end if
Expand Down Expand Up @@ -1088,7 +1035,7 @@ subroutine Dump(this)
write(fates_log(),*) 'structural (dead) carbon = ', this%prt%GetState(struct_organ,carbon12_element)
write(fates_log(),*) 'storage carbon = ', this%prt%GetState(store_organ,carbon12_element)
write(fates_log(),*) 'reproductive carbon = ', this%prt%GetState(repro_organ,carbon12_element)
write(fates_log(),*) 'cohort%g_sb_laweight = ', this%g_sb_laweight
!write(fates_log(),*) 'cohort%g_sb_laweight = ', this%g_sb_laweight
write(fates_log(),*) 'cohort%leaf_cost = ', this%leaf_cost
write(fates_log(),*) 'cohort%canopy_layer = ', this%canopy_layer
write(fates_log(),*) 'cohort%canopy_layer_yesterday = ', this%canopy_layer_yesterday
Expand All @@ -1107,17 +1054,11 @@ subroutine Dump(this)
write(fates_log(),*) 'cohort%coage_by_pft_class = ', this%coage_by_pft_class
write(fates_log(),*) 'cohort%gpp_acc_hold = ', this%gpp_acc_hold
write(fates_log(),*) 'cohort%gpp_acc = ', this%gpp_acc
write(fates_log(),*) 'cohort%gpp_tstep = ', this%gpp_tstep
write(fates_log(),*) 'cohort%npp_acc_hold = ', this%npp_acc_hold
write(fates_log(),*) 'cohort%npp_acc = ', this%npp_acc
write(fates_log(),*) 'cohort%resp_m_tstep = ', this%resp_m_tstep
write(fates_log(),*) 'cohort%resp_m_acc = ', this%resp_m_acc
write(fates_log(),*) 'cohort%resp_m_acc_hold = ', this%resp_m_acc_hold
write(fates_log(),*) 'cohort%resp_g_acc_hold = ', this%resp_g_acc_hold
write(fates_log(),*) 'cohort%rdark = ', this%rdark
write(fates_log(),*) 'cohort%livestem_mr = ', this%livestem_mr
write(fates_log(),*) 'cohort%livecroot_mr = ', this%livecroot_mr
write(fates_log(),*) 'cohort%froot_mr = ', this%froot_mr
write(fates_log(),*) 'cohort%dgmort = ', this%dgmort
write(fates_log(),*) 'cohort%treelai = ', this%treelai
write(fates_log(),*) 'cohort%treesai = ', this%treesai
Expand Down
Loading