diff --git a/build/source/engine/ssdNrgFlux.f90 b/build/source/engine/ssdNrgFlux.f90
index b9c791860328b491d312bf85ac0509c6c8b83447..04985bd66b3fed274581ce406df9ccab9d735d66 100644
--- a/build/source/engine/ssdNrgFlux.f90
+++ b/build/source/engine/ssdNrgFlux.f90
@@ -20,965 +20,964 @@
 
 module ssdNrgFlux_module
 
-    ! data types
-    USE nrtype
-    
-    ! data types
-    USE data_types,only:var_d           ! x%var(:)       (rkind)
-    USE data_types,only:var_dlength     ! x%var(:)%dat   (rkind)
-    USE data_types,only:var_ilength     ! x%var(:)%dat   (i4b)
-    
-    ! physical constants
-    USE multiconst,only:&
-                        sb,          & ! Stefan Boltzman constant      (W m-2 K-4)
-                        Em_Sno,      & ! emissivity of snow            (-)
-                        LH_fus,      & ! latent heat of fusion         (J kg-1)
-                        LH_vap,      & ! latent heat of vaporization   (J kg-1)
-                        LH_sub,      & ! latent heat of sublimation    (J kg-1)
-                        gravity,     & ! gravitational acceleteration  (m s-2)
-                        Tfreeze,     & ! freezing point of pure water  (K)
-                        iden_air,    & ! intrinsic density of air      (kg m-3)
-                        iden_ice,    & ! intrinsic density of ice      (kg m-3)
-                        iden_water,  &  ! intrinsic density of water    (kg m-3)
-                        ! specific heat
-                        Cp_air,      & ! specific heat of air          (J kg-1 K-1)
-                        Cp_water,    & ! specific heat of liquid water (J kg-1 K-1)
-                        ! thermal conductivity
-                        lambda_air,  & ! thermal conductivity of air   (J s-1 m-1)
-                        lambda_ice,  & ! thermal conductivity of ice   (J s-1 m-1)
-                        lambda_water   ! thermal conductivity of water (J s-1 m-1)
-    
-    
-    ! missing values
-    USE globalData,only:integerMissing  ! missing integer
-    USE globalData,only:realMissing     ! missing real number
-    
-    ! named variables for snow and soil
-    USE globalData,only:iname_snow     ! named variables for snow
-    USE globalData,only:iname_soil     ! named variables for soil
-    
-    ! named variables
-    USE var_lookup,only:iLookPROG       ! named variables for structure elements
-    USE var_lookup,only:iLookDIAG       ! named variables for structure elements
-    USE var_lookup,only:iLookFLUX       ! named variables for structure elements
-    USE var_lookup,only:iLookPARAM      ! named variables for structure elements
-    USE var_lookup,only:iLookINDEX      ! named variables for structure elements
-    
-    ! model decisions
-    USE globalData,only:model_decisions                         ! model decision structure
-    USE var_lookup,only:iLookDECISIONS                          ! named variables for elements of the decision structure
-    
-    ! provide access to look-up values for model decisions
-    USE mDecisions_module,only:      &
-     ! look-up values for method used to compute derivative
-     numerical,                      & ! numerical solution
-     analytical,                     & ! analytical solution
-     ! look-up values for choice of boundary conditions for thermodynamics
-     prescribedTemp,                 & ! prescribed temperature
-     energyFlux,                     & ! energy flux
-     zeroFlux,                       & ! zero flux
-     ! look-up values for choice of boundary conditions for soil hydrology
-     prescribedHead,                 & ! prescribed head
-     ! look-up values for choice of thermal conductivity representation for snow
-     Yen1965,                        & ! Yen (1965)
-     Mellor1977,                     & ! Mellor (1977)
-     Jordan1991,                     & ! Jordan (1991)
-     Smirnova2000,                   & ! Smirnova et al. (2000)
-     ! look-up values for choice of thermal conductivity representation for soil
-     funcSoilWet,                    & ! function of soil wetness
-     mixConstit,                     & ! mixture of constituents
-     hanssonVZJ,                     & ! test case for the mizoguchi lab experiment, Hansson et al. VZJ 2004
-     ! look-up values for the form of Richards' equation
-     moisture,                       & ! moisture-based form of Richards' equation
-     mixdform                          ! mixed form of Richards' equation
-    
-    ! -------------------------------------------------------------------------------------------------
-    implicit none
-    private
-    public::ssdNrgFlux
-    ! global parameters
-    real(rkind),parameter            :: dx=1.e-10_rkind             ! finite difference increment (K)
-    contains
-    
-    
-     ! **********************************************************************************************************
-     ! public subroutine ssdNrgFlux: compute energy fluxes and derivatives at layer interfaces
-     ! **********************************************************************************************************
-     subroutine ssdNrgFlux(&
-                           ! input: model control
-                           scalarSolution,                     & ! intent(in):    flag to indicate the scalar solution
-                           deriv_desired,                & ! intent(in): flag indicating if derivatives are desired
-                           ! input: fluxes and derivatives at the upper boundary
-                           groundNetFlux,                      & ! intent(in):    total flux at the ground surface (W m-2)
-                           dGroundNetFlux_dGroundTemp,         & ! intent(in):    derivative in total ground surface flux w.r.t. ground temperature (W m-2 K-1)
-                           ! input: liquid water fluxes
-                           iLayerLiqFluxSnow,                  & ! intent(in):    liquid flux at the interface of each snow layer (m s-1)
-                           iLayerLiqFluxSoil,                  & ! intent(in):    liquid flux at the interface of each soil layer (m s-1)
-                           ! input: trial value of model state variables
-                           mLayerTempTrial,                    & ! intent(in):    trial temperature at the current iteration (K)
-                           mLayerMatricHeadTrial,              & ! intent(in):    trial matric head at the current iteration(m)
-                           mLayerVolFracLiqTrial,              & ! intent(in):    trial volumetric fraction of liquid water at the current iteration(-)
-                           mLayerVolFracIceTrial,              & ! intent(in):    trial volumetric fraction of ice water at the current iteration(-)
-                           ! input: pre-computed derivatives
-                           mLayerdTheta_dTk,                   & ! intent(in):    derivative in volumetric liquid water content w.r.t. temperature (K-1)
-                           mLayerFracLiqSnow,                  & ! intent(in):    fraction of liquid water (-)
-                           ! input-output: data structures
-                           mpar_data,                          & ! intent(in):    model parameters
-                           indx_data,                          & ! intent(in):    model indices
-                           prog_data,                          & ! intent(in):    model prognostic variables for a local HRU
-                           diag_data,                          & ! intent(inout):    model diagnostic variables for a local HRU
-                           flux_data,                          & ! intent(inout): model fluxes for a local HRU
-                           ! output: fluxes and derivatives at all layer interfaces
-                           iLayerNrgFlux,                      & ! intent(out):   energy flux at the layer interfaces (W m-2)
-                           dFlux_dTempAbove,                   & ! intent(out):   derivatives in the flux w.r.t. temperature in the layer above (W m-2 K-1)
-                           dFlux_dTempBelow,                   & ! intent(out):   derivatives in the flux w.r.t. temperature in the layer below (W m-2 K-1)
-                           dFlux_dWatAbove,                    & ! intent(out):   derivatives in the flux w.r.t. water state in the layer above (W m-2 K-1)
-                           dFlux_dWatBelow,                    & ! intent(out):   derivatives in the flux w.r.t. water state in the layer below (W m-2 K-1)
-                          ! output: error control
-                           err,message)                          ! intent(out): error control
-     ! utility modules
-     USE soil_utils_module,only:volFracLiq     ! compute volumetric fraction of liquid water
-     USE soil_utils_module,only:matricHead     ! compute the matric head based on volumetric water content
-     USE soil_utils_module,only:crit_soilT     ! compute critical temperature below which ice exists
-     USE snow_utils_module,only:fracliquid     ! compute fraction of liquid water at a given temperature
-     USE soil_utils_module,only:dTheta_dPsi    ! compute derivative of the soil moisture characteristic w.r.t. psi (m-1)
-     USE soil_utils_module,only:dPsi_dTheta    ! compute derivative of the soil moisture characteristic w.r.t. theta (m)
-    
-     ! constants
-     USE multiconst, only: gravity, &                          ! gravitational acceleration (m s-1)
-                          Tfreeze, &                          ! freezing point of water (K)
-                          iden_water,iden_ice,&      ! intrinsic density of water and ice (kg m-3)
-                          LH_fus                              ! latent heat of fusion (J kg-1)
-     ! -------------------------------------------------------------------------------------------------------------------------------------------------
-     implicit none
-     ! input: model control
-     logical(lgt),intent(in)            :: scalarSolution              ! flag to denote if implementing the scalar solution
-     logical(lgt),intent(in)            :: deriv_desired               ! flag indicating if derivatives are desired
-     ! input: fluxes and derivatives at the upper boundary
-     real(rkind),intent(in)             :: groundNetFlux               ! net energy flux for the ground surface (W m-2)
-     real(rkind),intent(inout)          :: dGroundNetFlux_dGroundTemp  ! derivative in net ground flux w.r.t. ground temperature (W m-2 K-1)
-     ! input: liquid water fluxes
-     real(rkind),intent(in)             :: iLayerLiqFluxSnow(0:)       ! liquid flux at the interface of each snow layer (m s-1)
-     real(rkind),intent(in)             :: iLayerLiqFluxSoil(0:)       ! liquid flux at the interface of each soil layer (m s-1)
-     ! input: trial model state variables
-     real(rkind),intent(in)              :: mLayerTempTrial(:)         ! temperature in each layer at the current iteration (m)
-     real(rkind),intent(in)              :: mLayerMatricHeadTrial(:)   ! matric head in each layer at the current iteration (m)
-     real(rkind),intent(in)              :: mLayerVolFracLiqTrial(:)   ! volumetric fraction of liquid at the current iteration (-)
-     real(rkind),intent(in)              :: mLayerVolFracIceTrial(:)   ! volumetric fraction of ice at the current iteration (-)
-    ! input: pre-computed derivatives
-     real(rkind),intent(in)              :: mLayerdTheta_dTk(:)        ! derivative in volumetric liquid water content w.r.t. temperature (K-1)
-     real(rkind),intent(in)              :: mLayerFracLiqSnow(:)       ! fraction of liquid water (-)
-     ! input-output: data structures
-     type(var_dlength),intent(in)        :: mpar_data                  ! model parameters
-     type(var_ilength),intent(in)        :: indx_data                  ! state vector geometry
-     type(var_dlength),intent(in)        :: prog_data                  ! prognostic variables for a local HRU
-     type(var_dlength),intent(inout)        :: diag_data                  ! diagnostic variables for a local HRU
-     type(var_dlength),intent(inout)     :: flux_data                  ! model fluxes for a local HRU
-     ! output: fluxes and derivatives at all layer interfaces
-     real(rkind),intent(out)             :: iLayerNrgFlux(0:)          ! energy flux at the layer interfaces (W m-2)
-     real(rkind),intent(out)             :: dFlux_dTempAbove(0:)       ! derivatives in the flux w.r.t. temperature in the layer above (J m-2 s-1 K-1)
-     real(rkind),intent(out)             :: dFlux_dTempBelow(0:)       ! derivatives in the flux w.r.t. temperature in the layer below (J m-2 s-1 K-1)
-     real(rkind),intent(out)             :: dFlux_dWatAbove(0:)        ! derivatives in the flux w.r.t. water state in the layer above (J m-2 s-1 K-1)
-     real(rkind),intent(out)             :: dFlux_dWatBelow(0:)        ! derivatives in the flux w.r.t. water state in the layer below (J m-2 s-1 K-1)
-     ! output: error control
-     integer(i4b),intent(out)            :: err                        ! error code
-     character(*),intent(out)            :: message                    ! error message
-     ! ------------------------------------------------------------------------------------------------------------------------------------------------------
-     ! local variables
-     character(LEN=256)               :: cmessage                     ! error message of downwind routine
-     integer(i4b)                     :: i,j,iLayer                   ! index of model layers
-     integer(i4b)                     :: ixLayerDesired(1)            ! layer desired (scalar solution)
-     integer(i4b)                     :: ixTop                        ! top layer in subroutine call
-     integer(i4b)                     :: ixBot                        ! bottom layer in subroutine call
-     real(rkind)                      :: qFlux                        ! liquid flux at layer interfaces (m s-1)
-     real(rkind)                      :: dz                           ! height difference (m)
-     ! additional variables to compute numerical derivatives
-     integer(i4b)                     :: nFlux                        ! number of flux calculations required (>1 = numerical derivatives with one-sided finite differences)
-     integer(i4b)                     :: itry                         ! index of different flux calculations
-     integer(i4b),parameter           :: unperturbed=0                ! named variable to identify the case of unperturbed state variables
-     integer(i4b),parameter           :: perturbState=1               ! named variable to identify the case where we perturb the state in the current layer
-     integer(i4b),parameter           :: perturbStateTempAbove=2      ! named variable to identify the case where we perturb the state layer above
-     integer(i4b),parameter           :: perturbStateTempBelow=3      ! named variable to identify the case where we perturb the state layer below
-     integer(i4b),parameter           :: perturbStateWatAbove=4       ! named variable to identify the case where we perturb the state layer above
-     integer(i4b),parameter           :: perturbStateWatBelow=5       ! named variable to identify the case where we perturb the state layer below
-     integer(i4b)                     :: ixPerturb                    ! index of element in 2-element vector to perturb
-     integer(i4b)                     :: ixOriginal                   ! index of perturbed element in the original vector
-     real(rkind)                      :: scalarThermCFlux               ! thermal conductivity (W m-1 K-1)
-     real(rkind)                      :: scalarThermCFlux_dTempAbove    ! thermal conductivity with perturbation to the temperature state above (W m-1 K-1)
-     real(rkind)                      :: scalarThermCFlux_dTempBelow    ! thermal conductivity with perturbation to the temperature state below (W m-1 K-1)
-     real(rkind)                      :: scalarThermCFlux_dWatAbove     ! thermal conductivity with perturbation to the water state above
-     real(rkind)                      :: scalarThermCFlux_dWatBelow     ! thermal conductivity with perturbation to the water state below
-     real(rkind)                      :: flux0,flux1,flux2            ! fluxes used to calculate derivatives (W m-2)
-     ! compute fluxes and derivatives at layer interfaces
-     integer(i4b),dimension(2)        :: mLayer_ind                   ! indices of above and below layers
-     integer(i4b),dimension(2)        :: iLayer_ind                   ! indices of above and below interfaces
-     real(rkind)                      :: matricFHead                  ! matric head for frozen soil
-     real(rkind)                      :: Tcrit                        ! temperature where all water is unfrozen (K)
-     real(rkind)                      :: fLiq                         ! fraction of liquid water (-)
-     real(rkind),dimension(2)         :: vectorMatricHeadTrial        ! trial value of matric head (m)
-     real(rkind),dimension(2)         :: vectorVolFracLiqTrial        ! trial value of volumetric liquid content (-)
-     real(rkind),dimension(2)         :: vectorVolFracIceTrial        ! trial value of volumetric ice content (-)
-     real(rkind),dimension(2)         :: vectorTempTrial              ! trial value of temperature (K)
-     real(rkind),dimension(2)         :: vectordTheta_dPsi            ! derivative in the soil water characteristic w.r.t. psi (m-1)
-     real(rkind),dimension(2)         :: vectordPsi_dTheta            ! derivative in the soil water characteristic w.r.t. theta (m)
-     real(rkind),dimension(2)         :: vectorFracLiqSnow            ! fraction of liquid water (-)
-     real(rkind),dimension(2)         :: vectortheta_sat              ! layer above and below soil porosity (-)
-     real(rkind),dimension(2)         :: vectoriden_soil              ! layer above and below density of soil (kg m-3)
-     real(rkind),dimension(2)         :: vectorthCond_soil            ! layer above and below thermal conductivity of soil (W m-1 K-1)
-     real(rkind),dimension(2)         :: vectorfrac_sand              ! layer above and below fraction of sand (-)
-     real(rkind),dimension(2)         :: vectorfrac_clay              ! layer above and below fraction of clay (-)
-     ! recompute the perturbed version of iLayerThermalC, this could be the only version and remove the omputThermConduct_module
-     real(rkind)                      :: dThermalC_dHydStateAbove     ! derivative in the thermal conductivity w.r.t. water state in the layer above
-     real(rkind)                      :: dThermalC_dHydStateBelow     ! derivative in the thermal conductivity w.r.t. water state in the layer above
-     real(rkind)                      :: dThermalC_dNrgStateAbove     ! derivative in the thermal conductivity w.r.t. energy state in the layer above
-     real(rkind)                      :: dThermalC_dNrgStateBelow     ! derivative in the thermal conductivity w.r.t. energy state in the layer above
-     ! ------------------------------------------------------------------------------------------------------------------------------------------------------
-     ! make association of local variables with information in the data structures
-     associate(&
-      ixDerivMethod           => model_decisions(iLookDECISIONS%fDerivMeth)%iDecision,      & ! intent(in): method used to calculate flux derivatives
-      ix_bcUpprTdyn           => model_decisions(iLookDECISIONS%bcUpprTdyn)%iDecision,      & ! intent(in): method used to calculate the upper boundary condition for thermodynamics
-      ix_bcLowrTdyn           => model_decisions(iLookDECISIONS%bcLowrTdyn)%iDecision,      & ! intent(in): method used to calculate the lower boundary condition for thermodynamics
-      ixRichards                 => model_decisions(iLookDECISIONS%f_Richards)%iDecision,   & ! intent(in): index of the form of Richards' equation
-      ixThCondSnow            => model_decisions(iLookDECISIONS%thCondSnow)%iDecision,      & ! intent(in): choice of method for thermal conductivity of snow
-      ixThCondSoil            => model_decisions(iLookDECISIONS%thCondSoil)%iDecision,      & ! intent(in): choice of method for thermal conductivity of soil
-      ! input: model coordinates
-      nSnow                   => indx_data%var(iLookINDEX%nSnow)%dat(1),               & ! intent(in): number of snow layers
-      nLayers                 => indx_data%var(iLookINDEX%nLayers)%dat(1),             & ! intent(in): total number of layers
-      layerType               => indx_data%var(iLookINDEX%layerType)%dat,              & ! intent(in): layer type (iname_soil or iname_snow)
-      ixLayerState            => indx_data%var(iLookINDEX%ixLayerState)%dat,           & ! intent(in): list of indices for all model layers
-      ixSnowSoilNrg           => indx_data%var(iLookINDEX%ixSnowSoilNrg)%dat,          & ! intent(in): index in the state subset for energy state variables in the snow+soil domain
-      ! input: thermal properties
-      mLayerDepth             => prog_data%var(iLookPROG%mLayerDepth)%dat,             & ! intent(in): depth of each layer (m)
-      mLayerHeight            => prog_data%var(iLookPROG%mLayerHeight)%dat,            & ! intent(in): height at the mid-point of each layer (m)
-      upperBoundTemp          => mpar_data%var(iLookPARAM%upperBoundTemp)%dat(1),      & ! intent(in): temperature of the upper boundary (K)
-      lowerBoundTemp          => mpar_data%var(iLookPARAM%lowerBoundTemp)%dat(1),      & ! intent(in): temperature of the lower boundary (K)
-      iLayerHeight            => prog_data%var(iLookPROG%iLayerHeight)%dat,            & ! intent(in): height at the interface of each layer (m)
-      fixedThermalCond_snow   => mpar_data%var(iLookPARAM%fixedThermalCond_snow)%dat(1),    & ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
-      iLayerThermalC          => diag_data%var(iLookDIAG%iLayerThermalC)%dat,          & ! intent(inout): thermal conductivity at the interface of each layer (W m-1 K-1)
-      ! input: depth varying soil parameters
-      iden_soil               => mpar_data%var(iLookPARAM%soil_dens_intr)%dat,              & ! intent(in): intrinsic density of soil (kg m-3)
-      thCond_soil             => mpar_data%var(iLookPARAM%thCond_soil)%dat,                 & ! intent(in): thermal conductivity of soil (W m-1 K-1)
-      theta_sat               => mpar_data%var(iLookPARAM%theta_sat)%dat,                   & ! intent(in): soil porosity (-)
-      frac_sand               => mpar_data%var(iLookPARAM%frac_sand)%dat,                   & ! intent(in): fraction of sand (-)
-      frac_clay               => mpar_data%var(iLookPARAM%frac_clay)%dat,                   & ! intent(in): fraction of clay (-)
-      vGn_m                   => diag_data%var(iLookDIAG%scalarVGn_m)%dat,                  & ! intent(in):  [dp(:)] van Genutchen "m" parameter (-)
-      vGn_n                   => mpar_data%var(iLookPARAM%vGn_n)%dat,                       & ! intent(in):  [dp(:)] van Genutchen "n" parameter (-)
-      vGn_alpha               => mpar_data%var(iLookPARAM%vGn_alpha)%dat,                   & ! intent(in):  [dp(:)] van Genutchen "alpha" parameter (m-1)
-      theta_res               => mpar_data%var(iLookPARAM%theta_res)%dat,                   & ! intent(in):  [dp(:)] soil residual volumetric water content (-)
-      ! input: snow parameters
-      snowfrz_scale           => mpar_data%var(iLookPARAM%snowfrz_scale)%dat(1),            & ! intent(in):  [dp] scaling parameter for the snow freezing curve (K-1)
-      ! output: diagnostic fluxes
-      iLayerConductiveFlux => flux_data%var(iLookFLUX%iLayerConductiveFlux)%dat,    & ! intent(out): conductive energy flux at layer interfaces at end of time step (W m-2)
-      iLayerAdvectiveFlux  => flux_data%var(iLookFLUX%iLayerAdvectiveFlux)%dat      & ! intent(out): advective energy flux at layer interfaces at end of time step (W m-2)
-     )  ! association of local variables with information in the data structures
-     ! ------------------------------------------------------------------------------------------------------------------------------------------------------
-     ! initialize error control
-     err=0; message='ssdNrgFlux/'
-    
-     ! set conductive and advective fluxes to missing in the upper boundary
-     ! NOTE: advective flux at the upper boundary is included in the ground heat flux
-     iLayerConductiveFlux(0) = realMissing
-     iLayerAdvectiveFlux(0)  = realMissing
-    
-     ! check the need to compute numerical derivatives
-     if(ixDerivMethod==numerical)then
+! data types
+USE nrtype
+
+! data types
+USE data_types,only:var_d           ! x%var(:)       (rkind)
+USE data_types,only:var_dlength     ! x%var(:)%dat   (rkind)
+USE data_types,only:var_ilength     ! x%var(:)%dat   (i4b)
+
+! physical constants
+USE multiconst,only:&
+                    sb,          & ! Stefan Boltzman constant      (W m-2 K-4)
+                    Em_Sno,      & ! emissivity of snow            (-)
+                    LH_fus,      & ! latent heat of fusion         (J kg-1)
+                    LH_vap,      & ! latent heat of vaporization   (J kg-1)
+                    LH_sub,      & ! latent heat of sublimation    (J kg-1)
+                    gravity,     & ! gravitational acceleteration  (m s-2)
+                    Tfreeze,     & ! freezing point of pure water  (K)
+                    iden_air,    & ! intrinsic density of air      (kg m-3)
+                    iden_ice,    & ! intrinsic density of ice      (kg m-3)
+                    iden_water,  &  ! intrinsic density of water    (kg m-3)
+                    ! specific heat
+                    Cp_air,      & ! specific heat of air          (J kg-1 K-1)
+                    Cp_water,    & ! specific heat of liquid water (J kg-1 K-1)
+                    ! thermal conductivity
+                    lambda_air,  & ! thermal conductivity of air   (J s-1 m-1)
+                    lambda_ice,  & ! thermal conductivity of ice   (J s-1 m-1)
+                    lambda_water   ! thermal conductivity of water (J s-1 m-1)
+
+
+! missing values
+USE globalData,only:integerMissing  ! missing integer
+USE globalData,only:realMissing     ! missing real number
+
+! named variables for snow and soil
+USE globalData,only:iname_snow     ! named variables for snow
+USE globalData,only:iname_soil     ! named variables for soil
+
+! named variables
+USE var_lookup,only:iLookPROG       ! named variables for structure elements
+USE var_lookup,only:iLookDIAG       ! named variables for structure elements
+USE var_lookup,only:iLookFLUX       ! named variables for structure elements
+USE var_lookup,only:iLookPARAM      ! named variables for structure elements
+USE var_lookup,only:iLookINDEX      ! named variables for structure elements
+
+! model decisions
+USE globalData,only:model_decisions                         ! model decision structure
+USE var_lookup,only:iLookDECISIONS                          ! named variables for elements of the decision structure
+
+! provide access to look-up values for model decisions
+USE mDecisions_module,only:      &
+  ! look-up values for method used to compute derivative
+  numerical,                      & ! numerical solution
+  analytical,                     & ! analytical solution
+  ! look-up values for choice of boundary conditions for thermodynamics
+  prescribedTemp,                 & ! prescribed temperature
+  energyFlux,                     & ! energy flux
+  zeroFlux,                       & ! zero flux
+  ! look-up values for choice of boundary conditions for soil hydrology
+  prescribedHead,                 & ! prescribed head
+  ! look-up values for choice of thermal conductivity representation for snow
+  Yen1965,                        & ! Yen (1965)
+  Mellor1977,                     & ! Mellor (1977)
+  Jordan1991,                     & ! Jordan (1991)
+  Smirnova2000,                   & ! Smirnova et al. (2000)
+  ! look-up values for choice of thermal conductivity representation for soil
+  funcSoilWet,                    & ! function of soil wetness
+  mixConstit,                     & ! mixture of constituents
+  hanssonVZJ,                     & ! test case for the mizoguchi lab experiment, Hansson et al. VZJ 2004
+  ! look-up values for the form of Richards' equation
+  moisture,                       & ! moisture-based form of Richards' equation
+  mixdform                          ! mixed form of Richards' equation
+
+! -------------------------------------------------------------------------------------------------
+implicit none
+private
+public::ssdNrgFlux
+! global parameters
+real(rkind),parameter            :: dx=1.e-10_rkind             ! finite difference increment (K)
+contains
+
+
+! **********************************************************************************************************
+! public subroutine ssdNrgFlux: compute energy fluxes and derivatives at layer interfaces
+! **********************************************************************************************************
+subroutine ssdNrgFlux(&
+                      ! input: model control
+                      scalarSolution,                     & ! intent(in):    flag to indicate the scalar solution
+                      deriv_desired,                & ! intent(in): flag indicating if derivatives are desired
+                      ! input: fluxes and derivatives at the upper boundary
+                      groundNetFlux,                      & ! intent(in):    total flux at the ground surface (W m-2)
+                      dGroundNetFlux_dGroundTemp,         & ! intent(in):    derivative in total ground surface flux w.r.t. ground temperature (W m-2 K-1)
+                      ! input: liquid water fluxes
+                      iLayerLiqFluxSnow,                  & ! intent(in):    liquid flux at the interface of each snow layer (m s-1)
+                      iLayerLiqFluxSoil,                  & ! intent(in):    liquid flux at the interface of each soil layer (m s-1)
+                      ! input: trial value of model state variables
+                      mLayerTempTrial,                    & ! intent(in):    trial temperature at the current iteration (K)
+                      mLayerMatricHeadTrial,              & ! intent(in):    trial matric head at the current iteration(m)
+                      mLayerVolFracLiqTrial,              & ! intent(in):    trial volumetric fraction of liquid water at the current iteration(-)
+                      mLayerVolFracIceTrial,              & ! intent(in):    trial volumetric fraction of ice water at the current iteration(-)
+                      ! input: pre-computed derivatives
+                      mLayerdTheta_dTk,                   & ! intent(in):    derivative in volumetric liquid water content w.r.t. temperature (K-1)
+                      mLayerFracLiqSnow,                  & ! intent(in):    fraction of liquid water (-)
+                      ! input-output: data structures
+                      mpar_data,                          & ! intent(in):    model parameters
+                      indx_data,                          & ! intent(in):    model indices
+                      prog_data,                          & ! intent(in):    model prognostic variables for a local HRU
+                      diag_data,                          & ! intent(inout):    model diagnostic variables for a local HRU
+                      flux_data,                          & ! intent(inout): model fluxes for a local HRU
+                      ! output: fluxes and derivatives at all layer interfaces
+                      iLayerNrgFlux,                      & ! intent(out):   energy flux at the layer interfaces (W m-2)
+                      dFlux_dTempAbove,                   & ! intent(out):   derivatives in the flux w.r.t. temperature in the layer above (W m-2 K-1)
+                      dFlux_dTempBelow,                   & ! intent(out):   derivatives in the flux w.r.t. temperature in the layer below (W m-2 K-1)
+                      dFlux_dWatAbove,                    & ! intent(out):   derivatives in the flux w.r.t. water state in the layer above (W m-2 K-1)
+                      dFlux_dWatBelow,                    & ! intent(out):   derivatives in the flux w.r.t. water state in the layer below (W m-2 K-1)
+                    ! output: error control
+                      err,message)                          ! intent(out): error control
+  ! utility modules
+  USE soil_utils_module,only:volFracLiq     ! compute volumetric fraction of liquid water
+  USE soil_utils_module,only:matricHead     ! compute the matric head based on volumetric water content
+  USE soil_utils_module,only:crit_soilT     ! compute critical temperature below which ice exists
+  USE snow_utils_module,only:fracliquid     ! compute fraction of liquid water at a given temperature
+  USE soil_utils_module,only:dTheta_dPsi    ! compute derivative of the soil moisture characteristic w.r.t. psi (m-1)
+  USE soil_utils_module,only:dPsi_dTheta    ! compute derivative of the soil moisture characteristic w.r.t. theta (m)
+
+  ! constants
+  USE multiconst, only: gravity, &                          ! gravitational acceleration (m s-1)
+                        Tfreeze, &                          ! freezing point of water (K)
+                        iden_water,iden_ice,&      ! intrinsic density of water and ice (kg m-3)
+                        LH_fus                              ! latent heat of fusion (J kg-1)
+  ! -------------------------------------------------------------------------------------------------------------------------------------------------
+  implicit none
+  ! input: model control
+  logical(lgt),intent(in)            :: scalarSolution              ! flag to denote if implementing the scalar solution
+  logical(lgt),intent(in)            :: deriv_desired               ! flag indicating if derivatives are desired
+  ! input: fluxes and derivatives at the upper boundary
+  real(rkind),intent(in)             :: groundNetFlux               ! net energy flux for the ground surface (W m-2)
+  real(rkind),intent(inout)          :: dGroundNetFlux_dGroundTemp  ! derivative in net ground flux w.r.t. ground temperature (W m-2 K-1)
+  ! input: liquid water fluxes
+  real(rkind),intent(in)             :: iLayerLiqFluxSnow(0:)       ! liquid flux at the interface of each snow layer (m s-1)
+  real(rkind),intent(in)             :: iLayerLiqFluxSoil(0:)       ! liquid flux at the interface of each soil layer (m s-1)
+  ! input: trial model state variables
+  real(rkind),intent(in)              :: mLayerTempTrial(:)         ! temperature in each layer at the current iteration (m)
+  real(rkind),intent(in)              :: mLayerMatricHeadTrial(:)   ! matric head in each layer at the current iteration (m)
+  real(rkind),intent(in)              :: mLayerVolFracLiqTrial(:)   ! volumetric fraction of liquid at the current iteration (-)
+  real(rkind),intent(in)              :: mLayerVolFracIceTrial(:)   ! volumetric fraction of ice at the current iteration (-)
+  ! input: pre-computed derivatives
+  real(rkind),intent(in)              :: mLayerdTheta_dTk(:)        ! derivative in volumetric liquid water content w.r.t. temperature (K-1)
+  real(rkind),intent(in)              :: mLayerFracLiqSnow(:)       ! fraction of liquid water (-)
+  ! input-output: data structures
+  type(var_dlength),intent(in)        :: mpar_data                  ! model parameters
+  type(var_ilength),intent(in)        :: indx_data                  ! state vector geometry
+  type(var_dlength),intent(in)        :: prog_data                  ! prognostic variables for a local HRU
+  type(var_dlength),intent(inout)        :: diag_data                  ! diagnostic variables for a local HRU
+  type(var_dlength),intent(inout)     :: flux_data                  ! model fluxes for a local HRU
+  ! output: fluxes and derivatives at all layer interfaces
+  real(rkind),intent(out)             :: iLayerNrgFlux(0:)          ! energy flux at the layer interfaces (W m-2)
+  real(rkind),intent(out)             :: dFlux_dTempAbove(0:)       ! derivatives in the flux w.r.t. temperature in the layer above (J m-2 s-1 K-1)
+  real(rkind),intent(out)             :: dFlux_dTempBelow(0:)       ! derivatives in the flux w.r.t. temperature in the layer below (J m-2 s-1 K-1)
+  real(rkind),intent(out)             :: dFlux_dWatAbove(0:)        ! derivatives in the flux w.r.t. water state in the layer above (J m-2 s-1 K-1)
+  real(rkind),intent(out)             :: dFlux_dWatBelow(0:)        ! derivatives in the flux w.r.t. water state in the layer below (J m-2 s-1 K-1)
+  ! output: error control
+  integer(i4b),intent(out)            :: err                        ! error code
+  character(*),intent(out)            :: message                    ! error message
+  ! ------------------------------------------------------------------------------------------------------------------------------------------------------
+  ! local variables
+  character(LEN=256)               :: cmessage                     ! error message of downwind routine
+  integer(i4b)                     :: i,j,iLayer                   ! index of model layers
+  integer(i4b)                     :: ixLayerDesired(1)            ! layer desired (scalar solution)
+  integer(i4b)                     :: ixTop                        ! top layer in subroutine call
+  integer(i4b)                     :: ixBot                        ! bottom layer in subroutine call
+  real(rkind)                      :: qFlux                        ! liquid flux at layer interfaces (m s-1)
+  real(rkind)                      :: dz                           ! height difference (m)
+  ! additional variables to compute numerical derivatives
+  integer(i4b)                     :: nFlux                        ! number of flux calculations required (>1 = numerical derivatives with one-sided finite differences)
+  integer(i4b)                     :: itry                         ! index of different flux calculations
+  integer(i4b),parameter           :: unperturbed=0                ! named variable to identify the case of unperturbed state variables
+  integer(i4b),parameter           :: perturbState=1               ! named variable to identify the case where we perturb the state in the current layer
+  integer(i4b),parameter           :: perturbStateTempAbove=2      ! named variable to identify the case where we perturb the state layer above
+  integer(i4b),parameter           :: perturbStateTempBelow=3      ! named variable to identify the case where we perturb the state layer below
+  integer(i4b),parameter           :: perturbStateWatAbove=4       ! named variable to identify the case where we perturb the state layer above
+  integer(i4b),parameter           :: perturbStateWatBelow=5       ! named variable to identify the case where we perturb the state layer below
+  integer(i4b)                     :: ixPerturb                    ! index of element in 2-element vector to perturb
+  integer(i4b)                     :: ixOriginal                   ! index of perturbed element in the original vector
+  real(rkind)                      :: scalarThermCFlux               ! thermal conductivity (W m-1 K-1)
+  real(rkind)                      :: scalarThermCFlux_dTempAbove    ! thermal conductivity with perturbation to the temperature state above (W m-1 K-1)
+  real(rkind)                      :: scalarThermCFlux_dTempBelow    ! thermal conductivity with perturbation to the temperature state below (W m-1 K-1)
+  real(rkind)                      :: scalarThermCFlux_dWatAbove     ! thermal conductivity with perturbation to the water state above
+  real(rkind)                      :: scalarThermCFlux_dWatBelow     ! thermal conductivity with perturbation to the water state below
+  real(rkind)                      :: flux0,flux1,flux2            ! fluxes used to calculate derivatives (W m-2)
+  ! compute fluxes and derivatives at layer interfaces
+  integer(i4b),dimension(2)        :: mLayer_ind                   ! indices of above and below layers
+  integer(i4b),dimension(2)        :: iLayer_ind                   ! indices of above and below interfaces
+  real(rkind)                      :: matricFHead                  ! matric head for frozen soil
+  real(rkind)                      :: Tcrit                        ! temperature where all water is unfrozen (K)
+  real(rkind)                      :: fLiq                         ! fraction of liquid water (-)
+  real(rkind),dimension(2)         :: vectorMatricHeadTrial        ! trial value of matric head (m)
+  real(rkind),dimension(2)         :: vectorVolFracLiqTrial        ! trial value of volumetric liquid content (-)
+  real(rkind),dimension(2)         :: vectorVolFracIceTrial        ! trial value of volumetric ice content (-)
+  real(rkind),dimension(2)         :: vectorTempTrial              ! trial value of temperature (K)
+  real(rkind),dimension(2)         :: vectordTheta_dPsi            ! derivative in the soil water characteristic w.r.t. psi (m-1)
+  real(rkind),dimension(2)         :: vectordPsi_dTheta            ! derivative in the soil water characteristic w.r.t. theta (m)
+  real(rkind),dimension(2)         :: vectorFracLiqSnow            ! fraction of liquid water (-)
+  real(rkind),dimension(2)         :: vectortheta_sat              ! layer above and below soil porosity (-)
+  real(rkind),dimension(2)         :: vectoriden_soil              ! layer above and below density of soil (kg m-3)
+  real(rkind),dimension(2)         :: vectorthCond_soil            ! layer above and below thermal conductivity of soil (W m-1 K-1)
+  real(rkind),dimension(2)         :: vectorfrac_sand              ! layer above and below fraction of sand (-)
+  real(rkind),dimension(2)         :: vectorfrac_clay              ! layer above and below fraction of clay (-)
+  ! recompute the perturbed version of iLayerThermalC, this could be the only version and remove the omputThermConduct_module
+  real(rkind)                      :: dThermalC_dHydStateAbove     ! derivative in the thermal conductivity w.r.t. water state in the layer above
+  real(rkind)                      :: dThermalC_dHydStateBelow     ! derivative in the thermal conductivity w.r.t. water state in the layer above
+  real(rkind)                      :: dThermalC_dNrgStateAbove     ! derivative in the thermal conductivity w.r.t. energy state in the layer above
+  real(rkind)                      :: dThermalC_dNrgStateBelow     ! derivative in the thermal conductivity w.r.t. energy state in the layer above
+  ! ------------------------------------------------------------------------------------------------------------------------------------------------------
+  ! make association of local variables with information in the data structures
+  associate(&
+    ixDerivMethod           => model_decisions(iLookDECISIONS%fDerivMeth)%iDecision,      & ! intent(in): method used to calculate flux derivatives
+    ix_bcUpprTdyn           => model_decisions(iLookDECISIONS%bcUpprTdyn)%iDecision,      & ! intent(in): method used to calculate the upper boundary condition for thermodynamics
+    ix_bcLowrTdyn           => model_decisions(iLookDECISIONS%bcLowrTdyn)%iDecision,      & ! intent(in): method used to calculate the lower boundary condition for thermodynamics
+    ixRichards                 => model_decisions(iLookDECISIONS%f_Richards)%iDecision,   & ! intent(in): index of the form of Richards' equation
+    ixThCondSnow            => model_decisions(iLookDECISIONS%thCondSnow)%iDecision,      & ! intent(in): choice of method for thermal conductivity of snow
+    ixThCondSoil            => model_decisions(iLookDECISIONS%thCondSoil)%iDecision,      & ! intent(in): choice of method for thermal conductivity of soil
+    ! input: model coordinates
+    nSnow                   => indx_data%var(iLookINDEX%nSnow)%dat(1),               & ! intent(in): number of snow layers
+    nLayers                 => indx_data%var(iLookINDEX%nLayers)%dat(1),             & ! intent(in): total number of layers
+    layerType               => indx_data%var(iLookINDEX%layerType)%dat,              & ! intent(in): layer type (iname_soil or iname_snow)
+    ixLayerState            => indx_data%var(iLookINDEX%ixLayerState)%dat,           & ! intent(in): list of indices for all model layers
+    ixSnowSoilNrg           => indx_data%var(iLookINDEX%ixSnowSoilNrg)%dat,          & ! intent(in): index in the state subset for energy state variables in the snow+soil domain
+    ! input: thermal properties
+    mLayerDepth             => prog_data%var(iLookPROG%mLayerDepth)%dat,             & ! intent(in): depth of each layer (m)
+    mLayerHeight            => prog_data%var(iLookPROG%mLayerHeight)%dat,            & ! intent(in): height at the mid-point of each layer (m)
+    upperBoundTemp          => mpar_data%var(iLookPARAM%upperBoundTemp)%dat(1),      & ! intent(in): temperature of the upper boundary (K)
+    lowerBoundTemp          => mpar_data%var(iLookPARAM%lowerBoundTemp)%dat(1),      & ! intent(in): temperature of the lower boundary (K)
+    iLayerHeight            => prog_data%var(iLookPROG%iLayerHeight)%dat,            & ! intent(in): height at the interface of each layer (m)
+    fixedThermalCond_snow   => mpar_data%var(iLookPARAM%fixedThermalCond_snow)%dat(1),    & ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
+    iLayerThermalC          => diag_data%var(iLookDIAG%iLayerThermalC)%dat,          & ! intent(inout): thermal conductivity at the interface of each layer (W m-1 K-1)
+    ! input: depth varying soil parameters
+    iden_soil               => mpar_data%var(iLookPARAM%soil_dens_intr)%dat,              & ! intent(in): intrinsic density of soil (kg m-3)
+    thCond_soil             => mpar_data%var(iLookPARAM%thCond_soil)%dat,                 & ! intent(in): thermal conductivity of soil (W m-1 K-1)
+    theta_sat               => mpar_data%var(iLookPARAM%theta_sat)%dat,                   & ! intent(in): soil porosity (-)
+    frac_sand               => mpar_data%var(iLookPARAM%frac_sand)%dat,                   & ! intent(in): fraction of sand (-)
+    frac_clay               => mpar_data%var(iLookPARAM%frac_clay)%dat,                   & ! intent(in): fraction of clay (-)
+    vGn_m                   => diag_data%var(iLookDIAG%scalarVGn_m)%dat,                  & ! intent(in):  [dp(:)] van Genutchen "m" parameter (-)
+    vGn_n                   => mpar_data%var(iLookPARAM%vGn_n)%dat,                       & ! intent(in):  [dp(:)] van Genutchen "n" parameter (-)
+    vGn_alpha               => mpar_data%var(iLookPARAM%vGn_alpha)%dat,                   & ! intent(in):  [dp(:)] van Genutchen "alpha" parameter (m-1)
+    theta_res               => mpar_data%var(iLookPARAM%theta_res)%dat,                   & ! intent(in):  [dp(:)] soil residual volumetric water content (-)
+    ! input: snow parameters
+    snowfrz_scale           => mpar_data%var(iLookPARAM%snowfrz_scale)%dat(1),            & ! intent(in):  [dp] scaling parameter for the snow freezing curve (K-1)
+    ! output: diagnostic fluxes
+    iLayerConductiveFlux => flux_data%var(iLookFLUX%iLayerConductiveFlux)%dat,    & ! intent(out): conductive energy flux at layer interfaces at end of time step (W m-2)
+    iLayerAdvectiveFlux  => flux_data%var(iLookFLUX%iLayerAdvectiveFlux)%dat      & ! intent(out): advective energy flux at layer interfaces at end of time step (W m-2)
+    )  ! association of local variables with information in the data structures
+    ! ------------------------------------------------------------------------------------------------------------------------------------------------------
+    ! initialize error control
+    err=0; message='ssdNrgFlux/'
+
+    ! set conductive and advective fluxes to missing in the upper boundary
+    ! NOTE: advective flux at the upper boundary is included in the ground heat flux
+    iLayerConductiveFlux(0) = realMissing
+    iLayerAdvectiveFlux(0)  = realMissing
+
+    ! check the need to compute numerical derivatives
+    if(ixDerivMethod==numerical)then
       nFlux=5  ! compute the derivatives and cross derivates using one-sided finite differences
-     else
+    else
       nFlux=0  ! compute analytical derivatives
-     end if
-    
-     ! get the indices for the snow+soil layers
-     if(scalarSolution)then
+    end if
+
+    ! get the indices for the snow+soil layers
+    if(scalarSolution)then
       ixLayerDesired = pack(ixLayerState, ixSnowSoilNrg/=integerMissing)
       ixTop = ixLayerDesired(1)
       ixBot = ixLayerDesired(1)
-     else
+    else
       ixTop = 0 !include layer 0 in layer interface derivatives
       ixBot = nLayers
-     endif
-    
-     ! -------------------------------------------------------------------------------------------------------------------
-     ! ***** compute the derivative in fluxes at layer interfaces w.r.t state in the layer above and the layer below *****
-     ! -------------------------------------------------------------------------------------------------------------------
-    
-     ! initialize un-used elements
-     ! ***** the upper boundary
-     dFlux_dTempAbove(0) = 0._rkind ! this will be in canopy
-     dFlux_dWatAbove(0) = 0._rkind ! this will be in canopy
-    
-     ! ***** the lower boundary
-     dFlux_dTempBelow(nLayers) = -huge(lowerBoundTemp)  ! don't expect this to be used, so deliberately set to a ridiculous value to cause problems
-     dFlux_dWatBelow(nLayers) = -huge(lowerBoundTemp)  ! don't expect this to be used, so deliberately set to a ridiculous value to cause problems
-    
-     ! loop through INTERFACES...
-     do iLayer=ixTop,ixBot
-    
+    endif
+
+    ! -------------------------------------------------------------------------------------------------------------------
+    ! ***** compute the derivative in fluxes at layer interfaces w.r.t state in the layer above and the layer below *****
+    ! -------------------------------------------------------------------------------------------------------------------
+
+    ! initialize un-used elements
+    ! ***** the upper boundary
+    dFlux_dTempAbove(0) = 0._rkind ! this will be in canopy
+    dFlux_dWatAbove(0) = 0._rkind ! this will be in canopy
+
+    ! ***** the lower boundary
+    dFlux_dTempBelow(nLayers) = -huge(lowerBoundTemp)  ! don't expect this to be used, so deliberately set to a ridiculous value to cause problems
+    dFlux_dWatBelow(nLayers) = -huge(lowerBoundTemp)  ! don't expect this to be used, so deliberately set to a ridiculous value to cause problems
+
+      ! loop through INTERFACES...
+    do iLayer=ixTop,ixBot
+
       ! either one or multiple flux calls, depending on if using analytical or numerical derivatives
       do itry=nFlux,0,-1  ! (work backwards to ensure all computed fluxes come from the un-perturbed case)
-    
-       ! =====
-       ! determine layer to perturb
-       ! ==========================
-       select case(itry)
-        ! skip undesired perturbations
-        case(perturbState); cycle       ! perturbing the layers above and below the flux at the interface
-        ! identify the index for the perturbation
-        case(unperturbed);       ixPerturb = 0
-        case(perturbStateTempAbove)
-         if(iLayer==0) cycle ! cannot perturb state above (does not exist) -- so keep cycling
-         ixPerturb = 1
-        case(perturbStateTempBelow)
-         if(iLayer==nLayers) cycle  ! cannot perturb state below (does not exist) -- so keep cycling
-         ixPerturb = 2
-        case(perturbStateWatAbove)
-         if(iLayer==0) cycle ! cannot perturb state above (does not exist) -- so keep cycling
-         ixPerturb = 3
-        case(perturbStateWatBelow)
-         if(iLayer==nLayers) cycle  ! cannot perturb state below (does not exist) -- so keep cycling
-         ixPerturb = 4
-        case default; err=10; message=trim(message)//"unknown perturbation"; return
-       end select ! (identifying layer to of perturbation)
-       ! determine the index in the original vector
-       ixOriginal = iLayer + (ixPerturb-1)
-    
-       ! =====
-       ! set indices and parameters needed for layer perturbation
-       ! ========================================================
-       mLayer_ind(1) = iLayer
-       mLayer_ind(2) = iLayer+1
-       if (iLayer==0 ) mLayer_ind(1) = 1
-       if (iLayer==nLayers ) mLayer_ind(2) = nLayers
-       ! indices of interface are different at top layer since interface 0 exists
-       iLayer_ind = mLayer_ind
-       if (iLayer==0 ) iLayer_ind(1) = 0
-    
-       ! =====
-       ! get input state variables...
-       ! ============================
-       ! start with the un-perturbed case
-       vectorVolFracLiqTrial(1:2) = mLayerVolFracLiqTrial(mLayer_ind)
-       vectorMatricHeadTrial(1:2) = mLayerMatricHeadTrial(mLayer_ind-nSnow)
-       vectorTempTrial(1:2) = mLayerTempTrial(mLayer_ind)
-       vectorVolFracIceTrial(1:2) = mLayerVolFracIceTrial(mLayer_ind)
-       ! make appropriate perturbations,
-       if(ixPerturb > 2)then
-        vectorMatricHeadTrial(ixPerturb-2) = vectorMatricHeadTrial(ixPerturb-2) + dx
-        vectorVolFracLiqTrial(ixPerturb-2) = vectorVolFracLiqTrial(ixPerturb-2) + dx
-       else if(ixPerturb > 0)then
-        vectorTempTrial(ixPerturb) = vectorTempTrial(ixPerturb) + dx
-       endif
-    
-       ! *****
-       ! * compute the volumetric fraction of liquid, ice, and air in each layer in response to perturbation ...
-       ! *******************************************************************************************************
-    
-       do i = 1,2 !(layer above and below)
-        select case(layerType(mLayer_ind(i))) !(snow or soil)
-    
-         case(iname_soil)
-          j = mLayer_ind(i)-nSnow !soil layer
-          if(ixPerturb > 0)then ! only recompute these if perturbed
-           select case(ixRichards)  ! (form of Richards' equation)
-            case(moisture) !
-             vectorMatricHeadTrial(i) = matricHead(vectorVolFracLiqTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
-             Tcrit = crit_soilT(vectorMatricHeadTrial(i))
-             !if change temp and below critical, it changes the state variable, seems like a problem FIX
-             if(vectorTempTrial(i) < Tcrit) then !if do not perturb temperature, this should not change
-              matricFHead = (LH_fus/gravity)*(vectorTempTrial(i) - Tfreeze)/Tfreeze
-              vectorVolFracLiqTrial(i) = volFracLiq(matricFHead,vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
-             endif
-            case(mixdform)
-             Tcrit = crit_soilT(vectorMatricHeadTrial(i))
-             if(vectorTempTrial(i) < Tcrit) then !if do not perturb temperature, this should not change, but matricHeadTrial will have changed
-              matricFHead = (LH_fus/gravity)*(vectorTempTrial(i) - Tfreeze)/Tfreeze
-              vectorVolFracLiqTrial(i) = volFracLiq(matricFHead,vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
-             else
-              vectorVolFracLiqTrial(i) = volFracLiq(vectorMatricHeadTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
-             endif
-           end select ! (form of Richards' equation)
-           vectorVolFracIceTrial(i) = volFracLiq(vectorMatricHeadTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j)) - vectorVolFracLiqTrial(i)
-          endif ! (recompute if perturbed)
-          ! derivatives, these need to be computed because they are computed only in soilLiqFlx which is called after this
-          vectordPsi_dTheta(i) = dPsi_dTheta(vectorVolFracLiqTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
-          vectordTheta_dPsi(i) = dTheta_dPsi(vectorMatricHeadTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
-          vectorFracLiqSnow(i) = realMissing
-          ! soil parameters
-          vectortheta_sat(i) = theta_sat(j)
-          vectoriden_soil(i) = iden_soil(j)
-          vectorthCond_soil(i) = thCond_soil(j)
-          vectorfrac_sand(i) = frac_sand(j)
-          vectorfrac_clay(i) = frac_clay(j)
-    
-         case(iname_snow)
-          fLiq = fracliquid(vectorTempTrial(i),snowfrz_scale) ! fraction of liquid water
-          if(ixPerturb > 0) vectorVolFracIceTrial(i) = ( vectorVolFracLiqTrial(i) / fLiq - vectorVolFracLiqTrial(i) )*(iden_water/iden_ice) ! use perturbed nodeVolTotWatTrial
-          ! derivatives
-          vectordPsi_dTheta(i) = realMissing
-          vectordTheta_dPsi(i) = realMissing
-          vectorFracLiqSnow(i) = mLayerFracLiqSnow(mLayer_ind(i))
-          ! soil parameters do not exist
-          vectortheta_sat(i) = realMissing
-          vectoriden_soil(i) = realMissing
-          vectorthCond_soil(i) = realMissing
-          vectorfrac_sand(i) = realMissing
-          vectorfrac_clay(i) = realMissing
-    
-         case default; err=20; message=trim(message)//'unable to identify type of layer (snow or soil) to compute volumetric fraction of air'; return
-    
-        end select !(snow or soil)
-       enddo !(layer above and below)
-    
-       ! =====
-       ! get thermal conductivity at layer interface and its derivative w.r.t. the state above and the state below...
-       ! ============================================================================================================
-       call iLayerThermalConduct(&
-                           ! input: model control
-                           deriv_desired,             & ! intent(in): flag indicating if derivatives are desired
-                           ixRichards,                         & ! intent(in): index defining the form of Richards' equation (moisture or mixdform)
-                           ixThCondSnow,                        & ! intent(in): choice of method for thermal conductivity of snow
-                           ixThCondSoil,                        & ! intent(in): choice of method for thermal conductivity of soil
-                           ! input: coordinate variables
-                           nLayers,                             & ! intent(in): number of layers
-                           iLayer,                              & ! intent(in): layer index for output
-                           layerType(mLayer_ind),               & ! intent(in): layer type (iname_soil or iname_snow)
-                           ! input: state variables (adjacent layers)
-                           vectorMatricHeadTrial,               & ! intent(in): matric head at the nodes (m)
-                           vectorVolFracLiqTrial,               & ! intent(in): volumetric liquid water at the nodes (m)
-                           vectorVolFracIceTrial,               & ! intent(in): volumetric ice at the nodes (m)
-                           vectorTempTrial,                     & ! intent(in): temperature at the nodes (m)
-                           ! input: pre-computed derivatives
-                           mLayerdTheta_dTk(mLayer_ind),        & ! intent(in): derivative in volumetric liquid water content w.r.t. temperature (K-1)
-                           vectorFracLiqSnow,                   & ! intent(in): fraction of liquid water (-)
-                           vectordTheta_dPsi,                   & ! intent(in): derivative in the soil water characteristic w.r.t. psi (m-1)
-                           vectordPsi_dTheta,                   & ! intent(in): derivative in the soil water characteristic w.r.t. theta (m)
-                           ! input: model coordinate variables (adjacent layers)
-                           mLayerHeight(mLayer_ind),            & ! intent(in): height at the mid-point of the node (m)
-                           iLayerHeight(iLayer_ind),            & ! intent(in): height at the interface of the nodes (m)
-                           ! input: soil parameters
-                           vectortheta_sat,                     & ! intent(in): soil porosity (-)
-                           vectoriden_soil,                     & ! intent(in): intrinsic density of soil (kg m-3)
-                           vectorthCond_soil,                   & ! intent(in): thermal conductivity of soil (W m-1 K-1)
-                           vectorfrac_sand,                     & ! intent(in): fraction of sand (-)
-                           vectorfrac_clay,                     & ! intent(in): fraction of clay (-)
-                           ! input: snow parameters
-                           fixedThermalCond_snow,               & ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
-                           ! output: conductivity at the layer interface (scalars)
-                           iLayerThermalC(iLayer),       & ! intent(inout): thermal conductivity at the interface of each layer (W m-1 K-1)
-                           ! output: derivatives in thermal conductivity w.r.t. state variables -- matric head or volumetric lquid water -- in the layer above and layer below
-                           dThermalC_dHydStateAbove,    & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
-                           dThermalC_dHydStateBelow,    & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
-                           ! output: derivatives in thermal conductivity w.r.t. energy state variables -- now just temperature -- in the layer above and layer below (W m-1 K-2)
-                           dThermalC_dNrgStateAbove,    & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
-                           dThermalC_dNrgStateBelow,    & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
-                           ! output: error control
-                           err,cmessage)               ! intent(out): error control
-    
-       if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
-    
-       ! compute total vertical flux, to compute derivatives
-       if(deriv_desired .and. ixDerivMethod==numerical)then
+
+          ! =====
+          ! determine layer to perturb
+          ! ==========================
         select case(itry)
-         case(unperturbed);           scalarThermCFlux            = iLayerThermalC(iLayer)
-         case(perturbStateTempAbove); scalarThermCFlux_dTempAbove = iLayerThermalC(iLayer)
-         case(perturbStateTempBelow); scalarThermCFlux_dTempBelow = iLayerThermalC(iLayer)
-         case(perturbStateWatAbove);  scalarThermCFlux_dWatAbove  = iLayerThermalC(iLayer)
-         case(perturbStateWatBelow);  scalarThermCFlux_dWatBelow  = iLayerThermalC(iLayer)
-         case default; err=10; message=trim(message)//"unknown perturbation"; return
-        end select
-       end if
-    
+          ! skip undesired perturbations
+          case(perturbState); cycle       ! perturbing the layers above and below the flux at the interface
+          ! identify the index for the perturbation
+          case(unperturbed);       ixPerturb = 0
+          case(perturbStateTempAbove)
+            if(iLayer==0) cycle ! cannot perturb state above (does not exist) -- so keep cycling
+            ixPerturb = 1
+          case(perturbStateTempBelow)
+            if(iLayer==nLayers) cycle  ! cannot perturb state below (does not exist) -- so keep cycling
+            ixPerturb = 2
+          case(perturbStateWatAbove)
+            if(iLayer==0) cycle ! cannot perturb state above (does not exist) -- so keep cycling
+            ixPerturb = 3
+          case(perturbStateWatBelow)
+            if(iLayer==nLayers) cycle  ! cannot perturb state below (does not exist) -- so keep cycling
+            ixPerturb = 4
+          case default; err=10; message=trim(message)//"unknown perturbation"; return
+        end select ! (identifying layer to of perturbation)
+        ! determine the index in the original vector
+        ixOriginal = iLayer + (ixPerturb-1)
+
+        ! =====
+        ! set indices and parameters needed for layer perturbation
+        ! ========================================================
+        mLayer_ind(1) = iLayer
+        mLayer_ind(2) = iLayer+1
+        if (iLayer==0 ) mLayer_ind(1) = 1
+        if (iLayer==nLayers ) mLayer_ind(2) = nLayers
+        ! indices of interface are different at top layer since interface 0 exists
+        iLayer_ind = mLayer_ind
+        if (iLayer==0 ) iLayer_ind(1) = 0
+
+        ! =====
+        ! get input state variables...
+        ! ============================
+        ! start with the un-perturbed case
+        vectorVolFracLiqTrial(1:2) = mLayerVolFracLiqTrial(mLayer_ind)
+        ! need to protect against negative indexes
+        if ( mLayer_ind(1) .ge. nSnow .and. mLayer_ind(2) .ge. nSnow)then
+          if (iLayer==nSnow ) mLayer_ind(1) = nsnow+1
+          vectorMatricHeadTrial(1:2) = mLayerMatricHeadTrial(mLayer_ind-nSnow)
+        end if
+        vectorTempTrial(1:2) = mLayerTempTrial(mLayer_ind)
+        vectorVolFracIceTrial(1:2) = mLayerVolFracIceTrial(mLayer_ind)
+        ! make appropriate perturbations,
+        if(ixPerturb > 2)then
+          vectorMatricHeadTrial(ixPerturb-2) = vectorMatricHeadTrial(ixPerturb-2) + dx
+          vectorVolFracLiqTrial(ixPerturb-2) = vectorVolFracLiqTrial(ixPerturb-2) + dx
+        else if(ixPerturb > 0)then
+          vectorTempTrial(ixPerturb) = vectorTempTrial(ixPerturb) + dx
+        endif
+
+        ! *****
+        ! * compute the volumetric fraction of liquid, ice, and air in each layer in response to perturbation ...
+        ! *******************************************************************************************************
+
+        do i = 1,2 !(layer above and below)
+          select case(layerType(mLayer_ind(i))) !(snow or soil)
+
+            case(iname_soil)
+              j = mLayer_ind(i)-nSnow !soil layer
+              if(ixPerturb > 0)then ! only recompute these if perturbed
+                select case(ixRichards)  ! (form of Richards' equation)
+                  case(moisture) !
+                    vectorMatricHeadTrial(i) = matricHead(vectorVolFracLiqTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
+                    Tcrit = crit_soilT(vectorMatricHeadTrial(i))
+                    !if change temp and below critical, it changes the state variable, seems like a problem FIX
+                    if(vectorTempTrial(i) < Tcrit) then !if do not perturb temperature, this should not change
+                      matricFHead = (LH_fus/gravity)*(vectorTempTrial(i) - Tfreeze)/Tfreeze
+                      vectorVolFracLiqTrial(i) = volFracLiq(matricFHead,vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
+                    endif
+                  case(mixdform)
+                    Tcrit = crit_soilT(vectorMatricHeadTrial(i))
+                    if(vectorTempTrial(i) < Tcrit) then !if do not perturb temperature, this should not change, but matricHeadTrial will have changed
+                      matricFHead = (LH_fus/gravity)*(vectorTempTrial(i) - Tfreeze)/Tfreeze
+                      vectorVolFracLiqTrial(i) = volFracLiq(matricFHead,vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
+                    else
+                      vectorVolFracLiqTrial(i) = volFracLiq(vectorMatricHeadTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
+                    endif
+                end select ! (form of Richards' equation)
+                vectorVolFracIceTrial(i) = volFracLiq(vectorMatricHeadTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j)) - vectorVolFracLiqTrial(i)
+              endif ! (recompute if perturbed)
+              ! derivatives, these need to be computed because they are computed only in soilLiqFlx which is called after this
+              vectordPsi_dTheta(i) = dPsi_dTheta(vectorVolFracLiqTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
+              vectordTheta_dPsi(i) = dTheta_dPsi(vectorMatricHeadTrial(i),vGn_alpha(j),theta_res(j),theta_sat(j),vGn_n(j),vGn_m(j))
+              vectorFracLiqSnow(i) = realMissing
+              ! soil parameters
+              vectortheta_sat(i) = theta_sat(j)
+              vectoriden_soil(i) = iden_soil(j)
+              vectorthCond_soil(i) = thCond_soil(j)
+              vectorfrac_sand(i) = frac_sand(j)
+              vectorfrac_clay(i) = frac_clay(j)
+
+            case(iname_snow)
+              fLiq = fracliquid(vectorTempTrial(i),snowfrz_scale) ! fraction of liquid water
+              if(ixPerturb > 0) vectorVolFracIceTrial(i) = ( vectorVolFracLiqTrial(i) / fLiq - vectorVolFracLiqTrial(i) )*(iden_water/iden_ice) ! use perturbed nodeVolTotWatTrial
+              ! derivatives
+              vectordPsi_dTheta(i) = realMissing
+              vectordTheta_dPsi(i) = realMissing
+              vectorFracLiqSnow(i) = mLayerFracLiqSnow(mLayer_ind(i))
+              ! soil parameters do not exist
+              vectortheta_sat(i) = realMissing
+              vectoriden_soil(i) = realMissing
+              vectorthCond_soil(i) = realMissing
+              vectorfrac_sand(i) = realMissing
+              vectorfrac_clay(i) = realMissing
+
+            case default; err=20; message=trim(message)//'unable to identify type of layer (snow or soil) to compute volumetric fraction of air'; return
+
+          end select !(snow or soil)
+        enddo !(layer above and below)
+
+        ! =====
+        ! get thermal conductivity at layer interface and its derivative w.r.t. the state above and the state below...
+        ! ============================================================================================================
+        call iLayerThermalConduct(&
+                            ! input: model control
+                            deriv_desired,             & ! intent(in): flag indicating if derivatives are desired
+                            ixRichards,                         & ! intent(in): index defining the form of Richards' equation (moisture or mixdform)
+                            ixThCondSnow,                        & ! intent(in): choice of method for thermal conductivity of snow
+                            ixThCondSoil,                        & ! intent(in): choice of method for thermal conductivity of soil
+                            ! input: coordinate variables
+                            nLayers,                             & ! intent(in): number of layers
+                            iLayer,                              & ! intent(in): layer index for output
+                            layerType(mLayer_ind),               & ! intent(in): layer type (iname_soil or iname_snow)
+                            ! input: state variables (adjacent layers)
+                            vectorMatricHeadTrial,               & ! intent(in): matric head at the nodes (m)
+                            vectorVolFracLiqTrial,               & ! intent(in): volumetric liquid water at the nodes (m)
+                            vectorVolFracIceTrial,               & ! intent(in): volumetric ice at the nodes (m)
+                            vectorTempTrial,                     & ! intent(in): temperature at the nodes (m)
+                            ! input: pre-computed derivatives
+                            mLayerdTheta_dTk(mLayer_ind),        & ! intent(in): derivative in volumetric liquid water content w.r.t. temperature (K-1)
+                            vectorFracLiqSnow,                   & ! intent(in): fraction of liquid water (-)
+                            vectordTheta_dPsi,                   & ! intent(in): derivative in the soil water characteristic w.r.t. psi (m-1)
+                            vectordPsi_dTheta,                   & ! intent(in): derivative in the soil water characteristic w.r.t. theta (m)
+                            ! input: model coordinate variables (adjacent layers)
+                            mLayerHeight(mLayer_ind),            & ! intent(in): height at the mid-point of the node (m)
+                            iLayerHeight(iLayer_ind),            & ! intent(in): height at the interface of the nodes (m)
+                            ! input: soil parameters
+                            vectortheta_sat,                     & ! intent(in): soil porosity (-)
+                            vectoriden_soil,                     & ! intent(in): intrinsic density of soil (kg m-3)
+                            vectorthCond_soil,                   & ! intent(in): thermal conductivity of soil (W m-1 K-1)
+                            vectorfrac_sand,                     & ! intent(in): fraction of sand (-)
+                            vectorfrac_clay,                     & ! intent(in): fraction of clay (-)
+                            ! input: snow parameters
+                            fixedThermalCond_snow,               & ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
+                            ! output: conductivity at the layer interface (scalars)
+                            iLayerThermalC(iLayer),       & ! intent(inout): thermal conductivity at the interface of each layer (W m-1 K-1)
+                            ! output: derivatives in thermal conductivity w.r.t. state variables -- matric head or volumetric lquid water -- in the layer above and layer below
+                            dThermalC_dHydStateAbove,    & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
+                            dThermalC_dHydStateBelow,    & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
+                            ! output: derivatives in thermal conductivity w.r.t. energy state variables -- now just temperature -- in the layer above and layer below (W m-1 K-2)
+                            dThermalC_dNrgStateAbove,    & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
+                            dThermalC_dNrgStateBelow,    & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
+                            ! output: error control
+                            err,cmessage)               ! intent(out): error control
+
+        if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
+
+        ! compute total vertical flux, to compute derivatives
+        if(deriv_desired .and. ixDerivMethod==numerical)then
+          select case(itry)
+            case(unperturbed);           scalarThermCFlux            = iLayerThermalC(iLayer)
+            case(perturbStateTempAbove); scalarThermCFlux_dTempAbove = iLayerThermalC(iLayer)
+            case(perturbStateTempBelow); scalarThermCFlux_dTempBelow = iLayerThermalC(iLayer)
+            case(perturbStateWatAbove);  scalarThermCFlux_dWatAbove  = iLayerThermalC(iLayer)
+            case(perturbStateWatBelow);  scalarThermCFlux_dWatBelow  = iLayerThermalC(iLayer)
+            case default; err=10; message=trim(message)//"unknown perturbation"; return
+          end select
+        end if
+
       end do  ! (looping through different flux calculations -- one or multiple calls depending if desire for numerical or analytical derivatives)
-    
-    
+
+
       ! ***** the upper boundary
       if(iLayer==0)then  ! (upper boundary)
-    
-       ! identify the upper boundary condition
-       select case(ix_bcUpprTdyn)
-    
-        ! * prescribed temperature at the upper boundary
-        case(prescribedTemp)
-         dz = (mLayerHeight(iLayer+1) - mLayerHeight(iLayer))
-         if(ixDerivMethod==analytical)then    ! ** analytical derivatives
-          dFlux_dWatBelow(iLayer)  = -dThermalC_dHydStateBelow * ( mLayerTempTrial(iLayer+1) - upperBoundTemp )/dz
-          dFlux_dTempBelow(iLayer) = -dThermalC_dNrgStateBelow * ( mLayerTempTrial(iLayer+1) - upperBoundTemp )/dz - iLayerThermalC(iLayer)/dz
-         else                              ! ** numerical derivatives
-          flux0 = -scalarThermCFlux          *( mLayerTempTrial(iLayer+1) - upperBoundTemp ) / dz
-          flux2 = -scalarThermCFlux_dWatBelow*( mLayerTempTrial(iLayer+1) - upperBoundTemp ) / dz
-          dFlux_dWatBelow(iLayer) = (flux2 - flux0)/dx
-          flux0 = -scalarThermCFlux           *( mLayerTempTrial(iLayer+1)     - upperBoundTemp ) / dz
-          flux2 = -scalarThermCFlux_dTempBelow*((mLayerTempTrial(iLayer+1)+dx) - upperBoundTemp ) / dz
-          dFlux_dTempBelow(iLayer) = (flux2 - flux0)/dx
-         end if
-    
-         ! * zero flux at the upper boundary
-        case(zeroFlux)
-         dFlux_dWatBelow(iLayer) = 0._rkind
-         dFlux_dTempBelow(iLayer) = 0._rkind
-    
-         ! * compute flux inside vegetation energy flux routine, use here
-        case(energyFlux)
-         dFlux_dWatBelow(iLayer) = 0._rkind !dGroundNetFlux_dGroundWat, does not exist in vegNrgFlux
-         dFlux_dTempBelow(iLayer) = dGroundNetFlux_dGroundTemp
-    
-        case default; err=20; message=trim(message)//'unable to identify upper boundary condition for thermodynamics'; return
-    
-       end select  ! (identifying the upper boundary condition for thermodynamics)
-       !dGroundNetFlux_dGroundWat  = dFlux_dWatBelow(iLayer) ! this is true, but since not used in vegNrgFlux do not define
-       dGroundNetFlux_dGroundTemp = dFlux_dTempBelow(iLayer) ! need this in vegNrgFlux
-    
+
+        ! identify the upper boundary condition
+        select case(ix_bcUpprTdyn)
+
+          ! * prescribed temperature at the upper boundary
+          case(prescribedTemp)
+            dz = (mLayerHeight(iLayer+1) - mLayerHeight(iLayer))
+            if(ixDerivMethod==analytical)then    ! ** analytical derivatives
+              dFlux_dWatBelow(iLayer)  = -dThermalC_dHydStateBelow * ( mLayerTempTrial(iLayer+1) - upperBoundTemp )/dz
+              dFlux_dTempBelow(iLayer) = -dThermalC_dNrgStateBelow * ( mLayerTempTrial(iLayer+1) - upperBoundTemp )/dz - iLayerThermalC(iLayer)/dz
+            else                              ! ** numerical derivatives
+              flux0 = -scalarThermCFlux          *( mLayerTempTrial(iLayer+1) - upperBoundTemp ) / dz
+              flux2 = -scalarThermCFlux_dWatBelow*( mLayerTempTrial(iLayer+1) - upperBoundTemp ) / dz
+              dFlux_dWatBelow(iLayer) = (flux2 - flux0)/dx
+              flux0 = -scalarThermCFlux           *( mLayerTempTrial(iLayer+1)     - upperBoundTemp ) / dz
+              flux2 = -scalarThermCFlux_dTempBelow*((mLayerTempTrial(iLayer+1)+dx) - upperBoundTemp ) / dz
+              dFlux_dTempBelow(iLayer) = (flux2 - flux0)/dx
+            end if
+
+          ! * zero flux at the upper boundary
+          case(zeroFlux)
+            dFlux_dWatBelow(iLayer) = 0._rkind
+            dFlux_dTempBelow(iLayer) = 0._rkind
+
+          ! * compute flux inside vegetation energy flux routine, use here
+          case(energyFlux)
+            dFlux_dWatBelow(iLayer) = 0._rkind !dGroundNetFlux_dGroundWat, does not exist in vegNrgFlux
+            dFlux_dTempBelow(iLayer) = dGroundNetFlux_dGroundTemp
+
+          case default; err=20; message=trim(message)//'unable to identify upper boundary condition for thermodynamics'; return
+
+        end select  ! (identifying the upper boundary condition for thermodynamics)
+        !dGroundNetFlux_dGroundWat  = dFlux_dWatBelow(iLayer) ! this is true, but since not used in vegNrgFlux do not define
+        dGroundNetFlux_dGroundTemp = dFlux_dTempBelow(iLayer) ! need this in vegNrgFlux
+
       ! ***** the lower boundary
       else if(iLayer==nLayers)then  ! (lower boundary)
-    
-       ! identify the lower boundary condition
-       select case(ix_bcLowrTdyn)
-    
-        ! * prescribed temperature at the lower boundary
-        case(prescribedTemp)
-         dz = mLayerDepth(iLayer)*0.5_rkind
-         if(ixDerivMethod==analytical)then    ! ** analytical derivatives
-          dFlux_dWatAbove(iLayer)  = -dThermalC_dHydStateAbove * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz
-          dFlux_dTempAbove(iLayer) = -dThermalC_dNrgStateAbove * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz + iLayerThermalC(iLayer)/dz
-         else                              ! ** numerical derivatives
-          flux0 = -scalarThermCFlux           * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz
-          flux1 = -scalarThermCFlux_dWatAbove * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz
+
+        ! identify the lower boundary condition
+        select case(ix_bcLowrTdyn)
+
+          ! * prescribed temperature at the lower boundary
+          case(prescribedTemp)
+          dz = mLayerDepth(iLayer)*0.5_rkind
+          if(ixDerivMethod==analytical)then    ! ** analytical derivatives
+            dFlux_dWatAbove(iLayer)  = -dThermalC_dHydStateAbove * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz
+            dFlux_dTempAbove(iLayer) = -dThermalC_dNrgStateAbove * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz + iLayerThermalC(iLayer)/dz
+          else                              ! ** numerical derivatives
+            flux0 = -scalarThermCFlux           * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz
+            flux1 = -scalarThermCFlux_dWatAbove * ( lowerBoundTemp - mLayerTempTrial(iLayer) )/dz
+            dFlux_dWatAbove(iLayer) = (flux1 - flux0)/dx
+            flux0 = -scalarThermCFlux            * ( lowerBoundTemp -  mLayerTempTrial(iLayer)     )/dz
+            flux1 = -scalarThermCFlux_dTempAbove * ( lowerBoundTemp - (mLayerTempTrial(iLayer)+dx) )/dz
+            dFlux_dTempAbove(iLayer) = (flux1 - flux0)/dx
+          end if
+
+          ! * zero flux at the lower boundary
+          case(zeroFlux)
+          dFlux_dWatAbove(iLayer) = 0._rkind
+          dFlux_dTempAbove(iLayer) = 0._rkind
+
+          case default; err=20; message=trim(message)//'unable to identify lower boundary condition for thermodynamics'; return
+
+        end select  ! (identifying the lower boundary condition for thermodynamics)
+
+        ! ***** internal layers
+
+      else
+        dz = (mLayerHeight(iLayer+1) - mLayerHeight(iLayer))
+        if(ixDerivMethod==analytical)then    ! ** analytical derivatives
+          dFlux_dWatAbove(iLayer)  = -dThermalC_dHydStateAbove * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz
+          dFlux_dWatBelow(iLayer)  = -dThermalC_dHydStateBelow * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz
+          dFlux_dTempAbove(iLayer) = -dThermalC_dNrgStateAbove * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz + iLayerThermalC(iLayer)/dz
+          dFlux_dTempBelow(iLayer) = -dThermalC_dNrgStateBelow * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz - iLayerThermalC(iLayer)/dz
+        else                              ! ** numerical derivatives
+          flux0 = -scalarThermCFlux          *( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) ) / dz
+          flux1 = -scalarThermCFlux_dWatAbove*( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) ) / dz
+          flux2 = -scalarThermCFlux_dWatBelow*( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) ) / dz
           dFlux_dWatAbove(iLayer) = (flux1 - flux0)/dx
-          flux0 = -scalarThermCFlux            * ( lowerBoundTemp -  mLayerTempTrial(iLayer)     )/dz
-          flux1 = -scalarThermCFlux_dTempAbove * ( lowerBoundTemp - (mLayerTempTrial(iLayer)+dx) )/dz
+          dFlux_dWatBelow(iLayer) = (flux2 - flux0)/dx
+          flux0 = -scalarThermCFlux           *( mLayerTempTrial(iLayer+1)     -  mLayerTempTrial(iLayer)    ) / dz
+          flux1 = -scalarThermCFlux_dTempAbove*( mLayerTempTrial(iLayer+1)     - (mLayerTempTrial(iLayer)+dx)) / dz
+          flux2 = -scalarThermCFlux_dTempBelow*((mLayerTempTrial(iLayer+1)+dx) -  mLayerTempTrial(iLayer)    ) / dz
           dFlux_dTempAbove(iLayer) = (flux1 - flux0)/dx
-         end if
-    
-         ! * zero flux at the lower boundary
-        case(zeroFlux)
-         dFlux_dWatAbove(iLayer) = 0._rkind
-         dFlux_dTempAbove(iLayer) = 0._rkind
-    
-        case default; err=20; message=trim(message)//'unable to identify lower boundary condition for thermodynamics'; return
-    
-       end select  ! (identifying the lower boundary condition for thermodynamics)
-    
-       ! ***** internal layers
-    
-      else
-       dz = (mLayerHeight(iLayer+1) - mLayerHeight(iLayer))
-       if(ixDerivMethod==analytical)then    ! ** analytical derivatives
-        dFlux_dWatAbove(iLayer)  = -dThermalC_dHydStateAbove * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz
-        dFlux_dWatBelow(iLayer)  = -dThermalC_dHydStateBelow * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz
-        dFlux_dTempAbove(iLayer) = -dThermalC_dNrgStateAbove * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz + iLayerThermalC(iLayer)/dz
-        dFlux_dTempBelow(iLayer) = -dThermalC_dNrgStateBelow * ( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) )/dz - iLayerThermalC(iLayer)/dz
-       else                              ! ** numerical derivatives
-        flux0 = -scalarThermCFlux          *( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) ) / dz
-        flux1 = -scalarThermCFlux_dWatAbove*( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) ) / dz
-        flux2 = -scalarThermCFlux_dWatBelow*( mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer) ) / dz
-        dFlux_dWatAbove(iLayer) = (flux1 - flux0)/dx
-        dFlux_dWatBelow(iLayer) = (flux2 - flux0)/dx
-        flux0 = -scalarThermCFlux           *( mLayerTempTrial(iLayer+1)     -  mLayerTempTrial(iLayer)    ) / dz
-        flux1 = -scalarThermCFlux_dTempAbove*( mLayerTempTrial(iLayer+1)     - (mLayerTempTrial(iLayer)+dx)) / dz
-        flux2 = -scalarThermCFlux_dTempBelow*((mLayerTempTrial(iLayer+1)+dx) -  mLayerTempTrial(iLayer)    ) / dz
-        dFlux_dTempAbove(iLayer) = (flux1 - flux0)/dx
-        dFlux_dTempBelow(iLayer) = (flux2 - flux0)/dx
-       end if
-    
+          dFlux_dTempBelow(iLayer) = (flux2 - flux0)/dx
+        end if
+
       end if  ! type of layer (upper, internal, or lower)
-    
-     end do  ! (looping through layers)
-    
-     ! -------------------------------------------------------------------------------------------------------------------------
-     ! ***** compute the conductive fluxes at layer interfaces *****
-     ! Compute flux after the derivatives, because need iLayerThermal as calculated above
-     ! -------------------------------------------------------------------------------------------------------------------------
-     do iLayer=ixTop,ixBot ! (loop through model layers)
-    
+
+    end do  ! (looping through layers)
+
+    ! -------------------------------------------------------------------------------------------------------------------------
+    ! ***** compute the conductive fluxes at layer interfaces *****
+    ! Compute flux after the derivatives, because need iLayerThermal as calculated above
+    ! -------------------------------------------------------------------------------------------------------------------------
+    do iLayer=ixTop,ixBot ! (loop through model layers)
+
       if(iLayer==0)then  ! (upper boundary fluxes -- positive downwards)
       ! flux depends on the type of upper boundary condition
-       select case(ix_bcUpprTdyn) ! (identify the upper boundary condition for thermodynamics
+      select case(ix_bcUpprTdyn) ! (identify the upper boundary condition for thermodynamics
         case(prescribedTemp); iLayerConductiveFlux(iLayer) = -iLayerThermalC(iLayer)*( mLayerTempTrial(iLayer+1) - upperBoundTemp )/ &
                                         (mLayerHeight(iLayer+1) - mLayerHeight(iLayer))
         case(zeroFlux);       iLayerConductiveFlux(iLayer) = 0._rkind
         case(energyFlux);     iLayerConductiveFlux(iLayer) = groundNetFlux !from vegNrgFlux module
-       end select  ! (identifying the lower boundary condition for thermodynamics)
-    
+      end select  ! (identifying the lower boundary condition for thermodynamics)
+
       else if(iLayer==nLayers)then ! (lower boundary fluxes -- positive downwards)
-       ! flux depends on the type of lower boundary condition
-       select case(ix_bcLowrTdyn) ! (identify the lower boundary condition for thermodynamics
+      ! flux depends on the type of lower boundary condition
+      select case(ix_bcLowrTdyn) ! (identify the lower boundary condition for thermodynamics
         case(prescribedTemp); iLayerConductiveFlux(iLayer) = -iLayerThermalC(iLayer)*(lowerBoundTemp - mLayerTempTrial(iLayer))/(mLayerDepth(iLayer)*0.5_rkind)
         case(zeroFlux);       iLayerConductiveFlux(iLayer) = 0._rkind
-       end select  ! (identifying the lower boundary condition for thermodynamics)
-    
+      end select  ! (identifying the lower boundary condition for thermodynamics)
+
       else ! (domain boundary fluxes -- positive downwards)
         iLayerConductiveFlux(iLayer)  = -iLayerThermalC(iLayer)*(mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer)) / &
                                         (mLayerHeight(iLayer+1) - mLayerHeight(iLayer))
-    
+
         !write(*,'(a,i4,1x,2(f9.3,1x))') 'iLayer, iLayerConductiveFlux(iLayer), iLayerThermalC(iLayer) = ', iLayer, iLayerConductiveFlux(iLayer), iLayerThermalC(iLayer)
       end if ! (the type of layer)
-     end do  ! looping through layers
-    
-     ! -------------------------------------------------------------------------------------------------------------------------
-     ! ***** compute the advective fluxes at layer interfaces *****
-     ! -------------------------------------------------------------------------------------------------------------------------
-     do iLayer=ixTop,ixBot  !(loop through model layers)
-    
+    end do  ! looping through layers
+
+    ! -------------------------------------------------------------------------------------------------------------------------
+    ! ***** compute the advective fluxes at layer interfaces *****
+    ! -------------------------------------------------------------------------------------------------------------------------
+    do iLayer=ixTop,ixBot  !(loop through model layers)
+
       if (iLayer==0) then
-       iLayerAdvectiveFlux(iLayer) = realMissing !advective flux at the upper boundary is included in the ground heat flux
+        iLayerAdvectiveFlux(iLayer) = realMissing !advective flux at the upper boundary is included in the ground heat flux
       else ! get the liquid flux at layer interfaces
-       select case(layerType(iLayer))
-        case(iname_snow); qFlux = iLayerLiqFluxSnow(iLayer)
-        case(iname_soil); qFlux = iLayerLiqFluxSoil(iLayer-nSnow)
-        case default; err=20; message=trim(message)//'unable to identify layer type'; return
-       end select
-       ! compute fluxes at the lower boundary -- positive downwards
-       if(iLayer==nLayers)then
-        iLayerAdvectiveFlux(iLayer) = -Cp_water*iden_water*qFlux*(lowerBoundTemp - mLayerTempTrial(iLayer))
-       ! compute fluxes within the domain -- positive downwards
-       else
-        iLayerAdvectiveFlux(iLayer) = -Cp_water*iden_water*qFlux*(mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer))
-       end if
+        select case(layerType(iLayer))
+          case(iname_snow); qFlux = iLayerLiqFluxSnow(iLayer)
+          case(iname_soil); qFlux = iLayerLiqFluxSoil(iLayer-nSnow)
+          case default; err=20; message=trim(message)//'unable to identify layer type'; return
+        end select
+        ! compute fluxes at the lower boundary -- positive downwards
+        if(iLayer==nLayers)then
+          iLayerAdvectiveFlux(iLayer) = -Cp_water*iden_water*qFlux*(lowerBoundTemp - mLayerTempTrial(iLayer))
+        ! compute fluxes within the domain -- positive downwards
+        else
+          iLayerAdvectiveFlux(iLayer) = -Cp_water*iden_water*qFlux*(mLayerTempTrial(iLayer+1) - mLayerTempTrial(iLayer))
+        end if
       end if ! (all layers except surface)
-     end do  ! looping through layers
-    
-     ! -------------------------------------------------------------------------------------------------------------------------
-     ! ***** compute the total fluxes at layer interfaces *****
-     ! -------------------------------------------------------------------------------------------------------------------------
-     ! NOTE: ignore advective fluxes for now
-     iLayerNrgFlux(ixTop:ixBot) = iLayerConductiveFlux(ixTop:ixBot)
-     !print*, 'iLayerNrgFlux(0:4) = ', iLayerNrgFlux(0:4)
-    
-     ! end association of local variables with information in the data structures
-     end associate
-    
-     end subroutine ssdNrgFlux
-    
-    
-     ! *************************************************************************************************************************************
-     ! private subroutine iLayerThermalConduct: compute diagnostic energy variables (thermal conductivity and heat capacity) and derivatives
-     ! *************************************************************************************************************************************
-     subroutine iLayerThermalConduct(&
-                           ! input: model control
-                           deriv_desired,             & ! intent(in): flag indicating if derivatives are desired
-                           ixRichards,                & ! intent(in):    choice of option for Richards' equation
-                           ixThCondSnow,              & ! intent(in): choice of method for thermal conductivity of snow
-                           ixThCondSoil,              & ! intent(in): choice of method for thermal conductivity of soil
-                           ! input: coordinate variables
-                           nLayers,                   & ! intent(in): number of layers
-                           ixLayerDesired,            & ! intent(in): layer index for output
-                           layerType,                 & ! intent(in): layer type (iname_soil or iname_snow)
-                           ! input: state variables (adjacent layers)
-                           nodeMatricHead,            & ! intent(in): matric head at the nodes (m)
-                           nodeVolFracLiq,            & ! intent(in): volumetric liquid water content at the nodes (m)
-                           nodeVolFracIce,            & ! intent(in): volumetric ice at the nodes (m)
-                           nodeTemp,                  & ! intent(in): temperature at the nodes (m)
-                           ! input: pre-computed derivatives
-                           dTheta_dTk,                & ! intent(in): derivative in volumetric liquid water content w.r.t. temperature (K-1)
-                           fracLiqSnow,               & ! intent(in)  : fraction of liquid water (-)
-                           dTheta_dPsi,               & ! intent(in): derivative in the soil water characteristic w.r.t. psi (m-1)
-                           dPsi_dTheta,               & ! intent(in): derivative in the soil water characteristic w.r.t. theta (m)
-                           ! input: model coordinate variables (adjacent layers)
-                           nodeHeight,                & ! intent(in): height at the mid-point of the node (m)
-                           node_iHeight,              & ! intent(in): height at the interface of the nodes (m)
-                           ! input: soil parameters at nodes
-                           theta_sat,                 & ! intent(in): soil porosity (-)
-                           iden_soil,                 & !intrinsic density of soil (kg m-3)
-                           thCond_soil,               & ! thermal conductivity of soil (W m-1 K-1)
-                           frac_sand,                 & ! intent(in): fraction of sand (-)
-                           frac_clay,                 & ! fraction of clay (-)
-                           ! input: snow parameters
-                           fixedThermalCond_snow,     & ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
-                           ! output: conductivity at the layer interface (scalars)
-                           iLayerThermalC,            & ! intent(inout) thermal conductivity at the interface of each layer (W m-1 K-1)
-                            ! output: derivatives in thermal conductivity w.r.t. state variables -- matric head or volumetric lquid water -- in the layer above and layer below
-                           dThermalC_dHydStateAbove,  & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
-                           dThermalC_dHydStateBelow,  & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
-                          ! output: derivatives in thermal conductivity w.r.t. energy state variables -- now just temperature -- in the layer above and layer below (W m-1 K-2)
-                           dThermalC_dNrgStateAbove,  & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
-                           dThermalC_dNrgStateBelow,  & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
-                           ! output: error control
-                           err,message)                 ! intent(out): error control
-    
-     USE snow_utils_module,only:tcond_snow     ! compute thermal conductivity of snow
-     USE soil_utils_module,only:crit_soilT     ! compute critical temperature below which ice exists
-     ! constants
-     USE multiconst, only: gravity, &                          ! gravitational acceleration (m s-1)
-                           Tfreeze, &                          ! freezing point of water (K)
-                           iden_water,iden_ice,&               ! intrinsic density of water and ice (kg m-3)
-                           LH_fus                              ! latent heat of fusion (J kg-1)
-    
-     implicit none
-     ! --------------------------------------------------------------------------------------------------------------------------------------
-     ! input: model control
-     logical(lgt),intent(in)          :: deriv_desired             ! flag to indicate if derivatives are desired
-     integer(i4b),intent(in)          :: ixRichards                ! choice of option for Richards' equation
-     integer(i4b),intent(in)          :: ixThCondSnow              ! choice of method for thermal conductivity of snow
-     integer(i4b),intent(in)          :: ixThCondSoil              ! choice of method for thermal conductivity of soil
-     ! input: coordinate variables
-     integer(i4b),intent(in)          :: nLayers                   ! number of layers
-     integer(i4b),intent(in)          :: ixLayerDesired            ! layer index for output
-     integer(i4b),intent(in)          :: layerType(:)              ! layer type (iname_soil or iname_snow)
-     ! input: state variables
-     real(rkind),intent(in)           :: nodeMatricHead(:)         ! trial vector of total water matric potential (m)
-     real(rkind),intent(in)           :: nodeVolFracLiq(:)         ! trial vector of volumetric liquid water content, recomputed with perturbed water state(-)
-     real(rkind),intent(in)           :: nodeVolFracIce(:)         ! trial vector of ice content, recomputed with perturbed water state(-)
-     real(rkind),intent(in)           :: nodeTemp(:)               ! trial vector of temperature (K)
-     ! input: pre-computed derivatives
-     real(rkind),intent(in)           :: dTheta_dTk(:)             ! derivative in volumetric liquid water content w.r.t. temperature (K-1)
-     real(rkind),intent(in)           :: fracLiqSnow(:)            ! fraction of liquid water (-)
-     real(rkind),intent(in)           :: dTheta_dPsi(:)            ! derivative in the soil water characteristic w.r.t. psi (m-1)
-     real(rkind),intent(in)           :: dPsi_dTheta(:)            ! derivative in the soil water characteristic w.r.t. theta (m)
-     ! input: model coordinate variables
-     real(rkind),intent(in)           :: nodeHeight(:)             ! height at the mid-point of the lower node (m)
-     real(rkind),intent(in)           :: node_iHeight(:)           ! height at the interface of each node (m)
-     ! input: soil parameters
-     real(rkind),intent(in)           :: theta_sat(:)              ! soil porosity (-)
-     real(rkind),intent(in)           :: iden_soil(:)              ! intrinsic density of soil (kg m-3)
-     real(rkind),intent(in)           :: thCond_soil(:)            ! thermal conductivity of soil (W m-1 K-1)
-     real(rkind),intent(in)           :: frac_sand(:)              ! intent(in): fraction of sand (-)
-     real(rkind),intent(in)           :: frac_clay(:)              ! fraction of clay (-)
-     ! input: snow parameters
-     real(rkind),intent(in)           :: fixedThermalCond_snow     ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
-     ! output: thermal conductivity at layer interfaces
-     real(rkind),intent(inout)        :: iLayerThermalC            ! thermal conductivity at the interface of each layer (W m-1 K-1)
-     ! output: thermal conductivity derivatives at all layer interfaces
-     real(rkind),intent(out)          :: dThermalC_dHydStateAbove  ! derivatives in the thermal conductivity w.r.t. matric head or volumetric liquid water in the layer above
-     real(rkind),intent(out)          :: dThermalC_dHydStateBelow  ! derivatives in the thermal conductivity w.r.t. matric head or volumetric liquid water in the layer below
-     real(rkind),intent(out)          :: dThermalC_dNrgStateAbove  ! derivatives in the thermal conductivity w.r.t. temperature in the layer above (W m-1 K-2)
-     real(rkind),intent(out)          :: dThermalC_dNrgStateBelow  ! derivatives in the thermal conductivity w.r.t. temperature in the layer below (W m-1 K-2)
-     ! output: error control
-     integer(i4b),intent(out)         :: err                       ! error code
-     character(*),intent(out)         :: message                   ! error message
-     ! --------------------------------------------------------------------------------------------------------------------------------
-     ! local variables (named variables to provide index of 2-element vectors)
-     integer(i4b),parameter           :: ixUpper=1                 ! index of upper node in the 2-element vectors
-     integer(i4b),parameter           :: ixLower=2                 ! index of lower node in the 2-element vectors
-     character(LEN=256)               :: cmessage                  ! error message of downwind routine
-     integer(i4b)                     :: iLayer                    ! index of model layer
-     real(rkind)                      :: TCn                       ! thermal conductivity below the layer interface (W m-1 K-1)
-     real(rkind)                      :: TCp                       ! thermal conductivity above the layer interface (W m-1 K-1)
-     real(rkind)                      :: zdn                       ! height difference between interface and lower value (m)
-     real(rkind)                      :: zdp                       ! height difference between interface and upper value (m)
-     real(rkind)                      :: bulkden_soil              ! bulk density of soil (kg m-3)
-     real(rkind)                      :: lambda_drysoil            ! thermal conductivity of dry soil (W m-1)
-     real(rkind)                      :: lambda_wetsoil            ! thermal conductivity of wet soil (W m-1)
-     real(rkind)                      :: lambda_wet                ! thermal conductivity of the wet material
-     real(rkind)                      :: relativeSat               ! relative saturation (-)
-     real(rkind)                      :: kerstenNum                ! the Kersten number (-), defining weight applied to conductivity of the wet medium
-     real(rkind)                      :: den                       ! denominator in the thermal conductivity calculations
-     real(rkind)                      :: dThermalC_dWat(2)   ! derivative in thermal conductivity w.r.t. matric head or volumetric liquid water
-     real(rkind)                      :: dThermalC_dNrg(2)   ! derivative in thermal conductivity w.r.t. temperature
-     real(rkind)                      :: Tcrit                     ! temperature where all water is unfrozen (K)
-     real(rkind)                      :: dlambda_wet_dWat          ! derivative in thermal conductivity of wet material w.r.t.soil water state variable
-     real(rkind)                      :: dlambda_wet_dTk           ! derivative in thermal conductivity of wet material w.r.t. temperature
-     real(rkind)                      :: dkerstenNum_dWat          ! derivative in Kersten number w.r.t. soil water state variable
-     real(rkind)                      :: mLayerThermalC(2)         ! thermal conductivity of each layer (W m-1 K-1)
-     real(rkind)                      :: dVolFracLiq_dWat    ! derivative in vol fraction of liquid w.r.t. water state variable
-     real(rkind)                      :: dVolFracIce_dWat    ! derivative in vol fraction of ice w.r.t. water state variable
-     real(rkind)                      :: dVolFracLiq_dTk     ! derivative in vol fraction of liquid w.r.t. temperature
-     real(rkind)                      :: dVolFracIce_dTk     ! derivative in vol fraction of ice w.r.t. temperature
-    ! local variables to reproduce the thermal conductivity of Hansson et al. VZJ 2005
-     real(rkind),parameter            :: c1=0.55_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (W m-1 K-1)
-     real(rkind),parameter            :: c2=0.8_rkind              ! optimized parameter from Hansson et al. VZJ 2005 (W m-1 K-1)
-     real(rkind),parameter            :: c3=3.07_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (-)
-     real(rkind),parameter            :: c4=0.13_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (W m-1 K-1)
-     real(rkind),parameter            :: c5=4._rkind               ! optimized parameter from Hansson et al. VZJ 2005 (-)
-     real(rkind),parameter            :: f1=13.05_rkind            ! optimized parameter from Hansson et al. VZJ 2005 (-)
-     real(rkind),parameter            :: f2=1.06_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (-)
-     real(rkind)                      :: fArg,xArg                 ! temporary variables (see Hansson et al. VZJ 2005 for details)
-     real(rkind)                      :: dxArg_dWat,dxArg_dTk      ! derivates of the temporary variables with respect to soil water state variable and temperature
-    
-     ! --------------------------------------------------------------------------------------------------------------------------------
-     ! initialize error control
-     err=0; message="iLayerThermalConduct/"
-    
-     ! loop through layers
-     do iLayer=ixUpper,ixLower
-    
-      ! compute the thermal conductivity of dry and wet soils (W m-1)
-      ! NOTE: this is actually constant over the simulation, and included here for clarity
-      if(ixThCondSoil==funcSoilWet .and. layerType(iLayer)==iname_soil)then
-       bulkden_soil   = iden_soil(iLayer)*( 1._rkind - theta_sat(iLayer) )
-       lambda_drysoil = (0.135_rkind*bulkden_soil + 64.7_rkind) / (iden_soil(iLayer) - 0.947_rkind*bulkden_soil)
-       lambda_wetsoil = (8.80_rkind*frac_sand(iLayer) + 2.92_rkind*frac_clay(iLayer)) / (frac_sand(iLayer) + frac_clay(iLayer))
-      end if
-    
-      ! *****
-      ! * compute the thermal conductivity of snow and soil and derivates at the mid-point of each layer...
-      ! ***************************************************************************************************
-      dThermalC_dWat(iLayer) = 0._rkind
-      dThermalC_dNrg(iLayer) = 0._rkind
-    
-      select case(layerType(iLayer))
-    
-       ! ***** soil
-       case(iname_soil)
-    
+    end do  ! looping through layers
+
+    ! -------------------------------------------------------------------------------------------------------------------------
+    ! ***** compute the total fluxes at layer interfaces *****
+    ! -------------------------------------------------------------------------------------------------------------------------
+    ! NOTE: ignore advective fluxes for now
+    iLayerNrgFlux(ixTop:ixBot) = iLayerConductiveFlux(ixTop:ixBot)
+
+  ! end association of local variables with information in the data structures
+  end associate
+
+end subroutine ssdNrgFlux
+
+
+! *************************************************************************************************************************************
+! private subroutine iLayerThermalConduct: compute diagnostic energy variables (thermal conductivity and heat capacity) and derivatives
+! *************************************************************************************************************************************
+subroutine iLayerThermalConduct(&
+                      ! input: model control
+                      deriv_desired,             & ! intent(in): flag indicating if derivatives are desired
+                      ixRichards,                & ! intent(in):    choice of option for Richards' equation
+                      ixThCondSnow,              & ! intent(in): choice of method for thermal conductivity of snow
+                      ixThCondSoil,              & ! intent(in): choice of method for thermal conductivity of soil
+                      ! input: coordinate variables
+                      nLayers,                   & ! intent(in): number of layers
+                      ixLayerDesired,            & ! intent(in): layer index for output
+                      layerType,                 & ! intent(in): layer type (iname_soil or iname_snow)
+                      ! input: state variables (adjacent layers)
+                      nodeMatricHead,            & ! intent(in): matric head at the nodes (m)
+                      nodeVolFracLiq,            & ! intent(in): volumetric liquid water content at the nodes (m)
+                      nodeVolFracIce,            & ! intent(in): volumetric ice at the nodes (m)
+                      nodeTemp,                  & ! intent(in): temperature at the nodes (m)
+                      ! input: pre-computed derivatives
+                      dTheta_dTk,                & ! intent(in): derivative in volumetric liquid water content w.r.t. temperature (K-1)
+                      fracLiqSnow,               & ! intent(in)  : fraction of liquid water (-)
+                      dTheta_dPsi,               & ! intent(in): derivative in the soil water characteristic w.r.t. psi (m-1)
+                      dPsi_dTheta,               & ! intent(in): derivative in the soil water characteristic w.r.t. theta (m)
+                      ! input: model coordinate variables (adjacent layers)
+                      nodeHeight,                & ! intent(in): height at the mid-point of the node (m)
+                      node_iHeight,              & ! intent(in): height at the interface of the nodes (m)
+                      ! input: soil parameters at nodes
+                      theta_sat,                 & ! intent(in): soil porosity (-)
+                      iden_soil,                 & !intrinsic density of soil (kg m-3)
+                      thCond_soil,               & ! thermal conductivity of soil (W m-1 K-1)
+                      frac_sand,                 & ! intent(in): fraction of sand (-)
+                      frac_clay,                 & ! fraction of clay (-)
+                      ! input: snow parameters
+                      fixedThermalCond_snow,     & ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
+                      ! output: conductivity at the layer interface (scalars)
+                      iLayerThermalC,            & ! intent(inout) thermal conductivity at the interface of each layer (W m-1 K-1)
+                      ! output: derivatives in thermal conductivity w.r.t. state variables -- matric head or volumetric lquid water -- in the layer above and layer below
+                      dThermalC_dHydStateAbove,  & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
+                      dThermalC_dHydStateBelow,  & ! intent(out): derivative in the thermal conductivity w.r.t. water state in the layer above
+                    ! output: derivatives in thermal conductivity w.r.t. energy state variables -- now just temperature -- in the layer above and layer below (W m-1 K-2)
+                      dThermalC_dNrgStateAbove,  & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
+                      dThermalC_dNrgStateBelow,  & ! intent(out): derivative in the thermal conductivity w.r.t. energy state in the layer above
+                      ! output: error control
+                      err,message)                 ! intent(out): error control
+
+  USE snow_utils_module,only:tcond_snow     ! compute thermal conductivity of snow
+  USE soil_utils_module,only:crit_soilT     ! compute critical temperature below which ice exists
+  ! constants
+  USE multiconst, only: gravity, &                          ! gravitational acceleration (m s-1)
+                        Tfreeze, &                          ! freezing point of water (K)
+                        iden_water,iden_ice,&               ! intrinsic density of water and ice (kg m-3)
+                        LH_fus                              ! latent heat of fusion (J kg-1)
+
+  implicit none
+  ! --------------------------------------------------------------------------------------------------------------------------------------
+  ! input: model control
+  logical(lgt),intent(in)          :: deriv_desired             ! flag to indicate if derivatives are desired
+  integer(i4b),intent(in)          :: ixRichards                ! choice of option for Richards' equation
+  integer(i4b),intent(in)          :: ixThCondSnow              ! choice of method for thermal conductivity of snow
+  integer(i4b),intent(in)          :: ixThCondSoil              ! choice of method for thermal conductivity of soil
+  ! input: coordinate variables
+  integer(i4b),intent(in)          :: nLayers                   ! number of layers
+  integer(i4b),intent(in)          :: ixLayerDesired            ! layer index for output
+  integer(i4b),intent(in)          :: layerType(:)              ! layer type (iname_soil or iname_snow)
+  ! input: state variables
+  real(rkind),intent(in)           :: nodeMatricHead(:)         ! trial vector of total water matric potential (m)
+  real(rkind),intent(in)           :: nodeVolFracLiq(:)         ! trial vector of volumetric liquid water content, recomputed with perturbed water state(-)
+  real(rkind),intent(in)           :: nodeVolFracIce(:)         ! trial vector of ice content, recomputed with perturbed water state(-)
+  real(rkind),intent(in)           :: nodeTemp(:)               ! trial vector of temperature (K)
+  ! input: pre-computed derivatives
+  real(rkind),intent(in)           :: dTheta_dTk(:)             ! derivative in volumetric liquid water content w.r.t. temperature (K-1)
+  real(rkind),intent(in)           :: fracLiqSnow(:)            ! fraction of liquid water (-)
+  real(rkind),intent(in)           :: dTheta_dPsi(:)            ! derivative in the soil water characteristic w.r.t. psi (m-1)
+  real(rkind),intent(in)           :: dPsi_dTheta(:)            ! derivative in the soil water characteristic w.r.t. theta (m)
+  ! input: model coordinate variables
+  real(rkind),intent(in)           :: nodeHeight(:)             ! height at the mid-point of the lower node (m)
+  real(rkind),intent(in)           :: node_iHeight(:)           ! height at the interface of each node (m)
+  ! input: soil parameters
+  real(rkind),intent(in)           :: theta_sat(:)              ! soil porosity (-)
+  real(rkind),intent(in)           :: iden_soil(:)              ! intrinsic density of soil (kg m-3)
+  real(rkind),intent(in)           :: thCond_soil(:)            ! thermal conductivity of soil (W m-1 K-1)
+  real(rkind),intent(in)           :: frac_sand(:)              ! intent(in): fraction of sand (-)
+  real(rkind),intent(in)           :: frac_clay(:)              ! fraction of clay (-)
+  ! input: snow parameters
+  real(rkind),intent(in)           :: fixedThermalCond_snow     ! intent(in): temporally constant thermal conductivity of snow (W m-1 K-1)
+  ! output: thermal conductivity at layer interfaces
+  real(rkind),intent(inout)        :: iLayerThermalC            ! thermal conductivity at the interface of each layer (W m-1 K-1)
+  ! output: thermal conductivity derivatives at all layer interfaces
+  real(rkind),intent(out)          :: dThermalC_dHydStateAbove  ! derivatives in the thermal conductivity w.r.t. matric head or volumetric liquid water in the layer above
+  real(rkind),intent(out)          :: dThermalC_dHydStateBelow  ! derivatives in the thermal conductivity w.r.t. matric head or volumetric liquid water in the layer below
+  real(rkind),intent(out)          :: dThermalC_dNrgStateAbove  ! derivatives in the thermal conductivity w.r.t. temperature in the layer above (W m-1 K-2)
+  real(rkind),intent(out)          :: dThermalC_dNrgStateBelow  ! derivatives in the thermal conductivity w.r.t. temperature in the layer below (W m-1 K-2)
+  ! output: error control
+  integer(i4b),intent(out)         :: err                       ! error code
+  character(*),intent(out)         :: message                   ! error message
+  ! --------------------------------------------------------------------------------------------------------------------------------
+  ! local variables (named variables to provide index of 2-element vectors)
+  integer(i4b),parameter           :: ixUpper=1                 ! index of upper node in the 2-element vectors
+  integer(i4b),parameter           :: ixLower=2                 ! index of lower node in the 2-element vectors
+  character(LEN=256)               :: cmessage                  ! error message of downwind routine
+  integer(i4b)                     :: iLayer                    ! index of model layer
+  real(rkind)                      :: TCn                       ! thermal conductivity below the layer interface (W m-1 K-1)
+  real(rkind)                      :: TCp                       ! thermal conductivity above the layer interface (W m-1 K-1)
+  real(rkind)                      :: zdn                       ! height difference between interface and lower value (m)
+  real(rkind)                      :: zdp                       ! height difference between interface and upper value (m)
+  real(rkind)                      :: bulkden_soil              ! bulk density of soil (kg m-3)
+  real(rkind)                      :: lambda_drysoil            ! thermal conductivity of dry soil (W m-1)
+  real(rkind)                      :: lambda_wetsoil            ! thermal conductivity of wet soil (W m-1)
+  real(rkind)                      :: lambda_wet                ! thermal conductivity of the wet material
+  real(rkind)                      :: relativeSat               ! relative saturation (-)
+  real(rkind)                      :: kerstenNum                ! the Kersten number (-), defining weight applied to conductivity of the wet medium
+  real(rkind)                      :: den                       ! denominator in the thermal conductivity calculations
+  real(rkind)                      :: dThermalC_dWat(2)   ! derivative in thermal conductivity w.r.t. matric head or volumetric liquid water
+  real(rkind)                      :: dThermalC_dNrg(2)   ! derivative in thermal conductivity w.r.t. temperature
+  real(rkind)                      :: Tcrit                     ! temperature where all water is unfrozen (K)
+  real(rkind)                      :: dlambda_wet_dWat          ! derivative in thermal conductivity of wet material w.r.t.soil water state variable
+  real(rkind)                      :: dlambda_wet_dTk           ! derivative in thermal conductivity of wet material w.r.t. temperature
+  real(rkind)                      :: dkerstenNum_dWat          ! derivative in Kersten number w.r.t. soil water state variable
+  real(rkind)                      :: mLayerThermalC(2)         ! thermal conductivity of each layer (W m-1 K-1)
+  real(rkind)                      :: dVolFracLiq_dWat    ! derivative in vol fraction of liquid w.r.t. water state variable
+  real(rkind)                      :: dVolFracIce_dWat    ! derivative in vol fraction of ice w.r.t. water state variable
+  real(rkind)                      :: dVolFracLiq_dTk     ! derivative in vol fraction of liquid w.r.t. temperature
+  real(rkind)                      :: dVolFracIce_dTk     ! derivative in vol fraction of ice w.r.t. temperature
+  ! local variables to reproduce the thermal conductivity of Hansson et al. VZJ 2005
+  real(rkind),parameter            :: c1=0.55_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (W m-1 K-1)
+  real(rkind),parameter            :: c2=0.8_rkind              ! optimized parameter from Hansson et al. VZJ 2005 (W m-1 K-1)
+  real(rkind),parameter            :: c3=3.07_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (-)
+  real(rkind),parameter            :: c4=0.13_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (W m-1 K-1)
+  real(rkind),parameter            :: c5=4._rkind               ! optimized parameter from Hansson et al. VZJ 2005 (-)
+  real(rkind),parameter            :: f1=13.05_rkind            ! optimized parameter from Hansson et al. VZJ 2005 (-)
+  real(rkind),parameter            :: f2=1.06_rkind             ! optimized parameter from Hansson et al. VZJ 2005 (-)
+  real(rkind)                      :: fArg,xArg                 ! temporary variables (see Hansson et al. VZJ 2005 for details)
+  real(rkind)                      :: dxArg_dWat,dxArg_dTk      ! derivates of the temporary variables with respect to soil water state variable and temperature
+
+  ! --------------------------------------------------------------------------------------------------------------------------------
+  ! initialize error control
+  err=0; message="iLayerThermalConduct/"
+
+  ! loop through layers
+  do iLayer=ixUpper,ixLower
+
+    ! compute the thermal conductivity of dry and wet soils (W m-1)
+    ! NOTE: this is actually constant over the simulation, and included here for clarity
+    if(ixThCondSoil==funcSoilWet .and. layerType(iLayer)==iname_soil)then
+    bulkden_soil   = iden_soil(iLayer)*( 1._rkind - theta_sat(iLayer) )
+    lambda_drysoil = (0.135_rkind*bulkden_soil + 64.7_rkind) / (iden_soil(iLayer) - 0.947_rkind*bulkden_soil)
+    lambda_wetsoil = (8.80_rkind*frac_sand(iLayer) + 2.92_rkind*frac_clay(iLayer)) / (frac_sand(iLayer) + frac_clay(iLayer))
+    end if
+
+    ! *****
+    ! * compute the thermal conductivity of snow and soil and derivates at the mid-point of each layer...
+    ! ***************************************************************************************************
+    dThermalC_dWat(iLayer) = 0._rkind
+    dThermalC_dNrg(iLayer) = 0._rkind
+
+    select case(layerType(iLayer))
+
+      ! ***** soil
+      case(iname_soil)
+
         ! (process derivatives)
         dVolFracLiq_dWat = 0._rkind
         dVolFracIce_dWat = 0._rkind
         dVolFracLiq_dTk  = 0._rkind
         dVolFracIce_dTk  = 0._rkind
         if(deriv_desired)then
-         select case(ixRichards)  ! (form of Richards' equation)
-          case(moisture)
-           dVolFracLiq_dWat = 1._rkind
-           dVolFracIce_dWat = dPsi_dTheta(iLayer) - 1._rkind
-          case(mixdform)
-           Tcrit = crit_soilT(nodeMatricHead(iLayer) )
-           if(nodeTemp(iLayer) < Tcrit) then
-            dVolFracLiq_dWat = 0._rkind
-            dVolFracIce_dWat = dTheta_dPsi(iLayer)
-           else
-            dVolFracLiq_dWat = dTheta_dPsi(iLayer)
-            dVolFracIce_dWat = 0._rkind
-           endif
-         end select
-         dVolFracLiq_dTk = dTheta_dTk(iLayer) !already zeroed out if not below critical temperature
-         dVolFracIce_dTk = -dVolFracLiq_dTk !often can and will simplify one of these terms out
+          select case(ixRichards)  ! (form of Richards' equation)
+            case(moisture)
+              dVolFracLiq_dWat = 1._rkind
+              dVolFracIce_dWat = dPsi_dTheta(iLayer) - 1._rkind
+            case(mixdform)
+              Tcrit = crit_soilT(nodeMatricHead(iLayer) )
+              if(nodeTemp(iLayer) < Tcrit) then
+                dVolFracLiq_dWat = 0._rkind
+                dVolFracIce_dWat = dTheta_dPsi(iLayer)
+              else
+                dVolFracLiq_dWat = dTheta_dPsi(iLayer)
+                dVolFracIce_dWat = 0._rkind
+              endif
+          end select
+          dVolFracLiq_dTk = dTheta_dTk(iLayer) !already zeroed out if not below critical temperature
+          dVolFracIce_dTk = -dVolFracLiq_dTk !often can and will simplify one of these terms out
         endif
-    
+
         ! select option for thermal conductivity of soil
         select case(ixThCondSoil)
-    
-         ! ** function of soil wetness
-         case(funcSoilWet)
-    
-          ! compute the thermal conductivity of the wet material (W m-1)
-          lambda_wet  = lambda_wetsoil**( 1._rkind - theta_sat(iLayer) ) * lambda_water**theta_sat(iLayer) * lambda_ice**(theta_sat(iLayer) - nodeVolFracLiq(iLayer))
-          dlambda_wet_dWat = -lambda_wet * log(lambda_ice) * dVolFracLiq_dWat
-          dlambda_wet_dTk  = -lambda_wet * log(lambda_ice) * dVolFracLiq_dTk
-    
-          relativeSat = (nodeVolFracIce(iLayer) + nodeVolFracLiq(iLayer))/theta_sat(iLayer)  ! relative saturation
-          ! drelativeSat_dWat = dPsi0_dWat/theta_sat(iLayer), and drelativeSat_dTk = 0 (so dkerstenNum_dTk = 0)
-          ! compute the Kersten number (-)
-          if(relativeSat > 0.1_rkind)then ! log10(0.1) = -1
-           kerstenNum = log10(relativeSat) + 1._rkind
-           dkerstenNum_dWat = (dVolFracIce_dWat + dVolFracLiq_dWat) / ( theta_sat(iLayer) * relativeSat * log(10._rkind) )
-          else
-           kerstenNum = 0._rkind  ! dry thermal conductivity
-           dkerstenNum_dWat = 0._rkind
-          endif
-          ! ...and, compute the thermal conductivity
-          mLayerThermalC(iLayer) = kerstenNum*lambda_wet + (1._rkind - kerstenNum)*lambda_drysoil
-    
-          ! compute derivatives
-          dThermalC_dWat(iLayer) = dkerstenNum_dWat * ( lambda_wet - lambda_drysoil ) + kerstenNum*dlambda_wet_dWat
-          dThermalC_dNrg(iLayer) = kerstenNum*dlambda_wet_dTk
-    
-         ! ** mixture of constituents
-         case(mixConstit)
-          mLayerThermalC(iLayer) = thCond_soil(iLayer) * ( 1._rkind - theta_sat(iLayer) ) + & ! soil component
-                                   lambda_ice         * nodeVolFracIce(iLayer)     + & ! ice component
-                                   lambda_water       * nodeVolFracLiq(iLayer)     + & ! liquid water component
-                                   lambda_air         * ( theta_sat(iLayer) - (nodeVolFracIce(iLayer) + nodeVolFracLiq(iLayer)) ) ! air component
-          ! compute derivatives
-          dThermalC_dWat(iLayer) = lambda_ice*dVolFracIce_dWat + lambda_water*dVolFracLiq_dWat + lambda_air*(-dVolFracIce_dWat - dVolFracLiq_dWat)
-          dThermalC_dNrg(iLayer) = (lambda_ice - lambda_water) * dVolFracIce_dTk
-    
-         ! ** test case for the mizoguchi lab experiment, Hansson et al. VZJ 2004
-         case(hanssonVZJ)
-          fArg  = 1._rkind + f1*nodeVolFracIce(iLayer)**f2
-          xArg  = nodeVolFracLiq(iLayer) + fArg*nodeVolFracIce(iLayer)
-          dxArg_dWat = dVolFracLiq_dWat + dVolFracIce_dWat * (1._rkind + f1*(f2+1)*nodeVolFracIce(iLayer)**f2)
-          dxArg_dTk  = dVolFracIce_dTk * f1*(f2+1)*nodeVolFracIce(iLayer)**f2
-          ! ...and, compute the thermal conductivity
-          mLayerThermalC(iLayer) = c1 + c2*xArg + (c1 - c4)*exp(-(c3*xArg)**c5)
-    
-          ! compute derivatives
-          dThermalC_dWat(iLayer) = ( c2 - c5*c3*(c3*xArg)**(c5-1)*(c1 - c4)*exp(-(c3*xArg)**c5) ) * dxArg_dWat
-          dThermalC_dNrg(iLayer) = ( c2 - c5*c3*(c3*xArg)**(c5-1)*(c1 - c4)*exp(-(c3*xArg)**c5) ) * dxArg_dTk
-    
-         ! ** check
-         case default; err=20; message=trim(message)//'unable to identify option for thermal conductivity of soil'; return
-    
+
+          ! ** function of soil wetness
+          case(funcSoilWet)
+
+            ! compute the thermal conductivity of the wet material (W m-1)
+            lambda_wet  = lambda_wetsoil**( 1._rkind - theta_sat(iLayer) ) * lambda_water**theta_sat(iLayer) * lambda_ice**(theta_sat(iLayer) - nodeVolFracLiq(iLayer))
+            dlambda_wet_dWat = -lambda_wet * log(lambda_ice) * dVolFracLiq_dWat
+            dlambda_wet_dTk  = -lambda_wet * log(lambda_ice) * dVolFracLiq_dTk
+
+            relativeSat = (nodeVolFracIce(iLayer) + nodeVolFracLiq(iLayer))/theta_sat(iLayer)  ! relative saturation
+            ! drelativeSat_dWat = dPsi0_dWat/theta_sat(iLayer), and drelativeSat_dTk = 0 (so dkerstenNum_dTk = 0)
+            ! compute the Kersten number (-)
+            if(relativeSat > 0.1_rkind)then ! log10(0.1) = -1
+              kerstenNum = log10(relativeSat) + 1._rkind
+              dkerstenNum_dWat = (dVolFracIce_dWat + dVolFracLiq_dWat) / ( theta_sat(iLayer) * relativeSat * log(10._rkind) )
+            else
+              kerstenNum = 0._rkind  ! dry thermal conductivity
+              dkerstenNum_dWat = 0._rkind
+            endif
+            ! ...and, compute the thermal conductivity
+            mLayerThermalC(iLayer) = kerstenNum*lambda_wet + (1._rkind - kerstenNum)*lambda_drysoil
+
+            ! compute derivatives
+            dThermalC_dWat(iLayer) = dkerstenNum_dWat * ( lambda_wet - lambda_drysoil ) + kerstenNum*dlambda_wet_dWat
+            dThermalC_dNrg(iLayer) = kerstenNum*dlambda_wet_dTk
+
+          ! ** mixture of constituents
+          case(mixConstit)
+            mLayerThermalC(iLayer) = thCond_soil(iLayer) * ( 1._rkind - theta_sat(iLayer) ) + & ! soil component
+                                    lambda_ice         * nodeVolFracIce(iLayer)     + & ! ice component
+                                    lambda_water       * nodeVolFracLiq(iLayer)     + & ! liquid water component
+                                    lambda_air         * ( theta_sat(iLayer) - (nodeVolFracIce(iLayer) + nodeVolFracLiq(iLayer)) ) ! air component
+            ! compute derivatives
+            dThermalC_dWat(iLayer) = lambda_ice*dVolFracIce_dWat + lambda_water*dVolFracLiq_dWat + lambda_air*(-dVolFracIce_dWat - dVolFracLiq_dWat)
+            dThermalC_dNrg(iLayer) = (lambda_ice - lambda_water) * dVolFracIce_dTk
+
+          ! ** test case for the mizoguchi lab experiment, Hansson et al. VZJ 2004
+          case(hanssonVZJ)
+            fArg  = 1._rkind + f1*nodeVolFracIce(iLayer)**f2
+            xArg  = nodeVolFracLiq(iLayer) + fArg*nodeVolFracIce(iLayer)
+            dxArg_dWat = dVolFracLiq_dWat + dVolFracIce_dWat * (1._rkind + f1*(f2+1)*nodeVolFracIce(iLayer)**f2)
+            dxArg_dTk  = dVolFracIce_dTk * f1*(f2+1)*nodeVolFracIce(iLayer)**f2
+            ! ...and, compute the thermal conductivity
+            mLayerThermalC(iLayer) = c1 + c2*xArg + (c1 - c4)*exp(-(c3*xArg)**c5)
+
+            ! compute derivatives
+            dThermalC_dWat(iLayer) = ( c2 - c5*c3*(c3*xArg)**(c5-1)*(c1 - c4)*exp(-(c3*xArg)**c5) ) * dxArg_dWat
+            dThermalC_dNrg(iLayer) = ( c2 - c5*c3*(c3*xArg)**(c5-1)*(c1 - c4)*exp(-(c3*xArg)**c5) ) * dxArg_dTk
+
+          ! ** check
+          case default; err=20; message=trim(message)//'unable to identify option for thermal conductivity of soil'; return
+
         end select  ! option for the thermal conductivity of soil
-    
-       ! ***** snow
-       case(iname_snow)
+
+      ! ***** snow
+      case(iname_snow)
         dVolFracIce_dWat = ( 1._rkind - fracLiqSnow(iLayer) )*(iden_water/iden_ice)
         dVolFracIce_dTk = -dTheta_dTk(iLayer)*(iden_water/iden_ice)
-    
+
         ! temporally constant thermal conductivity
         if(ixThCondSnow==Smirnova2000)then
-         mLayerThermalC(iLayer) = fixedThermalCond_snow
-         dThermalC_dWat(iLayer) = 0._rkind
-         dThermalC_dNrg(iLayer) = 0._rkind
-        ! thermal conductivity as a function of snow density
+          mLayerThermalC(iLayer) = fixedThermalCond_snow
+          dThermalC_dWat(iLayer) = 0._rkind
+          dThermalC_dNrg(iLayer) = 0._rkind
+          ! thermal conductivity as a function of snow density
         else
-         call tcond_snow(nodeVolFracIce(iLayer)*iden_ice,  & ! input: snow density (kg m-3)
-                         mLayerThermalC(iLayer),             & ! output: thermal conductivity (W m-1 K-1)
-                         err,cmessage)                         ! output: error control
-         if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
-    
-         select case(ixThCondSnow)
-          case(Yen1965)
-           dThermalC_dWat(iLayer) = 2._rkind * 3.217d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dWat
-           dThermalC_dNrg(iLayer) = 2._rkind * 3.217d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dTk
-          case(Mellor1977)
-           dThermalC_dWat(iLayer) = 2._rkind * 2.576d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dWat
-           dThermalC_dNrg(iLayer) = 2._rkind * 2.576d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dTk
-          case(Jordan1991)
-           dThermalC_dWat(iLayer) = ( 7.75d-5 + 2._rkind * 1.105d-6 * nodeVolFracIce(iLayer) * iden_ice ) * (lambda_ice-lambda_air) * iden_ice * dVolFracIce_dWat
-           dThermalC_dNrg(iLayer) = ( 7.75d-5 + 2._rkind * 1.105d-6 * nodeVolFracIce(iLayer) * iden_ice ) * (lambda_ice-lambda_air) * iden_ice * dVolFracIce_dTk
-         end select  ! option for the thermal conductivity of snow
+          call tcond_snow(nodeVolFracIce(iLayer)*iden_ice,  & ! input: snow density (kg m-3)
+                          mLayerThermalC(iLayer),             & ! output: thermal conductivity (W m-1 K-1)
+                          err,cmessage)                         ! output: error control
+          if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
+
+          select case(ixThCondSnow)
+            case(Yen1965)
+              dThermalC_dWat(iLayer) = 2._rkind * 3.217d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dWat
+              dThermalC_dNrg(iLayer) = 2._rkind * 3.217d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dTk
+            case(Mellor1977)
+              dThermalC_dWat(iLayer) = 2._rkind * 2.576d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dWat
+              dThermalC_dNrg(iLayer) = 2._rkind * 2.576d-6 * nodeVolFracIce(iLayer) * iden_ice**2._rkind * dVolFracIce_dTk
+            case(Jordan1991)
+              dThermalC_dWat(iLayer) = ( 7.75d-5 + 2._rkind * 1.105d-6 * nodeVolFracIce(iLayer) * iden_ice ) * (lambda_ice-lambda_air) * iden_ice * dVolFracIce_dWat
+              dThermalC_dNrg(iLayer) = ( 7.75d-5 + 2._rkind * 1.105d-6 * nodeVolFracIce(iLayer) * iden_ice ) * (lambda_ice-lambda_air) * iden_ice * dVolFracIce_dTk
+          end select  ! option for the thermal conductivity of snow
         end if
-    
-       ! * error check
-       case default; err=20; message=trim(message)//'unable to identify type of layer (snow or soil) to compute thermal conductivity'; return
-    
-      end select
-      !print*, 'iLayer, mLayerThermalC(iLayer) = ', iLayer, mLayerThermalC(iLayer)
-    
-     end do  ! looping through layers
-     !pause
-    
-     ! *****
-     ! * compute the thermal conductivity of snow at the interface of each layer...
-     ! ****************************************************************************
-     if (ixLayerDesired==0) then
-      ! special case of hansson
-      if(ixThCondSoil==hanssonVZJ)then
-       iLayerThermalC = 28._rkind*(0.5_rkind*(node_iHeight(ixLower) - node_iHeight(ixUpper))) ! these are indices 1,0 since was passed with 0:1
-       dThermalC_dHydStateBelow = 0._rkind
-       dThermalC_dNrgStateBelow = 0._rkind
-      else
-       iLayerThermalC = mLayerThermalC(ixUpper) ! index was passed with 1:1
-       dThermalC_dHydStateBelow = dThermalC_dWat(ixUpper)
-       dThermalC_dNrgStateBelow = dThermalC_dNrg(ixUpper)
-      end if
-      dThermalC_dHydStateAbove = realMissing
-      dThermalC_dNrgStateAbove = realMissing
-     else if (ixLayerDesired==nLayers ) then
-      ! assume the thermal conductivity at the domain boundaries is equal to the thermal conductivity of the layer
-      iLayerThermalC = mLayerThermalC(ixLower) ! index was passed with iLayers:iLayers
-      dThermalC_dHydStateAbove = dThermalC_dWat(ixLower)
-      dThermalC_dNrgStateAbove = dThermalC_dNrg(ixLower)
-      dThermalC_dHydStateBelow = realMissing
-      dThermalC_dNrgStateBelow = realMissing
-     else
-      ! get temporary variables
-      TCn = mLayerThermalC(ixUpper)    ! thermal conductivity below the layer interface (W m-1 K-1)
-      TCp = mLayerThermalC(ixLower)  ! thermal conductivity above the layer interface (W m-1 K-1)
-      zdn = node_iHeight(ixUpper)   - nodeHeight(ixUpper) ! height difference between interface and lower value (m)
-      zdp = nodeHeight(ixLower) - node_iHeight(ixUpper) ! height difference between interface and upper value (m)
-      den = TCn*zdp + TCp*zdn  ! denominator
-      ! compute thermal conductivity
-      if(TCn+TCp > epsilon(TCn))then
-       iLayerThermalC = (TCn*TCp*(zdn + zdp)) / den
-       dThermalC_dHydStateBelow = ( TCn*(zdn + zdp) - iLayerThermalC*zdn ) / den * dThermalC_dWat(ixLower)
-       dThermalC_dHydStateAbove = ( TCp*(zdn + zdp) - iLayerThermalC*zdp ) / den * dThermalC_dWat(ixUpper)
-       dThermalC_dNrgStateBelow = ( TCn*(zdn + zdp) - iLayerThermalC*zdn ) / den * dThermalC_dNrg(ixLower)
-       dThermalC_dNrgStateAbove = ( TCp*(zdn + zdp) - iLayerThermalC*zdp ) / den * dThermalC_dNrg(ixUpper)
-      else
-       iLayerThermalC = (TCn*zdn +  TCp*zdp) / (zdn + zdp)
-       dThermalC_dHydStateBelow = zdp / (zdn + zdp) * dThermalC_dWat(ixLower)
-       dThermalC_dHydStateAbove = zdn / (zdn + zdp) * dThermalC_dWat(ixUpper)
-       dThermalC_dNrgStateBelow = zdp / (zdn + zdp) * dThermalC_dNrg(ixLower)
-       dThermalC_dNrgStateAbove = zdn / (zdn + zdp) * dThermalC_dNrg(ixUpper)
-      end if
-      !write(*,'(a,1x,i4,1x,10(f9.3,1x))') 'iLayer, TCn, TCp, zdn, zdp, iLayerThermalC(iLayer) = ', iLayer, TCn, TCp, zdn, zdp, iLayerThermalC(iLayer)
-     endif
-    
-     end subroutine iLayerThermalConduct
-    
-    
-    
-    end module ssdNrgFlux_module
-    
-    
\ No newline at end of file
+
+      ! * error check
+      case default; err=20; message=trim(message)//'unable to identify type of layer (snow or soil) to compute thermal conductivity'; return
+
+    end select
+
+  end do  ! looping through layers
+
+  ! *****
+  ! * compute the thermal conductivity of snow at the interface of each layer...
+  ! ****************************************************************************
+  if (ixLayerDesired==0) then
+    ! special case of hansson
+    if(ixThCondSoil==hanssonVZJ)then
+      iLayerThermalC = 28._rkind*(0.5_rkind*(node_iHeight(ixLower) - node_iHeight(ixUpper))) ! these are indices 1,0 since was passed with 0:1
+      dThermalC_dHydStateBelow = 0._rkind
+      dThermalC_dNrgStateBelow = 0._rkind
+    else
+      iLayerThermalC = mLayerThermalC(ixUpper) ! index was passed with 1:1
+      dThermalC_dHydStateBelow = dThermalC_dWat(ixUpper)
+      dThermalC_dNrgStateBelow = dThermalC_dNrg(ixUpper)
+    end if
+    dThermalC_dHydStateAbove = realMissing
+    dThermalC_dNrgStateAbove = realMissing
+  else if (ixLayerDesired==nLayers ) then
+    ! assume the thermal conductivity at the domain boundaries is equal to the thermal conductivity of the layer
+    iLayerThermalC = mLayerThermalC(ixLower) ! index was passed with iLayers:iLayers
+    dThermalC_dHydStateAbove = dThermalC_dWat(ixLower)
+    dThermalC_dNrgStateAbove = dThermalC_dNrg(ixLower)
+    dThermalC_dHydStateBelow = realMissing
+    dThermalC_dNrgStateBelow = realMissing
+  else
+    ! get temporary variables
+    TCn = mLayerThermalC(ixUpper)    ! thermal conductivity below the layer interface (W m-1 K-1)
+    TCp = mLayerThermalC(ixLower)  ! thermal conductivity above the layer interface (W m-1 K-1)
+    zdn = node_iHeight(ixUpper)   - nodeHeight(ixUpper) ! height difference between interface and lower value (m)
+    zdp = nodeHeight(ixLower) - node_iHeight(ixUpper) ! height difference between interface and upper value (m)
+    den = TCn*zdp + TCp*zdn  ! denominator
+    ! compute thermal conductivity
+    if(TCn+TCp > epsilon(TCn))then
+      iLayerThermalC = (TCn*TCp*(zdn + zdp)) / den
+      dThermalC_dHydStateBelow = ( TCn*(zdn + zdp) - iLayerThermalC*zdn ) / den * dThermalC_dWat(ixLower)
+      dThermalC_dHydStateAbove = ( TCp*(zdn + zdp) - iLayerThermalC*zdp ) / den * dThermalC_dWat(ixUpper)
+      dThermalC_dNrgStateBelow = ( TCn*(zdn + zdp) - iLayerThermalC*zdn ) / den * dThermalC_dNrg(ixLower)
+      dThermalC_dNrgStateAbove = ( TCp*(zdn + zdp) - iLayerThermalC*zdp ) / den * dThermalC_dNrg(ixUpper)
+    else
+      iLayerThermalC = (TCn*zdn +  TCp*zdp) / (zdn + zdp)
+      dThermalC_dHydStateBelow = zdp / (zdn + zdp) * dThermalC_dWat(ixLower)
+      dThermalC_dHydStateAbove = zdn / (zdn + zdp) * dThermalC_dWat(ixUpper)
+      dThermalC_dNrgStateBelow = zdp / (zdn + zdp) * dThermalC_dNrg(ixLower)
+      dThermalC_dNrgStateAbove = zdn / (zdn + zdp) * dThermalC_dNrg(ixUpper)
+    end if
+  endif
+
+end subroutine iLayerThermalConduct
+
+
+
+end module ssdNrgFlux_module
+
diff --git a/build/source/engine/vegLiqFlux.f90 b/build/source/engine/vegLiqFlux.f90
index 44fe6f69578735faa441346b02176b47789b0fb0..78e0ab758ec79bce734e2527e2829fe82c29e62b 100755
--- a/build/source/engine/vegLiqFlux.f90
+++ b/build/source/engine/vegLiqFlux.f90
@@ -24,8 +24,8 @@ module vegLiqFlux_module
 USE nrtype
 
 ! data types
-USE data_types,only:var_d           ! x%var(:)       (dp)
-USE data_types,only:var_dlength     ! x%var(:)%dat   (dp)
+USE data_types,only:var_d           ! x%var(:)       (rkind)
+USE data_types,only:var_dlength     ! x%var(:)%dat   (rkind)
 
 ! named variables
 USE var_lookup,only:iLookPARAM,iLookDIAG ! named variables for structure elements
@@ -34,7 +34,7 @@ USE var_lookup,only:iLookPARAM,iLookDIAG ! named variables for structure element
 USE globalData,only:model_decisions      ! model decision structure
 USE var_lookup,only:iLookDECISIONS       ! named variables for elements of the decision structure
 
-! decisions on canopy interception parameterization 
+! decisions on canopy interception parameterization
 USE mDecisions_module,only:         &
                       unDefined,    & ! original model (no flexibility in canopy interception): 100% of rainfall is intercepted by the vegetation canopy
                       sparseCanopy, & ! fraction of rainfall that never hits the canopy (throughfall); drainage above threshold
@@ -47,106 +47,103 @@ public::vegLiqFlux
 contains
 
 
- ! ************************************************************************************************
- ! public subroutine vegLiqFlux: compute water balance for the vegetation canopy
- ! ************************************************************************************************
- subroutine vegLiqFlux(&
-                       ! input
-                       computeVegFlux,               & ! intent(in): flag to denote if computing energy flux over vegetation
-                       scalarCanopyLiqTrial,         & ! intent(in): trial mass of liquid water on the vegetation canopy at the current iteration (kg m-2)
-                       scalarRainfall,               & ! intent(in): rainfall rate (kg m-2 s-1)
-                       ! input-output: data structures
-                       mpar_data,                    & ! intent(in): model parameters
-                       diag_data,                    & ! intent(in): local HRU model diagnostic variables
-                       ! output
-                       scalarThroughfallRain,        & ! intent(out): rain that reaches the ground without ever touching the canopy (kg m-2 s-1)
-                       scalarCanopyLiqDrainage,      & ! intent(out): drainage of liquid water from the vegetation canopy (kg m-2 s-1)
-                       scalarThroughfallRainDeriv,   & ! intent(out): derivative in throughfall w.r.t. canopy liquid water (s-1)
-                       scalarCanopyLiqDrainageDeriv, & ! intent(out): derivative in canopy drainage w.r.t. canopy liquid water (s-1)
-                       err,message)                    ! intent(out): error control
- implicit none
- ! input
- logical(lgt),intent(in)         :: computeVegFlux               ! flag to indicate if we are computing fluxes over vegetation (.false. means veg is buried with snow)
- real(dp),intent(in)             :: scalarCanopyLiqTrial         ! trial mass of liquid water on the vegetation canopy at the current iteration (kg m-2)
- real(dp),intent(in)             :: scalarRainfall               ! rainfall (kg m-2 s-1)
- ! input-output: data structures
- type(var_dlength),intent(in)    :: mpar_data                    ! model parameters
- type(var_dlength),intent(inout) :: diag_data                    ! model diagnostic variables for the local basin
- ! output
- real(dp),intent(out)            :: scalarThroughfallRain        ! rain that reaches the ground without ever touching the canopy (kg m-2 s-1)
- real(dp),intent(out)            :: scalarCanopyLiqDrainage      ! drainage of liquid water from the vegetation canopy (kg m-2 s-1)
- real(dp),intent(out)            :: scalarThroughfallRainDeriv   ! derivative in throughfall w.r.t. canopy liquid water (s-1)
- real(dp),intent(out)            :: scalarCanopyLiqDrainageDeriv ! derivative in canopy drainage w.r.t. canopy liquid water (s-1)
- integer(i4b),intent(out)        :: err                          ! error code
- character(*),intent(out)        :: message                      ! error message
- ! ------------------------------------------------------------------------------------------------------------------------------------------------------
- ! make association of local variables with information in the data structures
- associate(&
-  ixCanopyInterception       => model_decisions(iLookDECISIONS%cIntercept)%iDecision, & ! intent(in): index defining choice of parameterization for canopy interception
-  scalarCanopyLiqMax         => diag_data%var(iLookDIAG%scalarCanopyLiqMax)%dat(1),   & ! intent(in): maximum storage before canopy drainage begins (kg m-2 s-1)
-  scalarThroughfallScaleRain => mpar_data%var(iLookPARAM%throughfallScaleRain)%dat(1),& ! intent(in): fraction of rain that hits the ground without touching the canopy (-)
-  scalarCanopyDrainageCoeff  => mpar_data%var(iLookPARAM%canopyDrainageCoeff)%dat(1)  & ! intent(in): canopy drainage coefficient (s-1)
- ) ! associating local variables with information in the data structures
- ! ------------------------------------------------------------------------------------------------------------------------------------------------------
- ! initialize error control
- err=0; message="vegLiqFlux/"
-
- ! set throughfall to inputs if vegetation is completely buried with snow
- if(.not.computeVegFlux)then
-  scalarThroughfallRain        = scalarRainfall
-  scalarCanopyLiqDrainage      = 0._dp
-  scalarThroughfallRainDeriv   = 0._dp
-  scalarCanopyLiqDrainageDeriv = 0._dp
-  return
- end if
-
- ! compute throughfall
- select case(ixCanopyInterception)
-
-  ! original model (no flexibility in canopy interception): 100% of rainfall is intercepted by the vegetation canopy
-  ! NOTE: this could be done with scalarThroughfallScaleRain=0, though requires setting scalarThroughfallScaleRain in all test cases
-  case(unDefined)
-   scalarThroughfallRain      = 0._dp
-   scalarThroughfallRainDeriv = 0._dp
-
-  ! fraction of rainfall hits the ground without ever touching the canopy
-  case(sparseCanopy)
-   scalarThroughfallRain      = scalarThroughfallScaleRain*scalarRainfall
-   scalarThroughfallRainDeriv = 0._dp
-
-  ! throughfall a function of canopy storage
-  case(storageFunc)
-
-   ! throughfall during wetting-up phase
-   if(scalarCanopyLiqTrial < scalarCanopyLiqMax)then
-    scalarThroughfallRain      = scalarRainfall*(scalarCanopyLiqTrial/scalarCanopyLiqMax)
-    scalarThroughfallRainDeriv = scalarRainfall/scalarCanopyLiqMax
-
-   ! all rain falls through the canopy when the canopy is at capacity
-   else
-    scalarThroughfallRain      = scalarRainfall
-    scalarThroughfallRainDeriv = 0._dp
-   end if
-
-  case default; err=20; message=trim(message)//'unable to identify option for canopy interception'; return
-
- end select ! (option for canopy interception)
-
- ! compute canopy drainage
- if(scalarCanopyLiqTrial > scalarCanopyLiqMax)then
-  scalarCanopyLiqDrainage       = scalarCanopyDrainageCoeff*(scalarCanopyLiqTrial - scalarCanopyLiqMax)
-  scalarCanopyLiqDrainageDeriv  = scalarCanopyDrainageCoeff
- else
-  scalarCanopyLiqDrainage       = 0._dp
-  scalarCanopyLiqDrainageDeriv  = 0._dp
- end if
-
- !write(*,'(a,1x,f25.15)') 'scalarCanopyLiqDrainage = ', scalarCanopyLiqDrainage
-
- ! end association of local variables with information in the data structures
- end associate
-
- end subroutine vegLiqFlux
-
+! ************************************************************************************************
+! public subroutine vegLiqFlux: compute water balance for the vegetation canopy
+! ************************************************************************************************
+subroutine vegLiqFlux(&
+                    ! input
+                    computeVegFlux,               & ! intent(in): flag to denote if computing energy flux over vegetation
+                    scalarCanopyLiqTrial,         & ! intent(in): trial mass of liquid water on the vegetation canopy at the current iteration (kg m-2)
+                    scalarRainfall,               & ! intent(in): rainfall rate (kg m-2 s-1)
+                    ! input-output: data structures
+                    mpar_data,                    & ! intent(in): model parameters
+                    diag_data,                    & ! intent(in): local HRU model diagnostic variables
+                    ! output
+                    scalarThroughfallRain,        & ! intent(out): rain that reaches the ground without ever touching the canopy (kg m-2 s-1)
+                    scalarCanopyLiqDrainage,      & ! intent(out): drainage of liquid water from the vegetation canopy (kg m-2 s-1)
+                    scalarThroughfallRainDeriv,   & ! intent(out): derivative in throughfall w.r.t. canopy liquid water (s-1)
+                    scalarCanopyLiqDrainageDeriv, & ! intent(out): derivative in canopy drainage w.r.t. canopy liquid water (s-1)
+                    err,message)                    ! intent(out): error control
+  implicit none
+  ! input
+  logical(lgt),intent(in)         :: computeVegFlux               ! flag to indicate if we are computing fluxes over vegetation (.false. means veg is buried with snow)
+  real(rkind),intent(in)             :: scalarCanopyLiqTrial         ! trial mass of liquid water on the vegetation canopy at the current iteration (kg m-2)
+  real(rkind),intent(in)             :: scalarRainfall               ! rainfall (kg m-2 s-1)
+  ! input-output: data structures
+  type(var_dlength),intent(in)    :: mpar_data                    ! model parameters
+  type(var_dlength),intent(inout) :: diag_data                    ! model diagnostic variables for the local basin
+  ! output
+  real(rkind),intent(out)            :: scalarThroughfallRain        ! rain that reaches the ground without ever touching the canopy (kg m-2 s-1)
+  real(rkind),intent(out)            :: scalarCanopyLiqDrainage      ! drainage of liquid water from the vegetation canopy (kg m-2 s-1)
+  real(rkind),intent(out)            :: scalarThroughfallRainDeriv   ! derivative in throughfall w.r.t. canopy liquid water (s-1)
+  real(rkind),intent(out)            :: scalarCanopyLiqDrainageDeriv ! derivative in canopy drainage w.r.t. canopy liquid water (s-1)
+  integer(i4b),intent(out)        :: err                          ! error code
+  character(*),intent(out)        :: message                      ! error message
+  ! ------------------------------------------------------------------------------------------------------------------------------------------------------
+  ! make association of local variables with information in the data structures
+  associate(&
+    ixCanopyInterception       => model_decisions(iLookDECISIONS%cIntercept)%iDecision, & ! intent(in): index defining choice of parameterization for canopy interception
+    scalarCanopyLiqMax         => diag_data%var(iLookDIAG%scalarCanopyLiqMax)%dat(1),   & ! intent(in): maximum storage before canopy drainage begins (kg m-2 s-1)
+    scalarThroughfallScaleRain => mpar_data%var(iLookPARAM%throughfallScaleRain)%dat(1),& ! intent(in): fraction of rain that hits the ground without touching the canopy (-)
+    scalarCanopyDrainageCoeff  => mpar_data%var(iLookPARAM%canopyDrainageCoeff)%dat(1)  & ! intent(in): canopy drainage coefficient (s-1)
+    ) ! associating local variables with information in the data structures
+    ! ------------------------------------------------------------------------------------------------------------------------------------------------------
+    ! initialize error control
+    err=0; message="vegLiqFlux/"
+
+    ! set throughfall to inputs if vegetation is completely buried with snow
+    if(.not.computeVegFlux)then
+      scalarThroughfallRain        = scalarRainfall
+      scalarCanopyLiqDrainage      = 0._rkind
+      scalarThroughfallRainDeriv   = 0._rkind
+      scalarCanopyLiqDrainageDeriv = 0._rkind
+      return
+    end if
+
+    ! compute throughfall
+    select case(ixCanopyInterception)
+
+      ! original model (no flexibility in canopy interception): 100% of rainfall is intercepted by the vegetation canopy
+      ! NOTE: this could be done with scalarThroughfallScaleRain=0, though requires setting scalarThroughfallScaleRain in all test cases
+      case(unDefined)
+        scalarThroughfallRain      = 0._rkind
+        scalarThroughfallRainDeriv = 0._rkind
+
+      ! fraction of rainfall hits the ground without ever touching the canopy
+      case(sparseCanopy)
+        scalarThroughfallRain      = scalarThroughfallScaleRain*scalarRainfall
+        scalarThroughfallRainDeriv = 0._rkind
+
+      ! throughfall a function of canopy storage
+      case(storageFunc)
+
+        ! throughfall during wetting-up phase
+        if(scalarCanopyLiqTrial < scalarCanopyLiqMax)then
+          scalarThroughfallRain      = scalarRainfall*(scalarCanopyLiqTrial/scalarCanopyLiqMax)
+          scalarThroughfallRainDeriv = scalarRainfall/scalarCanopyLiqMax
+
+        ! all rain falls through the canopy when the canopy is at capacity
+        else
+          scalarThroughfallRain      = scalarRainfall
+          scalarThroughfallRainDeriv = 0._rkind
+        end if
+
+      case default; err=20; message=trim(message)//'unable to identify option for canopy interception'; return
+
+    end select ! (option for canopy interception)
+
+    ! compute canopy drainage
+    if(scalarCanopyLiqTrial > scalarCanopyLiqMax)then
+      scalarCanopyLiqDrainage       = scalarCanopyDrainageCoeff*(scalarCanopyLiqTrial - scalarCanopyLiqMax)
+      scalarCanopyLiqDrainageDeriv  = scalarCanopyDrainageCoeff
+    else
+      scalarCanopyLiqDrainage       = 0._rkind
+      scalarCanopyLiqDrainageDeriv  = 0._rkind
+    end if
+
+  ! end association of local variables with information in the data structures
+  end associate
+
+end subroutine vegLiqFlux
 
 end module vegLiqFlux_module