diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm
index 083ce3b667..3f158d6275 100755
--- a/bld/CLMBuildNamelist.pm
+++ b/bld/CLMBuildNamelist.pm
@@ -5405,6 +5405,7 @@ sub write_output_files {
soil_resis_inparm bgc_shared canopyfluxes_inparm aerosol
clmu_inparm clm_soilstate_inparm clm_nitrogen clm_snowhydrology_inparm hillslope_hydrology_inparm hillslope_properties_inparm
cnprecision_inparm clm_glacier_behavior crop_inparm irrigation_inparm
+ debug
surfacealbedo_inparm water_tracers_inparm tillage_inparm);
#@groups = qw(clm_inparm clm_canopyhydrology_inparm clm_soilhydrology_inparm
diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml
index ef5e6919db..8eec8e0fe1 100644
--- a/bld/namelist_files/namelist_defaults_ctsm.xml
+++ b/bld/namelist_files/namelist_defaults_ctsm.xml
@@ -2797,4 +2797,13 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2
.false.
0.26d00
+
+
+
+
+-999
+-999
+-999
+-999
+
diff --git a/bld/namelist_files/namelist_definition.xsl b/bld/namelist_files/namelist_definition.xsl
index 7917cc262f..2719d1a4ca 100644
--- a/bld/namelist_files/namelist_definition.xsl
+++ b/bld/namelist_files/namelist_definition.xsl
@@ -185,6 +185,19 @@
+
+ CLM Debugging
+
+ | Name |
+ Type |
+ Description |
+
+
+ | Valid values |
+
+
+
+
diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml
index 179704e518..e1936f6ac4 100644
--- a/bld/namelist_files/namelist_definition_ctsm.xml
+++ b/bld/namelist_files/namelist_definition_ctsm.xml
@@ -3267,4 +3267,28 @@ Toggle to use original (Graham et al. 2021) tillage logic, with bug for seasons
Maximum depth to till soil (m). Default 0.26; original (Graham et al., 2021) value was unintentionally 0.32.
+
+
+
+
+
+Global index of patch to debug.
+
+
+
+Global index of column to debug.
+
+
+
+Global index of landunit to debug.
+
+
+
+Global index of gridcell to debug.
+
+
diff --git a/ccs_config b/ccs_config
index 39683243b4..7020eb9a16 160000
--- a/ccs_config
+++ b/ccs_config
@@ -1 +1 @@
-Subproject commit 39683243b4e8e5b4576fd1b828c3ec4c9e15bc6b
+Subproject commit 7020eb9a16a2c1cde7b7fbb588e08dbb7b1ce85c
diff --git a/cime b/cime
index 51cfec52f2..d5e1e034b6 160000
--- a/cime
+++ b/cime
@@ -1 +1 @@
-Subproject commit 51cfec52f297eb4d30dd34548bf4b69b9ab72d1e
+Subproject commit d5e1e034b6b8568f02bcae1091a689212f86b382
diff --git a/components/cmeps b/components/cmeps
index ebcfeafa52..480bfc1502 160000
--- a/components/cmeps
+++ b/components/cmeps
@@ -1 +1 @@
-Subproject commit ebcfeafa524f29181058f64809d165a58733236e
+Subproject commit 480bfc1502d42ae1decdc56c731f0dd80fbf9139
diff --git a/libraries/parallelio b/libraries/parallelio
index 39e5584411..1d516b8276 160000
--- a/libraries/parallelio
+++ b/libraries/parallelio
@@ -1 +1 @@
-Subproject commit 39e558441197b0b98f69b989708b3df22a5d7438
+Subproject commit 1d516b82768ef9d2cade524724c38ab63fbe08e4
diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90
index 4530fda860..65c88e75fc 100644
--- a/src/main/clm_initializeMod.F90
+++ b/src/main/clm_initializeMod.F90
@@ -183,6 +183,7 @@ subroutine initialize2(ni,nj, currtime)
use FATESFireFactoryMod , only : scalar_lightning
use dynFATESLandUseChangeMod , only : dynFatesLandUseInit
use HillslopeHydrologyMod , only : InitHillslope
+ use debugMod , only : debugMod_init
!
! !ARGUMENTS
integer, intent(in) :: ni, nj ! global grid sizes
@@ -309,6 +310,9 @@ subroutine initialize2(ni,nj, currtime)
call decompInit_glcp(ni, nj, glc_behavior)
call t_stopf('clm_decompInit_glcp')
+ ! Initialize debugMod early so we can use its functions as soon as possible
+ call debugMod_init()
+
if (use_hillslope) then
! Initialize hillslope properties
call InitHillslope(bounds_proc, hillslope_file)
diff --git a/src/main/debugMod.F90 b/src/main/debugMod.F90
new file mode 100644
index 0000000000..330b183121
--- /dev/null
+++ b/src/main/debugMod.F90
@@ -0,0 +1,254 @@
+module debugMod
+
+ !-----------------------------------------------------------------------
+ ! !DESCRIPTION:
+ ! Provides a place to define gridcells, landunits, columns, and/or patches that we want debug
+ ! output for, as well as functions for checking whether a given g/l/c/p is being debugged.
+ !
+ ! !USES:
+#include "shr_assert.h"
+ use abortutils , only : endrun
+ use decompMod , only : subgrid_level_gridcell, subgrid_level_landunit
+ use decompMod , only : subgrid_level_column, subgrid_level_patch
+ use decompMod , only : get_global_index
+ !
+ ! !PUBLIC TYPES:
+ implicit none
+ private
+ !
+ ! !PUBLIC MEMBER SUBROUTINES AND FUNCTIONS:
+ public :: debugMod_init
+ public :: do_debug_patch
+ public :: do_debug_column
+ public :: do_debug_landunit
+ public :: do_debug_gridcell
+ !
+ ! !PRIVATE MEMBER DATA:
+
+ ! Global indices for objects to debug.
+ integer :: debug_p
+ integer :: debug_c
+ integer :: debug_l
+ integer :: debug_g
+
+ character(len=*), parameter, private :: sourcefile = __FILE__
+ !-----------------------------------------------------------------------
+
+contains
+
+ !-----------------------------------------------------------------------
+ subroutine debugMod_init()
+ !
+ ! Handle namelist variables
+ !
+ ! !USES:
+ use clm_varctl , only : iulog
+ use spmdMod , only : masterproc, mpicom
+ use controlMod , only : NLFilename
+ use clm_nlUtilsMod , only : find_nlgroup_name
+ use shr_mpi_mod , only : shr_mpi_bcast
+ !
+ ! !LOCAL VARIABLES:
+ integer :: nu_nml ! unit for namelist file
+ integer :: nml_error ! namelist i/o error flag
+ integer :: nml_debug
+ !-----------------------------------------------------------------------
+
+ namelist /debug/ &
+ debug_p, &
+ debug_c, &
+ debug_l, &
+ debug_g
+
+ ! Default namelist variable values
+ debug_p = -999
+ debug_c = -999
+ debug_l = -999
+ debug_g = -999
+
+ ! Read namelist
+ if (masterproc) then
+ open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
+ call find_nlgroup_name(nu_nml, 'debug', status=nml_error)
+ if (nml_error == 0) then
+ read(nu_nml, nml=debug,iostat=nml_error)
+ if (nml_error /= 0) then
+ call endrun('ERROR reading debug namelist')
+ end if
+ else
+ call endrun('ERROR finding debug namelist')
+ end if
+ close(nu_nml)
+
+ ! Print values
+ write(iulog,*)
+ write(iulog,*) 'Debug settings:'
+ write(iulog, '(a,i8)') ' debug_p = ', debug_p
+ write(iulog, '(a,i8)') ' debug_c = ', debug_c
+ write(iulog, '(a,i8)') ' debug_l = ', debug_l
+ write(iulog, '(a,i8)') ' debug_g = ', debug_g
+ endif
+ call shr_mpi_bcast(debug_p, mpicom)
+ call shr_mpi_bcast(debug_c, mpicom)
+ call shr_mpi_bcast(debug_l, mpicom)
+ call shr_mpi_bcast(debug_g, mpicom)
+
+
+ end subroutine debugMod_init
+
+ !-----------------------------------------------------------------------
+ function do_debug_patch(i_local, i_global) result(do_debug)
+ !
+ ! !DESCRIPTION:
+ ! Return .true. if the given global patch index is the one we're debugging; .false. otherwise.
+ ! Provide only i_local or i_global.
+ !
+ ! !ARGUMENTS:
+ integer, optional :: i_local ! Local patch index
+ integer, optional :: i_global ! Global patch index
+ !
+ ! !RESULT:
+ logical :: do_debug
+ integer :: i ! Global patch index
+ !-----------------------------------------------------------------------
+
+ ! This makes it so that compilers should build this function as a simple boolean if we haven't
+ ! requested any patch to be debugged, which reduces performance cost in production runs.
+ if (debug_p < 1) then
+ do_debug = .false.
+ return
+ end if
+
+ if (present(i_global)) then
+ call shr_assert(.not. present(i_local), file=sourcefile, line=__LINE__)
+ call shr_assert(i_global >= 1, file=sourcefile, line=__LINE__)
+ i = i_global
+ else
+ call shr_assert(present(i_local), file=sourcefile, line=__LINE__)
+ i = get_global_index(subgrid_index=i_local, subgrid_level=subgrid_level_patch, &
+ donot_abort_on_badindex=.false.)
+ end if
+
+ do_debug = i == debug_p
+ return
+
+ end function do_debug_patch
+
+ !-----------------------------------------------------------------------
+ function do_debug_column(i_local, i_global) result(do_debug)
+ !
+ ! !DESCRIPTION:
+ ! Return .true. if the given global column index is the one we're debugging; .false. otherwise.
+ ! Provide only i_local or i_global.
+ !
+ ! !ARGUMENTS:
+ integer, optional :: i_local ! Local column index
+ integer, optional :: i_global ! Global column index
+ !
+ ! !RESULT:
+ logical :: do_debug
+ integer :: i ! Global column index
+ !-----------------------------------------------------------------------
+
+ ! This makes it so that compilers should build this function as a simple boolean if we haven't
+ ! requested any column to be debugged, which reduces performance cost in production runs.
+ if (debug_c < 1) then
+ do_debug = .false.
+ return
+ end if
+
+ if (present(i_global)) then
+ call shr_assert(.not. present(i_local), file=sourcefile, line=__LINE__)
+ call shr_assert(i_global >= 1, file=sourcefile, line=__LINE__)
+ i = i_global
+ else
+ call shr_assert(present(i_local), file=sourcefile, line=__LINE__)
+ i = get_global_index(subgrid_index=i_local, subgrid_level=subgrid_level_column, &
+ donot_abort_on_badindex=.false.)
+ end if
+
+ do_debug = i == debug_c
+ return
+
+ end function do_debug_column
+
+ !-----------------------------------------------------------------------
+ function do_debug_landunit(i_local, i_global) result(do_debug)
+ !
+ ! !DESCRIPTION:
+ ! Return .true. if the given global landunit index is the one we're debugging; .false. otherwise.
+ ! Provide only i_local or i_global.
+ !
+ ! !ARGUMENTS:
+ integer, optional :: i_local ! Local landunit index
+ integer, optional :: i_global ! Global landunit index
+ !
+ ! !RESULT:
+ logical :: do_debug
+ integer :: i ! Global landunit index
+ !-----------------------------------------------------------------------
+
+ ! This makes it so that compilers should build this function as a simple boolean if we haven't
+ ! requested any landunit to be debugged, which reduces performance cost in production runs.
+ if (debug_l < 1) then
+ do_debug = .false.
+ return
+ end if
+
+ if (present(i_global)) then
+ call shr_assert(.not. present(i_local), file=sourcefile, line=__LINE__)
+ call shr_assert(i_global >= 1, file=sourcefile, line=__LINE__)
+ i = i_global
+ else
+ call shr_assert(present(i_local), file=sourcefile, line=__LINE__)
+ i = get_global_index(subgrid_index=i_local, subgrid_level=subgrid_level_landunit, &
+ donot_abort_on_badindex=.false.)
+ end if
+
+ do_debug = i == debug_l
+ return
+
+ end function do_debug_landunit
+
+ !-----------------------------------------------------------------------
+ function do_debug_gridcell(i_local, i_global) result(do_debug)
+ !
+ ! !DESCRIPTION:
+ ! Return .true. if the given global gridcell index is the one we're debugging; .false. otherwise.
+ ! Provide only i_local or i_global.
+ !
+ ! !ARGUMENTS:
+ integer, optional :: i_local ! Local gridcell index
+ integer, optional :: i_global ! Global gridcell index
+ !
+ ! !RESULT:
+ logical :: do_debug
+ integer :: i ! Global gridcell index
+ !-----------------------------------------------------------------------
+
+ ! This makes it so that compilers should build this function as a simple boolean if we haven't
+ ! requested any gridcell to be debugged, which reduces performance cost in production runs.
+ if (debug_g < 1) then
+ do_debug = .false.
+ return
+ end if
+
+ if (present(i_global)) then
+ call shr_assert(.not. present(i_local), file=sourcefile, line=__LINE__)
+ call shr_assert(i_global >= 1, file=sourcefile, line=__LINE__)
+ i = i_global
+ else
+ call shr_assert(present(i_local), file=sourcefile, line=__LINE__)
+ i = get_global_index(subgrid_index=i_local, subgrid_level=subgrid_level_gridcell, &
+ donot_abort_on_badindex=.false.)
+ end if
+
+ do_debug = i == debug_g
+ return
+
+ end function do_debug_gridcell
+
+end module debugMod
+
+
+