diff --git a/diag_manager/fms_diag_file_object.F90 b/diag_manager/fms_diag_file_object.F90 index f9248a2cf..6a8db1a2d 100644 --- a/diag_manager/fms_diag_file_object.F90 +++ b/diag_manager/fms_diag_file_object.F90 @@ -99,6 +99,7 @@ module fms_diag_file_object_mod logical, allocatable :: time_ops !< .True. if file contains variables that are time_min, time_max, time_average, !! or time_sum integer :: unlim_dimension_level !< The unlimited dimension level currently being written + integer :: num_time_levels !< The number of time levels that were actually written to the file logical :: data_has_been_written !< .True. if data has been written for the current unlimited dimension level logical :: is_static !< .True. if the frequency is -1 integer :: nz_subaxis !< The number of Z axis currently added to the file @@ -194,6 +195,7 @@ module fms_diag_file_object_mod procedure :: init_unlim_dim procedure :: update_current_new_file_freq_index procedure :: get_unlim_dimension_level + procedure :: get_num_time_levels procedure :: flush_diag_file procedure :: get_next_output procedure :: get_next_next_output @@ -296,6 +298,7 @@ logical function fms_diag_files_object_init (files_array) endif obj%unlim_dimension_level = 0 + obj%num_time_levels = 0 obj%is_static = obj%get_file_freq() .eq. -1 obj%nz_subaxis = 0 @@ -1607,6 +1610,16 @@ subroutine init_unlim_dim(this, output_buffers) enddo end subroutine init_unlim_dim +!> \brief Get the number of time levels that were actually written to the file +!! \return Number of time levels that were actually written to the file +pure function get_num_time_levels(this) & +result(res) + class(fmsDiagFileContainer_type), intent(in), target :: this !< The file object + integer :: res + + res = this%FMS_diag_file%num_time_levels +end function + !> \brief Get the unlimited dimension level that is in the file !! \return The unlimited dimension pure function get_unlim_dimension_level(this) & @@ -1816,6 +1829,13 @@ subroutine close_diag_file(this, output_buffers, model_end_time, diag_fields) call close_file(fms2io_fileobj) end select + !< Keep track of the number of time levels that were written to the file + !! If the file is using the new_file_freq key, it will be closing the file multiple + !! time, so this ensures that we keep a running count + !! This is going be written to the output yaml, after all the files are closed + this%FMS_diag_file%num_time_levels = this%FMS_diag_file%num_time_levels + & + this%FMS_diag_file%unlim_dimension_level + !< Reset the unlimited dimension level back to 0, in case the fms2io_fileobj is re-used this%FMS_diag_file%unlim_dimension_level = 0 this%FMS_diag_file%is_file_open = .false. diff --git a/diag_manager/fms_diag_object.F90 b/diag_manager/fms_diag_object.F90 index 9bb7ef308..e1fb0a1b5 100644 --- a/diag_manager/fms_diag_object.F90 +++ b/diag_manager/fms_diag_object.F90 @@ -99,6 +99,7 @@ module fms_diag_object_mod procedure :: allocate_diag_field_output_buffers procedure :: fms_diag_compare_window procedure :: set_time_end + procedure :: get_ntimes_per_file #ifdef use_yaml procedure :: get_diag_buffer #endif @@ -154,6 +155,28 @@ subroutine fms_diag_object_init (this,diag_subset_output, time_init) #endif end subroutine fms_diag_object_init +!> @brief Determines the number of time levels that were written each file +!! @return The number of time levels that were written each file +function get_ntimes_per_file(this) & + result(ntimes) + class(fmsDiagObject_type) :: this !< Diag object + integer, allocatable :: ntimes(:) + + integer :: i !< For looping through the files + +#ifdef use_yaml + allocate(ntimes(size(this%FMS_diag_files))) + do i = 1, size(this%FMS_diag_files) + ntimes(i) = this%FMS_diag_files(i)%get_num_time_levels() + enddo +#else + allocate(ntimes(1)) + ntimes = diag_null + call mpp_error(FATAL, "You must compile with -Duse_yaml to call fms_diag_object%get_ntimes_per_file!") +#endif + +end function get_ntimes_per_file + !> \description Loops through all files and does one final write. !! Closes all files !! Deallocates all buffers, fields, and files @@ -161,17 +184,20 @@ end subroutine fms_diag_object_init subroutine fms_diag_object_end (this, time) class(fmsDiagObject_type) :: this TYPE(time_type), INTENT(in) :: time + integer, allocatable :: ntimes(:) !< Number of time steps per file integer :: i #ifdef use_yaml !TODO: loop through files and force write if (.not. this%initialized) return - ! write output yaml - call fms_diag_yaml_out() - call this%do_buffer_math() call this%fms_diag_do_io(end_time=time) + + ! write output yaml + ntimes = this%get_ntimes_per_file() + call fms_diag_yaml_out(ntimes) + !TODO: Deallocate diag object arrays and clean up all memory do i=1, size(this%FMS_diag_output_buffers) call this%FMS_diag_output_buffers(i)%flush_buffer() diff --git a/diag_manager/fms_diag_yaml.F90 b/diag_manager/fms_diag_yaml.F90 index 4d40b06d0..4c36e733e 100644 --- a/diag_manager/fms_diag_yaml.F90 +++ b/diag_manager/fms_diag_yaml.F90 @@ -1645,7 +1645,8 @@ subroutine dump_diag_yaml_obj( filename ) !> Writes an output yaml with all available information on the written files. !! Will only write with root pe. !! Global attributes are limited to 16 per file. -subroutine fms_diag_yaml_out() +subroutine fms_diag_yaml_out(ntimes) + integer, intent(in) :: ntimes(:) !< The number of time levels that were written for each file type(diagYamlFiles_type), pointer :: fileptr !< pointer for individual variables type(diagYamlFilesVar_type), pointer :: varptr !< pointer for individual variables type (fmsyamloutkeys_type), allocatable :: keys(:), keys2(:), keys3(:) @@ -1714,6 +1715,7 @@ subroutine fms_diag_yaml_out() call fms_f2c_string(keys2(i)%key8, 'start_time') call fms_f2c_string(keys2(i)%key9, 'file_duration') call fms_f2c_string(keys2(i)%key10, 'file_duration_units') + call fms_f2c_string(keys2(i)%key11, 'number_of_timelevels') call fms_f2c_string(vals2(i)%val1, fileptr%file_fname) call fms_f2c_string(vals2(i)%val5, fileptr%file_unlimdim) @@ -1750,6 +1752,7 @@ subroutine fms_diag_yaml_out() enddo call fms_f2c_string(vals2(i)%val9, adjustl(tmpstr1)) call fms_f2c_string(vals2(i)%val10, get_diag_unit_string(fileptr%file_duration_units)) + call fms_f2c_string(vals2(i)%val11, string(ntimes(i))) !! tier 3 - varlists, subregion, global metadata call yaml_out_add_level2key('varlist', keys2(i)) diff --git a/test_fms/diag_manager/test_diag_manager2.sh b/test_fms/diag_manager/test_diag_manager2.sh index 1c54a5496..948bf7794 100755 --- a/test_fms/diag_manager/test_diag_manager2.sh +++ b/test_fms/diag_manager/test_diag_manager2.sh @@ -898,6 +898,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 1 varlist: - module: atm_mod var_name: var7 @@ -930,6 +931,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 3 varlist: - module: ocn_mod var_name: var1 @@ -972,6 +974,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 3 varlist: - module: atm_mod var_name: var3 @@ -1036,6 +1039,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 3 varlist: - module: lnd_mod var_name: var5 @@ -1078,6 +1082,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 3 varlist: - module: lnd_mod var_name: var1 @@ -1109,6 +1114,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 3 varlist: - module: atm_mod var_name: var4 @@ -1140,6 +1146,7 @@ diag_files: start_time: 00020101.000000 file_duration: 12 file_duration_units: hours + number_of_timelevels: 2 varlist: - module: ocn_mod var_name: var1 @@ -1171,6 +1178,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 3 varlist: - module: ocn_mod var_name: var1 @@ -1202,6 +1210,7 @@ diag_files: start_time: 00020101.000000 file_duration: 12 3 9 file_duration_units: hours hours hours + number_of_timelevels: 24 varlist: - module: ocn_mod var_name: var1 @@ -1233,6 +1242,7 @@ diag_files: start_time: 00020101.000000 file_duration: 12 3 9 file_duration_units: hours hours hours + number_of_timelevels: 24 varlist: - module: ocn_mod var_name: var1 @@ -1264,6 +1274,7 @@ diag_files: start_time: file_duration: file_duration_units: + number_of_timelevels: 1 varlist: - module: ocn_mod var_name: var1