From cee8882269f63bb630a84ad536c195f4c84cf1bd Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Tue, 3 Mar 2026 13:52:39 -0700 Subject: [PATCH 1/4] Bring in changes from ESCOMP/CAM#1492 --- .config_files.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.config_files.xml b/.config_files.xml index b7ce80c59..301cfa872 100644 --- a/.config_files.xml +++ b/.config_files.xml @@ -5,21 +5,21 @@ char unset $SRCROOT - $CIMEROOT/src/components/data_comps/dlnd - $CIMEROOT/src/components/stub_comps/slnd - $CIMEROOT/src/components/xcpl_comps/xlnd + $SRCROOT/components/cdeps/datm + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/satm + $SRCROOT/components/cmeps/med_test_comps/xatm case_comps env_case.xml From 0f60d3aeeecdcffbcebd314a737adb27d6152626 Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Mon, 9 Mar 2026 13:22:16 -0400 Subject: [PATCH 2/4] Verbose physics data check: print out all checked variables --- src/data/write_init_files.py | 10 +- src/physics/utils/physics_data.F90 | 228 ++++++++++++++++++++++++++++- 2 files changed, 234 insertions(+), 4 deletions(-) diff --git a/src/data/write_init_files.py b/src/data/write_init_files.py index ce8ffb299..3bbf1569a 100644 --- a/src/data/write_init_files.py +++ b/src/data/write_init_files.py @@ -1288,7 +1288,8 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, ["shr_kind_mod", ["SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX"]], ["physics_data", ["check_field", "find_input_name_idx", "no_exist_idx", "init_mark_idx", - "prot_no_init_idx", "const_idx"]], + "prot_no_init_idx", "const_idx", + "flush_check_field_verbose"]], ["cam_ccpp_cap", ["ccpp_physics_suite_variables", "cam_advected_constituents_array", "cam_model_const_properties"]], @@ -1501,6 +1502,11 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("end if", 3) outfile.write("end do", 2) + # Flush any buffered verbose entries (printed after all diff entries): + outfile.comment("Flush verbose check_field entries (printed after diffs):", 2) + outfile.write("call flush_check_field_verbose()", 2) + outfile.blank_line() + # Close check file outfile.comment("Close check file:", 2) outfile.write("call cam_pio_closefile(file)", 2) @@ -1508,7 +1514,7 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("nullify(file)", 2) # Check if no differences were found - outfile.write("if (is_first) then", 2) + outfile.write("if (.not. overall_diff_found) then", 2) outfile.write("if (masterproc) then", 3) outfile.write("write(iulog,*) ''", 4) outfile.write("write(iulog,*) 'No differences found!'", 4) diff --git a/src/physics/utils/physics_data.F90 b/src/physics/utils/physics_data.F90 index c0997c90c..062a983c3 100644 --- a/src/physics/utils/physics_data.F90 +++ b/src/physics/utils/physics_data.F90 @@ -7,8 +7,9 @@ module physics_data public :: read_field public :: read_constituent_dimensioned_field public :: check_field + public :: flush_check_field_verbose - !Non-standard variable indices: + ! Non-standard variable indices: integer, public, parameter :: no_exist_idx = -1 integer, public, parameter :: init_mark_idx = -2 integer, public, parameter :: prot_no_init_idx = -3 @@ -30,6 +31,18 @@ module physics_data module procedure read_constituent_dimensioned_field_2d end interface read_constituent_dimensioned_field + ! Module-level storage for verbose check_field entries. + ! These are accumulated during check_field calls and flushed + ! at the end via flush_check_field_verbose, so that the verbose + ! "OK" list is printed after any diff entries. + integer, parameter :: max_verbose_entries = 1000 + integer, parameter :: verbose_name_len = 256 + integer, save :: num_verbose_entries = 0 + character(len=verbose_name_len), save :: verbose_stdnames(max_verbose_entries) + integer, save :: verbose_global_count(max_verbose_entries) + real(8), save :: verbose_avg_model(max_verbose_entries) + real(8), save :: verbose_avg_snapshot(max_verbose_entries) + !============================================================================== CONTAINS !============================================================================== @@ -638,7 +651,9 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & use cam_field_read, only: cam_read_field use mpi, only: mpi_maxloc, mpi_sum, mpi_status_size use mpi, only: mpi_2double_precision, mpi_integer + use mpi, only: mpi_double_precision use shr_infnan_mod, only: shr_infnan_isnan + use cam_logfile, only: debug_output, DEBUGOUT_INFO !Max possible length of variable name in file: use phys_vars_init_check, only: std_name_len @@ -674,6 +689,16 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & integer :: nan_count_gl ! Global count of NaNs logical :: has_nan ! Flag indicating NaN was found + ! Variables for verbose mode global averages + real(kind_phys) :: local_sum_model ! Local sum of model values + real(kind_phys) :: local_sum_snapshot ! Local sum of snapshot values + integer :: local_count ! Local count of valid (non-NaN) values + real(kind_phys) :: global_sum_model ! Global sum of model values + real(kind_phys) :: global_sum_snapshot! Global sum of snapshot values + integer :: global_count ! Global count of valid values + real(kind_phys) :: global_avg_model ! Global average of model state + real(kind_phys) :: global_avg_snapshot! Global average of snapshot + !Initialize output variables ierr = 0 allocate(buffer(size(current_value)), stat=ierr) @@ -698,6 +723,11 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & nan_count = 0 has_nan = .false. + ! Initialize verbose mode accumulators + local_sum_model = 0._kind_phys + local_sum_snapshot = 0._kind_phys + local_count = 0 + do col = 1, size(buffer) ! First, check if there are NaNs anywhere in the state if (shr_infnan_isnan(current_value(col))) then @@ -711,6 +741,11 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & max_diff_col = col end if else + ! Accumulate for global average (verbose mode) + local_sum_model = local_sum_model + current_value(col) + local_sum_snapshot = local_sum_snapshot + buffer(col) + local_count = local_count + 1 + ! Calculate actual diffs for non-NaN values: if (abs(current_value(col)) < min_relative_value) then !Calculate absolute difference: @@ -744,6 +779,23 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & MPI_2DOUBLE_PRECISION, & mpi_maxloc, mpicom, ierr) + ! Gather global averages for verbose mode + if (debug_output >= DEBUGOUT_INFO) then + call mpi_reduce(local_sum_model, global_sum_model, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_sum_snapshot, global_sum_snapshot, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_count, global_count, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) + + if (masterproc .and. global_count > 0) then + global_avg_model = global_sum_model / real(global_count, kind_phys) + global_avg_snapshot = global_sum_snapshot / real(global_count, kind_phys) + end if + end if + if (iam == int(max_diff_gl(2)) .and. .not. masterproc) then !The largest diff happened on this task, so the local max is !the global max. So send the local max value's dimension @@ -773,6 +825,13 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & is_first = .false. diff_found = .true. end if + ! Store verbose entry for later printing (after all diffs) + if ((debug_output >= DEBUGOUT_INFO) .and. & + diff_count_gl == 0 .and. global_count > 0) then + call store_verbose_entry(stdname, global_count, & + global_avg_model, & + global_avg_snapshot) + end if end if end if end if @@ -792,8 +851,10 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & use cam_field_read, only: cam_read_field use mpi, only: mpi_maxloc, mpi_sum, mpi_status_size use mpi, only: mpi_2double_precision, mpi_integer + use mpi, only: mpi_double_precision use vert_coord, only: pver, pverp use shr_infnan_mod, only: shr_infnan_isnan + use cam_logfile, only: debug_output, DEBUGOUT_INFO !Max possible length of variable name in file: use phys_vars_init_check, only: std_name_len @@ -834,6 +895,16 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & integer :: nan_count_gl ! Global count of NaNs logical :: has_nan ! Flag indicating NaN was found + ! Variables for verbose mode global averages + real(kind_phys) :: local_sum_model ! Local sum of model values + real(kind_phys) :: local_sum_snapshot ! Local sum of snapshot values + integer :: local_count ! Local count of valid (non-NaN) values + real(kind_phys) :: global_sum_model ! Global sum of model values + real(kind_phys) :: global_sum_snapshot! Global sum of snapshot values + integer :: global_count ! Global count of valid values + real(kind_phys) :: global_avg_model ! Global average of model state + real(kind_phys) :: global_avg_snapshot! Global average of snapshot + !Initialize output variables ierr = 0 allocate(buffer(size(current_value, 1), size(current_value, 2)), & @@ -868,6 +939,11 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & nan_count = 0 has_nan = .false. + ! Initialize verbose mode accumulators + local_sum_model = 0._kind_phys + local_sum_snapshot = 0._kind_phys + local_count = 0 + do lev = 1, num_levs do col = 1, size(buffer(:,lev)) ! First, check if there are NaNs anywhere in the state @@ -883,6 +959,11 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & max_diff_lev = lev end if else + ! Accumulate for global average (verbose mode) + local_sum_model = local_sum_model + current_value(col, lev) + local_sum_snapshot = local_sum_snapshot + buffer(col, lev) + local_count = local_count + 1 + ! Calculate actual diffs for non-NaN values: if (abs(current_value(col, lev)) < min_relative_value) then !Calculate absolute difference: @@ -918,6 +999,23 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & MPI_2DOUBLE_PRECISION, & mpi_maxloc, mpicom, ierr) + ! Gather global averages for verbose mode + if (debug_output >= DEBUGOUT_INFO) then + call mpi_reduce(local_sum_model, global_sum_model, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_sum_snapshot, global_sum_snapshot, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_count, global_count, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) + + if (masterproc .and. global_count > 0) then + global_avg_model = global_sum_model / real(global_count, kind_phys) + global_avg_snapshot = global_sum_snapshot / real(global_count, kind_phys) + end if + end if + if (iam == int(max_diff_gl(2)) .and. .not. masterproc) then !The largest diff happened on this task, so the local max is !the global max. So send the local max value's dimension @@ -955,6 +1053,13 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & is_first = .false. diff_found = .true. end if + ! Store verbose entry for later printing (after all diffs) + if ((debug_output >= DEBUGOUT_INFO) .and. & + diff_count_gl == 0 .and. global_count > 0) then + call store_verbose_entry(stdname, global_count, & + global_avg_model, & + global_avg_snapshot) + end if end if end if end if @@ -974,8 +1079,9 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & use cam_abortutils, only: endrun, check_allocate use cam_field_read, only: cam_read_field use mpi, only: mpi_maxloc, mpi_sum, mpi_status_size - use mpi, only: mpi_2double_precision, mpi_integer + use mpi, only: mpi_2double_precision, mpi_integer, mpi_double_precision use vert_coord, only: pver, pverp + use cam_logfile, only: debug_output, DEBUGOUT_INFO !Max possible length of variable name in file: use phys_vars_init_check, only: std_name_len @@ -1019,6 +1125,16 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & integer :: nan_count_gl logical :: has_nan + ! Variables for verbose mode global averages + real(kind_phys) :: local_sum_model ! Local sum of model values + real(kind_phys) :: local_sum_snapshot ! Local sum of snapshot values + integer :: local_count ! Local count of valid (non-NaN) values + real(kind_phys) :: global_sum_model ! Global sum of model values + real(kind_phys) :: global_sum_snapshot! Global sum of snapshot values + integer :: global_count ! Global count of valid values + real(kind_phys) :: global_avg_model ! Global average of model state + real(kind_phys) :: global_avg_snapshot! Global average of snapshot + !Initialize output variables ierr = 0 allocate(buffer(size(current_value, 1), size(current_value, 2), & @@ -1056,6 +1172,11 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & dim3_bnds=[1, num_levs], dim3_pos=2, & dim4_bnds=[1, size(buffer, 3)],log_output=.false.) if (var_found) then + ! Initialize verbose mode accumulators + local_sum_model = 0._kind_phys + local_sum_snapshot = 0._kind_phys + local_count = 0 + do extra_dim = 1, size(buffer, 3) do lev = 1, num_levs do col = 1, size(buffer(:,lev,extra_dim)) @@ -1074,6 +1195,11 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & max_diff_extra_dim = extra_dim end if else + ! Accumulate for global average (verbose mode) + local_sum_model = local_sum_model + current_value(col, lev, extra_dim) + local_sum_snapshot = local_sum_snapshot + buffer(col, lev, extra_dim) + local_count = local_count + 1 + if (abs(current_value(col, lev, extra_dim)) < min_relative_value) then ! Absolute difference diff = abs(current_value(col, lev, extra_dim) - & @@ -1114,6 +1240,23 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & MPI_2DOUBLE_PRECISION, & mpi_maxloc, mpicom, ierr) + ! Gather global averages for verbose mode + if (debug_output >= DEBUGOUT_INFO) then + call mpi_reduce(local_sum_model, global_sum_model, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_sum_snapshot, global_sum_snapshot, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_count, global_count, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) + + if (masterproc .and. global_count > 0) then + global_avg_model = global_sum_model / real(global_count, kind_phys) + global_avg_snapshot = global_sum_snapshot / real(global_count, kind_phys) + end if + end if + if (iam == int(max_diff_gl(2)) .and. .not. masterproc) then !The largest diff happened on this task, so the local max is !the global max. So send the local max value's dimension @@ -1158,6 +1301,14 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & is_first = .false. diff_found = .true. end if + + ! Store verbose entry for later printing (after all diffs) + if ((debug_output >= DEBUGOUT_INFO) .and. & + diff_count_gl == 0 .and. global_count > 0) then + call store_verbose_entry(stdname, global_count, & + global_avg_model, & + global_avg_snapshot) + end if end if end if end if @@ -1230,4 +1381,77 @@ subroutine write_check_field_entry(stdname, & end subroutine write_check_field_entry + subroutine store_verbose_entry(stdname, global_count, & + global_avg_model, global_avg_snapshot) + use ccpp_kinds, only: kind_phys + + !Dummy variables: + character(len=*), intent(in) :: stdname + integer, intent(in) :: global_count + real(kind_phys), intent(in) :: global_avg_model + real(kind_phys), intent(in) :: global_avg_snapshot + + if (num_verbose_entries < max_verbose_entries) then + num_verbose_entries = num_verbose_entries + 1 + verbose_stdnames(num_verbose_entries) = stdname + verbose_global_count(num_verbose_entries) = global_count + verbose_avg_model(num_verbose_entries) = global_avg_model + verbose_avg_snapshot(num_verbose_entries) = global_avg_snapshot + end if + + end subroutine store_verbose_entry + + subroutine flush_check_field_verbose() + ! + ! Writes all buffered verbose check_field entries to the log. + ! This should be called after all check_field calls are complete, + ! so that the verbose "OK" list appears after any diff entries. + ! + + use cam_logfile, only: iulog + use spmd_utils, only: masterproc + use shr_kind_mod, only: cs=>shr_kind_cs + + !Local variables: + character(len=cs) :: fmt_str + integer :: i, slen + integer, parameter :: indent_level = 50 + + if (num_verbose_entries == 0) return + if (.not. masterproc) return + + !Write verbose check_field log header: + write(iulog, *) '' + write(iulog, *) 'No differences found for all the variables below:' + write(iulog, *) 'Note: If a variable is not in the registry, ' + write(iulog, *) ' or if a constituent is not registered,' + write(iulog, *) ' it is not checked against the snapshot.' + write(iulog, *) ' Verify all model state variables are enumerated below:' + write(iulog, *) '' + write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,a,3x,a,3x,a)" + write(iulog, fmt_str) 'Variable Checked', '# Values', 'Avg (model)', 'Avg (snapshot)' + write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,a,3x,a,3x,a)" + write(iulog, fmt_str) '--------', '--------', '------------', '--------------' + + do i = 1, num_verbose_entries + slen = len_trim(verbose_stdnames(i)) + + !Write standard name separately if longer than the indent level: + if (slen > indent_level) then + write(iulog, '(a)') trim(verbose_stdnames(i)) + slen = 0 + end if + + !Write out verbose entry with global averages: + write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,i8,3x,es12.5,3x,es12.5)" + write(iulog, fmt_str) verbose_stdnames(i)(1:slen), & + verbose_global_count(i), verbose_avg_model(i), & + verbose_avg_snapshot(i) + end do + + !Reset the buffer for the next check_data call: + num_verbose_entries = 0 + + end subroutine flush_check_field_verbose + end module physics_data From 5bd35ee6df0f3e4572fbc914ab19b586c135fede Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Mon, 9 Mar 2026 13:35:03 -0400 Subject: [PATCH 3/4] Update test sample files --- .../sample_files/write_init_files/physics_inputs_4D.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_bvd.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_cnst.F90 | 6 +++++- .../write_init_files/physics_inputs_constituent_dim.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_ddt.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_ddt2.F90 | 6 +++++- .../write_init_files/physics_inputs_ddt_array.F90 | 6 +++++- .../write_init_files/physics_inputs_host_var.F90 | 6 +++++- .../write_init_files/physics_inputs_initial_value.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_mf.F90 | 6 +++++- .../write_init_files/physics_inputs_no_horiz.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_noreq.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_param.F90 | 6 +++++- .../write_init_files/physics_inputs_protect.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_scalar.F90 | 6 +++++- .../sample_files/write_init_files/physics_inputs_simple.F90 | 6 +++++- 16 files changed, 80 insertions(+), 16 deletions(-) diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_4D.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_4D.F90 index b73f957da..c8bf52344 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_4D.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_4D.F90 @@ -228,6 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -382,11 +383,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_bvd.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_bvd.F90 index ebcbfbd3f..e06e034b7 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_bvd.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_bvd.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_cnst.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_cnst.F90 index 836b44d1c..e25ea252f 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_cnst.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_cnst.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_constituent_dim.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_constituent_dim.F90 index 599148b16..48b876ac1 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_constituent_dim.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_constituent_dim.F90 @@ -233,6 +233,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -387,11 +388,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_ddt.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_ddt.F90 index c1820be82..d1d5c0673 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_ddt.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_ddt.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_ddt2.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_ddt2.F90 index 72727daf3..f0bc91a6e 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_ddt2.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_ddt2.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_ddt_array.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_ddt_array.F90 index 1e66b2f29..10d582801 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_ddt_array.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_ddt_array.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_host_var.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_host_var.F90 index ec1ca6a0b..c3b967bac 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_host_var.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_host_var.F90 @@ -222,6 +222,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -371,11 +372,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_initial_value.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_initial_value.F90 index 2a460d699..3383109ab 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_initial_value.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_initial_value.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_mf.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_mf.F90 index 8fc4f7d49..7158150e5 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_mf.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_mf.F90 @@ -226,6 +226,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -380,11 +381,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_no_horiz.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_no_horiz.F90 index a44bd1f77..82b131b58 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_no_horiz.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_no_horiz.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_noreq.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_noreq.F90 index 6f64e83e5..b805b1ee6 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_noreq.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_noreq.F90 @@ -218,6 +218,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -367,11 +368,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_param.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_param.F90 index 3ea2ff058..6249b9207 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_param.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_param.F90 @@ -228,6 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -382,11 +383,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_protect.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_protect.F90 index 917d2031f..08cf0bb17 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_protect.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_protect.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_scalar.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_scalar.F90 index 575e87fbd..98010e097 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_scalar.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_scalar.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -379,11 +380,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' diff --git a/test/unit/python/sample_files/write_init_files/physics_inputs_simple.F90 b/test/unit/python/sample_files/write_init_files/physics_inputs_simple.F90 index 1d798e7b4..c9dc44151 100644 --- a/test/unit/python/sample_files/write_init_files/physics_inputs_simple.F90 +++ b/test/unit/python/sample_files/write_init_files/physics_inputs_simple.F90 @@ -225,6 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use physics_data, only: flush_check_field_verbose use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys @@ -386,11 +387,14 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end if end if end do + ! Flush verbose check_field entries (printed after diffs): + call flush_check_field_verbose() + ! Close check file: call cam_pio_closefile(file) deallocate(file) nullify(file) - if (is_first) then + if (.not. overall_diff_found) then if (masterproc) then write(iulog,*) '' write(iulog,*) 'No differences found!' From e7e84bd597f40637ae6a01c6dafda0104cb83618 Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Tue, 10 Mar 2026 13:40:47 -0400 Subject: [PATCH 4/4] Update comment in verbose output --- src/physics/utils/physics_data.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/physics/utils/physics_data.F90 b/src/physics/utils/physics_data.F90 index 062a983c3..f6f87c967 100644 --- a/src/physics/utils/physics_data.F90 +++ b/src/physics/utils/physics_data.F90 @@ -1422,11 +1422,12 @@ subroutine flush_check_field_verbose() !Write verbose check_field log header: write(iulog, *) '' - write(iulog, *) 'No differences found for all the variables below:' + write(iulog, *) 'No differences found (above the threshold) for all variables below:' write(iulog, *) 'Note: If a variable is not in the registry, ' write(iulog, *) ' or if a constituent is not registered,' + write(iulog, *) ' or the variable was not updated by any scheme,' write(iulog, *) ' it is not checked against the snapshot.' - write(iulog, *) ' Verify all model state variables are enumerated below:' + write(iulog, *) ' Verify all expected model state variables are enumerated below:' write(iulog, *) '' write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,a,3x,a,3x,a)" write(iulog, fmt_str) 'Variable Checked', '# Values', 'Avg (model)', 'Avg (snapshot)'