diff --git a/biogeochem/EDMortalityFunctionsMod.F90 b/biogeochem/EDMortalityFunctionsMod.F90 index 312b01bb83..8bd66568a0 100644 --- a/biogeochem/EDMortalityFunctionsMod.F90 +++ b/biogeochem/EDMortalityFunctionsMod.F90 @@ -86,8 +86,9 @@ subroutine mortality_rates( cohort_in,bc_in, btran_ft, mean_temp, & real(r8) :: target_leaf_c ! target leaf biomass for the current trim status and ! damage class [kgC] real(r8) :: store_c - real(r8) :: hf_sm_threshold ! hydraulic failure soil moisture threshold - real(r8) :: hf_flc_threshold ! hydraulic failure fractional loss of conductivity threshold + real(r8) :: mort_hydrfailure_threshold ! hydraulic failure threshold (btran units). When + ! FATES-Hydro is enabled, this is equivalent to + ! fraction of maximum conductivity (fmc) real(r8) :: mort_ip_size_senescence ! inflection point for increase in mortality with dbh real(r8) :: mort_r_size_senescence ! rate of mortality increase with dbh in senesence term real(r8) :: mort_ip_age_senescence ! inflection point for increase in mortality with age @@ -98,7 +99,6 @@ subroutine mortality_rates( cohort_in,bc_in, btran_ft, mean_temp, & real(r8) :: min_fmc_tr ! minimum fraction of maximum conductivity for transporting root real(r8) :: min_fmc_ar ! minimum fraction of maximum conductivity for absorbing root real(r8) :: min_fmc ! minimum fraction of maximum conductivity for whole plant - real(r8) :: flc ! fractional loss of conductivity logical :: is_decid_dormant ! Flag to signal that the cohort is deciduous and dormant @@ -160,36 +160,41 @@ subroutine mortality_rates( cohort_in,bc_in, btran_ft, mean_temp, & bmort = EDPftvarcon_inst%bmort(cohort_in%pft) ! Proxy for hydraulic failure induced mortality. - hf_sm_threshold = EDPftvarcon_inst%hf_sm_threshold(cohort_in%pft) - hf_flc_threshold = EDPftvarcon_inst%hf_flc_threshold(cohort_in%pft) - - if (hlm_use_planthydro == itrue) then - !note the flc is set as the fraction of max conductivity in hydro - min_fmc_ag = minval(cohort_in%co_hydr%ftc_ag(:)) - min_fmc_tr = cohort_in%co_hydr%ftc_troot - min_fmc_ar = minval(cohort_in%co_hydr%ftc_aroot(:)) - min_fmc = min(min_fmc_ag, min_fmc_tr) - min_fmc = min(min_fmc, min_fmc_ar) - flc = 1.0_r8-min_fmc - if(flc >= hf_flc_threshold .and. hf_flc_threshold < 1.0_r8 )then - hmort = (flc-hf_flc_threshold)/(1.0_r8-hf_flc_threshold) * & - EDPftvarcon_inst%mort_scalar_hydrfailure(cohort_in%pft) + mort_hydrfailure_threshold = EDPftvarcon_inst%mort_hydrfailure_threshold(cohort_in%pft) + + ! Make sure the hydraulic failure mortality threshold is positive. In case it is + ! zero, we bypass the mortality calculation altogether. + if ( mort_hydrfailure_threshold > nearzero ) then + ! We calculate the fraction of maximum conductivity differently, depending on + ! whether FATES-Hydro is enabled or disabled. + if (hlm_use_planthydro == itrue) then + ! FATES-Hydro enabled: set fmc as the fraction of max conductivity in hydro + min_fmc_ag = minval(cohort_in%co_hydr%ftc_ag(:)) + min_fmc_tr = cohort_in%co_hydr%ftc_troot + min_fmc_ar = minval(cohort_in%co_hydr%ftc_aroot(:)) + min_fmc = min(min_fmc_ag, min_fmc_tr) + min_fmc = min(min_fmc, min_fmc_ar) + else if ( (.not. is_decid_dormant) .and. & + ( ( minval(bc_in%t_soisno_sl) - tfrz ) > soil_tfrz_thresh ) ) then + ! FATES-Hydro disabled: set fmc as btran + min_fmc = btran_ft(cohort_in%pft) else - hmort = 0.0_r8 - endif + ! Dormant plant, or plant in frozen soils, assume conductivity at the threshold, + ! which effectively sets mortality to zero. + min_fmc = mort_hydrfailure_threshold + end if + + ! Hydraulic failure mortality increases as fmc decreases. Note that this is different + ! than before when FATES-Hydro was disabled, in which mortality followed a step function. + hmort = max( 0.0_r8, ( mort_hydrfailure_threshold - min_fmc ) / mort_hydrfailure_threshold ) * & + EDPftvarcon_inst%mort_scalar_hydrfailure(cohort_in%pft) else - ! When FATES-Hydro is off, hydraulic failure mortality occurs only when btran - ! falls below a threshold and plants have leaves. - if ( (.not. is_decid_dormant) .and. & - ( btran_ft(cohort_in%pft) <= hf_sm_threshold ) .and. & - ( ( minval(bc_in%t_soisno_sl) - tfrz ) > soil_tfrz_thresh ) ) then - hmort = EDPftvarcon_inst%mort_scalar_hydrfailure(cohort_in%pft) - else - hmort = 0.0_r8 - end if + ! Assume zero hydraulic failure mortality. + hmort = 0.0_r8 end if + ! Carbon Starvation induced mortality. if ( cohort_in%dbh > 0._r8 ) then diff --git a/main/EDPftvarcon.F90 b/main/EDPftvarcon.F90 index 835ffab36f..1ecbbe9520 100644 --- a/main/EDPftvarcon.F90 +++ b/main/EDPftvarcon.F90 @@ -87,10 +87,10 @@ module EDPftvarcon real(r8), allocatable :: mort_r_age_senescence(:) ! rate of change in mortality with age real(r8), allocatable :: mort_scalar_coldstress(:) ! maximum mortality rate from cold stress real(r8), allocatable :: mort_scalar_cstarvation(:) ! maximum mortality rate from carbon starvation - real(r8), allocatable :: mort_scalar_hydrfailure(:) ! maximum mortality rate from hydraulic failure real(r8), allocatable :: mort_upthresh_cstarvation(:) ! threshold for storage biomass (relative to target leaf biomass) above which carbon starvation is zero - real(r8), allocatable :: hf_sm_threshold(:) ! soil moisture (btran units) at which drought mortality begins for non-hydraulic model - real(r8), allocatable :: hf_flc_threshold(:) ! plant fractional loss of conductivity at which drought mortality begins for hydraulic model + real(r8), allocatable :: mort_scalar_hydrfailure(:) ! maximum mortality rate from hydraulic failure + real(r8), allocatable :: mort_hydrfailure_threshold(:) ! threshold (btran units) below which drought mortality begins. For FATES-Hydro, this is numerically + ! equivalent to the fraction of total conductivity (or one minus fraction of loss of conductivity) real(r8), allocatable :: germination_rate(:) ! Fraction of seed mass germinating per year (yr-1) real(r8), allocatable :: seed_decay_rate(:) ! Fraction of seed mass (both germinated and @@ -510,6 +510,10 @@ subroutine Register_PFT(this, fates_params) call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) + name = 'fates_mort_hydrfailure_threshold' + call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & + dimension_names=dim_names, lower_bounds=dim_lower_bound) + name = 'fates_mort_r_size_senescence' call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) @@ -542,14 +546,6 @@ subroutine Register_PFT(this, fates_params) call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) - name = 'fates_mort_hf_sm_threshold' - call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & - dimension_names=dim_names, lower_bounds=dim_lower_bound) - - name = 'fates_mort_hf_flc_threshold' - call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & - dimension_names=dim_names, lower_bounds=dim_lower_bound) - name = 'fates_recruit_seed_germination_rate' call fates_params%RegisterParameter(name=name, dimension_shape=dimension_shape_1d, & dimension_names=dim_names, lower_bounds=dim_lower_bound) @@ -927,14 +923,17 @@ subroutine Receive_PFT(this, fates_params) call fates_params%RetrieveParameterAllocate(name=name, & data=this%mort_scalar_cstarvation) + name = 'fates_mort_upthresh_cstarvation' + call fates_params%RetrieveParameterAllocate(name=name, & + data=this%mort_upthresh_cstarvation) + name = 'fates_mort_scalar_hydrfailure' call fates_params%RetrieveParameterAllocate(name=name, & data=this%mort_scalar_hydrfailure) - name = 'fates_mort_upthresh_cstarvation' + name = 'fates_mort_hydrfailure_threshold' call fates_params%RetrieveParameterAllocate(name=name, & - data=this%mort_upthresh_cstarvation) - + data=this%mort_hydrfailure_threshold) name = 'fates_mort_ip_size_senescence' call fates_params%RetrieveParameterAllocate(name=name, & @@ -964,15 +963,6 @@ subroutine Receive_PFT(this, fates_params) call fates_params%RetrieveParameterAllocate(name=name, & data=this%mort_upthresh_cstarvation) - - name = 'fates_mort_hf_sm_threshold' - call fates_params%RetrieveParameterAllocate(name=name, & - data=this%hf_sm_threshold) - - name = 'fates_mort_hf_flc_threshold' - call fates_params%RetrieveParameterAllocate(name=name, & - data=this%hf_flc_threshold) - name = 'fates_recruit_seed_germination_rate' call fates_params%RetrieveParameterAllocate(name=name, & data=this%germination_rate) @@ -1603,8 +1593,7 @@ subroutine FatesReportPFTParams(is_master) write(fates_log(),fmt0) 'mort_scalar_cstarvation = ',EDPftvarcon_inst%mort_scalar_cstarvation write(fates_log(),fmt0) 'mort_scalar_hydrfailure = ',EDPftvarcon_inst%mort_scalar_hydrfailure write(fates_log(),fmt0) 'mort_upthresh_cstarvation = ',EDPftvarcon_inst%mort_upthresh_cstarvation - write(fates_log(),fmt0) 'hf_sm_threshold = ',EDPftvarcon_inst%hf_sm_threshold - write(fates_log(),fmt0) 'hf_flc_threshold = ',EDPftvarcon_inst%hf_flc_threshold + write(fates_log(),fmt0) 'mort_hydrfailure_threshold = ',EDPftvarcon_inst%mort_hydrfailure_threshold write(fates_log(),fmt0) 'germination_timescale = ',EDPftvarcon_inst%germination_rate write(fates_log(),fmt0) 'seed_decay_turnover = ',EDPftvarcon_inst%seed_decay_rate diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 9fb97c811f..67264ca174 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -444,12 +444,9 @@ variables: double fates_mort_freezetol(fates_pft) ; fates_mort_freezetol:units = "degrees C" ; fates_mort_freezetol:long_name = "minimum temperature tolerance" ; - double fates_mort_hf_flc_threshold(fates_pft) ; - fates_mort_hf_flc_threshold:units = "fraction" ; - fates_mort_hf_flc_threshold:long_name = "plant fractional loss of conductivity at which drought mortality begins for hydraulic model" ; - double fates_mort_hf_sm_threshold(fates_pft) ; - fates_mort_hf_sm_threshold:units = "unitless" ; - fates_mort_hf_sm_threshold:long_name = "soil moisture (btran units) at which drought mortality begins for non-hydraulic model" ; + double fates_mort_hydrfailure_threshold(fates_pft) ; + fates_mort_hydrfailure_threshold:units = "fraction" ; + fates_mort_hydrfailure_threshold:long_name = "threshold (btran units) below which hydraulic failure mortality begins. When running FATES-Hydro, this is numerically equivalent to fraction of maximum conductivity (or one minus fraction of loss of conductivity)." ; double fates_mort_ip_age_senescence(fates_pft) ; fates_mort_ip_age_senescence:units = "years" ; fates_mort_ip_age_senescence:long_name = "Mortality cohort age senescence inflection point. If _ this mortality term is off. Setting this value turns on age dependent mortality. " ; @@ -1423,12 +1420,9 @@ data: fates_mort_freezetol = 2.5, -55, -80, -30, 2.5, -80, -60, -10, -80, -71, -95, -89, -20, 2.5 ; - fates_mort_hf_flc_threshold = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, + fates_mort_hydrfailure_threshold = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_mort_hf_sm_threshold = 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, - 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06 ; - fates_mort_ip_age_senescence = _, _, _, _, _, _, _, _, _, _, _, _, _, _ ; fates_mort_ip_size_senescence = _, _, _, _, _, _, _, _, _, _, _, _, _, _ ;