From 6be8c556c995352217b54a641c013ca6d6f8ee09 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 29 Aug 2024 14:47:53 -0600 Subject: [PATCH 1/5] Add global attribute write of dataset compatability as a floating point number to surface datasets --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index e22394e1e1..a3423e0c7b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -105,6 +105,7 @@ subroutine mkfile_define_atts(pioid, dynlanduse) character(len= 10) :: time ! temporary character(len= 5) :: zone ! temporary integer :: rcode + real(r4), parameter :: data_version = 5.3 ! Compatibility version number of the datasets to create character(len=*), parameter :: subname = 'mkfile_define_atts' !----------------------------------------------------------------------- @@ -126,6 +127,7 @@ subroutine mkfile_define_atts(pioid, dynlanduse) str = 'Community Land Model: CLM5' rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe)) + rcode = pio_put_att (pioid, pio_global, 'Dataset_Version', data_version) rcode = pio_put_att (pioid, pio_global, 'Logname', trim(logname)) rcode = pio_put_att (pioid, pio_global, 'Host', trim(hostname)) rcode = pio_put_att (pioid, pio_global, 'Number-of-tasks', npes) From 7118d709485113294c4c6f90ca64853d7d3b3862 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 31 Aug 2024 14:48:16 -0600 Subject: [PATCH 2/5] Add a check for compatibility based on the version in the surface dataset --- src/main/clm_initializeMod.F90 | 3 +- src/main/surfrdMod.F90 | 67 +++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 340a799908..c91090f6cb 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -58,7 +58,7 @@ subroutine initialize1(dtime) use clm_varcon , only: clm_varcon_init use landunit_varcon , only: landunit_varcon_init use clm_varctl , only: fsurdat, version - use surfrdMod , only: surfrd_get_num_patches, surfrd_get_nlevurb + use surfrdMod , only: surfrd_get_num_patches, surfrd_get_nlevurb, surfrd_check_file use controlMod , only: control_init, control_print, NLFilename use ncdio_pio , only: ncd_pio_init use initGridCellsMod , only: initGridCells @@ -100,6 +100,7 @@ subroutine initialize1(dtime) call control_init(dtime) call ncd_pio_init() + call surfrd_check_file(fsurdat) call surfrd_get_num_patches(fsurdat, actual_maxsoil_patches, actual_numpft, actual_numcft) call surfrd_get_nlevurb(fsurdat, actual_nlevurb) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 12212e2160..36399c3905 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -7,7 +7,7 @@ module surfrdMod ! ! !USES: #include "shr_assert.h" - use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_log_mod , only : errMsg => shr_log_errMsg use abortutils , only : endrun use clm_varpar , only : nlevsoifl @@ -27,6 +27,7 @@ module surfrdMod save ! ! !PUBLIC MEMBER FUNCTIONS: + public :: surfrd_check_file ! Check that this surface dataset is compatible public :: surfrd_get_data ! Read surface dataset and determine subgrid weights public :: surfrd_get_num_patches ! Read surface dataset to determine maxsoil_patches and numcft public :: surfrd_get_nlevurb ! Read surface dataset to determine nlevurb @@ -45,6 +46,70 @@ module surfrdMod contains + !----------------------------------------------------------------------- + subroutine surfrd_check_file ( lfsurdat ) + ! + ! !DESCRIPTION: + ! Check compatability for this surface dataset and abort with an error if it's not + ! + ! !USES: + use ncdio_pio, only : check_att + ! !ARGUMENTS: + character(len=*), intent(in) :: lfsurdat ! surface dataset filename + ! !LOCAL VARIABLES: + type(file_desc_t) :: ncid ! netcdf id + logical :: exists ! If attribute or variable was found on the file + integer :: status ! Status return code + real(r4) :: version ! Version number on the dataset + ! NOTE: Only increment the expected_version when surface datasets are incompatible with the previous version + ! If datasets are just updated data and backwards compatble leave the expected version alone + real(r4), parameter :: expected_version = 5.3_r4 + character(len=50) :: description + character(len=*), parameter :: version_name = 'Dataset_Version' + + call ncd_pio_openfile (ncid, trim(lfsurdat), 0) + call check_att(ncid, pio_global, version_name, exists) + if (exists) then + status = pio_get_att(ncid, pio_global, version_name, version) + else + ! For a few previous versions guess on the compatability version based on existence of variables + call check_var( ncid, 'PCT_OCEAN', exists) + if (exists) then + version = 5.2_r4 + else + call check_var( ncid, 'PCT_CFT', exists) + if (exists) then + version = 5.0_r4 + else + call check_var( ncid, 'PCT_GLC_MEC_GIC', exists) + if (exists) then + version = 4.5_r4 + else + ! This is a version before the main clm4_5 dataseta so marking it as 0 for unknown + version = 0.0_r4 + end if + end if + end if + end if + call ncd_pio_closefile(ncid) + if ( (version /= expected_version) )then + if ( version < expected_version )then + description = 'older' + if ( version == 0.0_r4 ) description = trim(description)//' than 4.5' + else if ( version > expected_version )then + description = 'newer' + end if + if ( masterproc )then + write(iulog,*) 'Input surface dataset is: ', trim(lfsurdat) + write(iulog,'(3a)') 'This surface dataset is ', trim(description), ' and incompatable with this version of CTSM' + write(iulog,'(a,f3.1,a,f3.1)') 'Dataset version = ', version, ' Version expected = ', expected_version + write(iulog,*) errMsg(sourcefile, __LINE__) + end if + call endrun(msg="ERROR: Incompatble surface dataset") + end if + + end subroutine surfrd_check_file + !----------------------------------------------------------------------- subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) ! From 90a5cf009906bf12b37472c42b89857b2b28c93e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Sep 2024 16:01:45 -0600 Subject: [PATCH 3/5] Remove error about surface datasets Remove the error messaging that talks about old/incompatible surface dataset because we now are checking for the surface dataset compatability. --- src/main/glcBehaviorMod.F90 | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/glcBehaviorMod.F90 b/src/main/glcBehaviorMod.F90 index 315aa88c67..8076f8fcaf 100644 --- a/src/main/glcBehaviorMod.F90 +++ b/src/main/glcBehaviorMod.F90 @@ -407,8 +407,7 @@ subroutine translate_glacier_region_behavior glacier_region_behavior(i) = BEHAVIOR_SINGLE_AT_ATM_TOPO case (behavior_str_unset) write(iulog,*) ' ERROR: glacier_region_behavior not specified for ID ', i - write(iulog,*) 'You may need to extend the glacier_region_behavior namelist array,' - write(iulog,*) 'or you may be running with an old/incompatible surface dataset.' + write(iulog,*) 'You may need to extend the glacier_region_behavior namelist array.' call endrun(msg=' ERROR: glacier_region_behavior not specified for ID '// & errMsg(sourcefile, __LINE__)) case default @@ -439,8 +438,7 @@ subroutine translate_glacier_region_melt_behavior glacier_region_melt_behavior(i) = MELT_BEHAVIOR_REMAINS_IN_PLACE case (behavior_str_unset) write(iulog,*) ' ERROR: glacier_region_melt_behavior not specified for ID ', i - write(iulog,*) 'You may need to extend the glacier_region_melt_behavior namelist array,' - write(iulog,*) 'or you may be running with an old/incompatible surface dataset.' + write(iulog,*) 'You may need to extend the glacier_region_melt_behavior namelist array.' call endrun(msg=' ERROR: glacier_region_melt_behavior not specified for ID '// & errMsg(sourcefile, __LINE__)) case default @@ -471,8 +469,7 @@ subroutine translate_glacier_region_ice_runoff_behavior glacier_region_ice_runoff_behavior(i) = ICE_RUNOFF_BEHAVIOR_MELTED case (behavior_str_unset) write(iulog,*) ' ERROR: glacier_region_ice_runoff_behavior not specified for ID ', i - write(iulog,*) 'You may need to extend the glacier_region_ice_runoff_behavior namelist array,' - write(iulog,*) 'or you may be running with an old/incompatible surface dataset.' + write(iulog,*) 'You may need to extend the glacier_region_ice_runoff_behavior namelist array.' call endrun(msg=' ERROR: glacier_region_ice_runoff_behavior not specified for ID '// & errMsg(sourcefile, __LINE__)) case default From 703c2913ec974bf6f536329eb92a4ec175ea2f2b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Sep 2024 16:19:24 -0600 Subject: [PATCH 4/5] Add comments about dataset verison Add some notes that dataset version is only updated when the new datasets will NOT be backwards compatible with the previous version. --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index a3423e0c7b..997020292b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -105,6 +105,10 @@ subroutine mkfile_define_atts(pioid, dynlanduse) character(len= 10) :: time ! temporary character(len= 5) :: zone ! temporary integer :: rcode + ! Surface dataset version these datasets are compatible with: + ! - Only update this when the new surface datasets will be incompatible with the previous verison + ! - Since whenever we update surface datasets we update to a new minor version this always corresponds + ! to a CTSM minor version: 5.3, i6.1, 6.5 etcetera real(r4), parameter :: data_version = 5.3 ! Compatibility version number of the datasets to create character(len=*), parameter :: subname = 'mkfile_define_atts' !----------------------------------------------------------------------- From 0fd3d41e58f6ec992aa78dac42bef707fea14be5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 5 Sep 2024 01:40:10 -0600 Subject: [PATCH 5/5] Change name of the subroutine for the surface dataset compatibility check, fix version guessing inside it, fix spelling error, respond to rest of the review conversations --- src/main/clm_initializeMod.F90 | 4 ++-- src/main/surfrdMod.F90 | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index c91090f6cb..bf9a97ae58 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -58,7 +58,7 @@ subroutine initialize1(dtime) use clm_varcon , only: clm_varcon_init use landunit_varcon , only: landunit_varcon_init use clm_varctl , only: fsurdat, version - use surfrdMod , only: surfrd_get_num_patches, surfrd_get_nlevurb, surfrd_check_file + use surfrdMod , only: surfrd_get_num_patches, surfrd_get_nlevurb, surfrd_compat_check use controlMod , only: control_init, control_print, NLFilename use ncdio_pio , only: ncd_pio_init use initGridCellsMod , only: initGridCells @@ -100,7 +100,7 @@ subroutine initialize1(dtime) call control_init(dtime) call ncd_pio_init() - call surfrd_check_file(fsurdat) + call surfrd_compat_check(fsurdat) call surfrd_get_num_patches(fsurdat, actual_maxsoil_patches, actual_numpft, actual_numcft) call surfrd_get_nlevurb(fsurdat, actual_nlevurb) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 36399c3905..88d43a09cc 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -27,7 +27,7 @@ module surfrdMod save ! ! !PUBLIC MEMBER FUNCTIONS: - public :: surfrd_check_file ! Check that this surface dataset is compatible + public :: surfrd_compat_check ! Check that this surface dataset is compatible public :: surfrd_get_data ! Read surface dataset and determine subgrid weights public :: surfrd_get_num_patches ! Read surface dataset to determine maxsoil_patches and numcft public :: surfrd_get_nlevurb ! Read surface dataset to determine nlevurb @@ -47,7 +47,7 @@ module surfrdMod contains !----------------------------------------------------------------------- - subroutine surfrd_check_file ( lfsurdat ) + subroutine surfrd_compat_check ( lfsurdat ) ! ! !DESCRIPTION: ! Check compatability for this surface dataset and abort with an error if it's not @@ -77,11 +77,11 @@ subroutine surfrd_check_file ( lfsurdat ) if (exists) then version = 5.2_r4 else - call check_var( ncid, 'PCT_CFT', exists) + call check_var( ncid, 'CONST_HARVEST_SH1', exists) if (exists) then version = 5.0_r4 else - call check_var( ncid, 'PCT_GLC_MEC_GIC', exists) + call check_var( ncid, 'GLACIER_REGION', exists) if (exists) then version = 4.5_r4 else @@ -101,14 +101,14 @@ subroutine surfrd_check_file ( lfsurdat ) end if if ( masterproc )then write(iulog,*) 'Input surface dataset is: ', trim(lfsurdat) - write(iulog,'(3a)') 'This surface dataset is ', trim(description), ' and incompatable with this version of CTSM' + write(iulog,'(3a)') 'This surface dataset is ', trim(description), ' and incompatible with this version of CTSM' write(iulog,'(a,f3.1,a,f3.1)') 'Dataset version = ', version, ' Version expected = ', expected_version write(iulog,*) errMsg(sourcefile, __LINE__) end if - call endrun(msg="ERROR: Incompatble surface dataset") + call endrun(msg="ERROR: Incompatible surface dataset") end if - end subroutine surfrd_check_file + end subroutine surfrd_compat_check !----------------------------------------------------------------------- subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft)