diff --git a/diag_manager/fms_diag_field_object.F90 b/diag_manager/fms_diag_field_object.F90 index 58b830d36c..1eb0221e94 100644 --- a/diag_manager/fms_diag_field_object.F90 +++ b/diag_manager/fms_diag_field_object.F90 @@ -96,6 +96,7 @@ module fms_diag_field_object_mod procedure :: set_math_needs_to_be_done => set_math_needs_to_be_done procedure :: add_attribute => diag_field_add_attribute procedure :: vartype_inq => what_is_vartype + procedure :: set_mask_variant ! Check functions procedure :: is_static => diag_obj_is_static procedure :: is_scalar @@ -436,6 +437,14 @@ subroutine set_math_needs_to_be_done (this, math_needs_to_be_done) this%math_needs_to_be_done = math_needs_to_be_done end subroutine set_math_needs_to_be_done +!> @brief Set the mask_variant to .true. +subroutine set_mask_variant(this, is_masked) + class (fmsDiagField_type) , intent(inout):: this !< The diag field object + logical, intent (in) :: is_masked !< .True. if the field is masked + + this%mask_variant = is_masked +end subroutine set_mask_variant + !> @brief Sets the flag saying that the data buffer is allocated subroutine set_data_buffer_is_allocated (this, data_buffer_is_allocated) class (fmsDiagField_type) , intent(inout) :: this !< The field object diff --git a/diag_manager/fms_diag_object.F90 b/diag_manager/fms_diag_object.F90 index d846c97afa..10c8514479 100644 --- a/diag_manager/fms_diag_object.F90 +++ b/diag_manager/fms_diag_object.F90 @@ -554,6 +554,9 @@ logical function fms_diag_accept_data (this, diag_field_id, field_data, mask, rm if (.not. allocated(mask) .and. .not. allocated(rmask)) call mpp_error(FATAL, & "The field was registered with mask_variant, but mask or rmask are not present in the send_data call. "//& trim(field_info)) + else + if (allocated(mask) .or. allocated(rmask)) & + call this%FMS_diag_fields(diag_field_id)%set_mask_variant(.True.) endif !< Check that mask and rmask are not both present @@ -795,6 +798,14 @@ function fms_diag_do_reduction(this, field_data, diag_field_id, oor_mask, weight call mpp_error(FATAl, "The missing value for the field:"//trim(field_ptr%get_varname())//& &" was not allocated to the correct type. This shouldn't have happened") end select + else + select type (missing_val => get_default_missing_value(r8)) + type is (real(kind=r8_kind)) + missing_value = missing_val + class default + call mpp_error(FATAl, "The missing value for the field:"//trim(field_ptr%get_varname())//& + &" was not allocated to the correct type. This shouldn't have happened") + end select endif buffer_loop: do ids = 1, size(field_ptr%buffer_ids) @@ -870,12 +881,23 @@ function fms_diag_do_reduction(this, field_data, diag_field_id, oor_mask, weight reduction_method = field_yaml_ptr%get_var_reduction() select case(reduction_method) case (time_none) - error_msg = buffer_ptr%do_time_none_wrapper(field_data, oor_mask, bounds_in, bounds_out, missing_value) + error_msg = buffer_ptr%do_time_none_wrapper(field_data, oor_mask, field_ptr%get_mask_variant(), & + bounds_in, bounds_out, missing_value) if (trim(error_msg) .ne. "") then return endif case (time_min) + error_msg = buffer_ptr%do_time_min_wrapper(field_data, oor_mask, field_ptr%get_mask_variant(), & + bounds_in, bounds_out, missing_value) + if (trim(error_msg) .ne. "") then + return + endif case (time_max) + error_msg = buffer_ptr%do_time_max_wrapper(field_data, oor_mask, field_ptr%get_mask_variant(), & + bounds_in, bounds_out, missing_value) + if (trim(error_msg) .ne. "") then + return + endif case (time_sum) case (time_average) case (time_power) diff --git a/diag_manager/fms_diag_output_buffer.F90 b/diag_manager/fms_diag_output_buffer.F90 index 9a3ffdf469..b2c54f1387 100644 --- a/diag_manager/fms_diag_output_buffer.F90 +++ b/diag_manager/fms_diag_output_buffer.F90 @@ -34,7 +34,7 @@ module fms_diag_output_buffer_mod use fms2_io_mod, only: FmsNetcdfFile_t, write_data, FmsNetcdfDomainFile_t, FmsNetcdfUnstructuredDomainFile_t use fms_diag_yaml_mod, only: diag_yaml use fms_diag_bbox_mod, only: fmsDiagIbounds_type -use fms_diag_reduction_methods_mod, only: do_time_none +use fms_diag_reduction_methods_mod, only: do_time_none, do_time_min, do_time_max use fms_diag_time_utils_mod, only: diag_time_inc implicit none @@ -76,6 +76,8 @@ module fms_diag_output_buffer_mod procedure :: get_buffer procedure :: flush_buffer procedure :: do_time_none_wrapper + procedure :: do_time_min_wrapper + procedure :: do_time_max_wrapper end type fmsDiagOutputBuffer_type @@ -470,35 +472,104 @@ end subroutine write_buffer_wrapper_u !> @brief Does the time_none reduction method on the buffer object !! @return Error message if the math was not successful -function do_time_none_wrapper(this, field_data, mask, bounds_in, bounds_out, missing_value) & +function do_time_none_wrapper(this, field_data, mask, is_masked, bounds_in, bounds_out, missing_value) & result(err_msg) class(fmsDiagOutputBuffer_type), intent(inout) :: this !< buffer object to write class(*), intent(in) :: field_data(:,:,:,:) !< Buffer data for current time type(fmsDiagIbounds_type), intent(in) :: bounds_in !< Indicies for the buffer passed in type(fmsDiagIbounds_type), intent(in) :: bounds_out !< Indicies for the output buffer logical, intent(in) :: mask(:,:,:,:) !< Mask for the field + logical, intent(in) :: is_masked !< .True. if the field has a mask real(kind=r8_kind), intent(in) :: missing_value !< Missing_value for data points that are masked character(len=50) :: err_msg - !TODO This does not need to be done for every time step !TODO This will be expanded for integers err_msg = "" select type (output_buffer => this%buffer) type is (real(kind=r8_kind)) select type (field_data) type is (real(kind=r8_kind)) - call do_time_none(output_buffer, field_data, mask, bounds_in, bounds_out, missing_value) + call do_time_none(output_buffer, field_data, mask, is_masked, bounds_in, bounds_out, missing_value) class default - err_msg="the output buffer and the buffer send in are not of the same type (r8_kind)" + err_msg="do_time_none_wrapper::the output buffer and the buffer send in are not of the same type (r8_kind)" end select type is (real(kind=r4_kind)) select type (field_data) type is (real(kind=r4_kind)) - call do_time_none(output_buffer, field_data, mask, bounds_in, bounds_out, real(missing_value, kind=r4_kind)) + call do_time_none(output_buffer, field_data, mask, is_masked, bounds_in, bounds_out, & + real(missing_value, kind=r4_kind)) class default - err_msg="the output buffer and the buffer send in are not of the same type (r4_kind)" + err_msg="do_time_none_wrapper::the output buffer and the buffer send in are not of the same type (r4_kind)" end select end select end function do_time_none_wrapper + +!> @brief Does the time_min reduction method on the buffer object +!! @return Error message if the math was not successful +function do_time_min_wrapper(this, field_data, mask, is_masked, bounds_in, bounds_out, missing_value) & + result(err_msg) + class(fmsDiagOutputBuffer_type), intent(inout) :: this !< buffer object to write + class(*), intent(in) :: field_data(:,:,:,:) !< Buffer data for current time + type(fmsDiagIbounds_type), intent(in) :: bounds_in !< Indicies for the buffer passed in + type(fmsDiagIbounds_type), intent(in) :: bounds_out !< Indicies for the output buffer + logical, intent(in) :: mask(:,:,:,:) !< Mask for the field + logical, intent(in) :: is_masked !< .True. if the field has a mask + real(kind=r8_kind), intent(in) :: missing_value !< Missing_value for data points that are masked + character(len=50) :: err_msg + + !TODO This will be expanded for integers + err_msg = "" + select type (output_buffer => this%buffer) + type is (real(kind=r8_kind)) + select type (field_data) + type is (real(kind=r8_kind)) + call do_time_min(output_buffer, field_data, mask, is_masked, bounds_in, bounds_out, missing_value) + class default + err_msg="do_time_min_wrapper::the output buffer and the buffer send in are not of the same type (r8_kind)" + end select + type is (real(kind=r4_kind)) + select type (field_data) + type is (real(kind=r4_kind)) + call do_time_min(output_buffer, field_data, mask, is_masked, bounds_in, bounds_out, & + real(missing_value, kind=r4_kind)) + class default + err_msg="do_time_min_wrapper::the output buffer and the buffer send in are not of the same type (r4_kind)" + end select + end select +end function do_time_min_wrapper + +!> @brief Does the time_min reduction method on the buffer object +!! @return Error message if the math was not successful +function do_time_max_wrapper(this, field_data, mask, is_masked, bounds_in, bounds_out, missing_value) & + result(err_msg) + class(fmsDiagOutputBuffer_type), intent(inout) :: this !< buffer object to write + class(*), intent(in) :: field_data(:,:,:,:) !< Buffer data for current time + type(fmsDiagIbounds_type), intent(in) :: bounds_in !< Indicies for the buffer passed in + type(fmsDiagIbounds_type), intent(in) :: bounds_out !< Indicies for the output buffer + logical, intent(in) :: mask(:,:,:,:) !< Mask for the field + logical, intent(in) :: is_masked !< .True. if the field has a mask + real(kind=r8_kind), intent(in) :: missing_value !< Missing_value for data points that are masked + character(len=50) :: err_msg + + !TODO This will be expanded for integers + err_msg = "" + select type (output_buffer => this%buffer) + type is (real(kind=r8_kind)) + select type (field_data) + type is (real(kind=r8_kind)) + call do_time_max(output_buffer, field_data, mask, is_masked, bounds_in, bounds_out, missing_value) + class default + err_msg="do_time_max_wrapper::the output buffer and the buffer send in are not of the same type (r8_kind)" + end select + type is (real(kind=r4_kind)) + select type (field_data) + type is (real(kind=r4_kind)) + call do_time_max(output_buffer, field_data, mask, is_masked, bounds_in, bounds_out, & + real(missing_value, kind=r4_kind)) + class default + err_msg="do_time_max_wrapper::the output buffer and the buffer send in are not of the same type (r4_kind)" + end select + end select +end function do_time_max_wrapper #endif end module fms_diag_output_buffer_mod diff --git a/diag_manager/fms_diag_reduction_methods.F90 b/diag_manager/fms_diag_reduction_methods.F90 index fa4a7b9fcd..c48f9b21cd 100644 --- a/diag_manager/fms_diag_reduction_methods.F90 +++ b/diag_manager/fms_diag_reduction_methods.F90 @@ -35,7 +35,7 @@ module fms_diag_reduction_methods_mod private public :: check_indices_order, init_mask, set_weight - public :: do_time_none + public :: do_time_none, do_time_min, do_time_max !> @brief Does the time_none reduction method. See include/fms_diag_reduction_methods.inc !TODO This needs to be extended to integers @@ -43,6 +43,18 @@ module fms_diag_reduction_methods_mod module procedure do_time_none_r4, do_time_none_r8 end interface do_time_none + !> @brief Does the time_min reduction method. See include/fms_diag_reduction_methods.inc + !TODO This needs to be extended to integers + interface do_time_min + module procedure do_time_min_r4, do_time_min_r8 + end interface do_time_min + + !> @brief Does the time_max reduction method. See include/fms_diag_reduction_methods.inc + !TODO This needs to be extended to integers + interface do_time_max + module procedure do_time_max_r4, do_time_max_r8 + end interface do_time_max + contains !> @brief Checks improper combinations of is, ie, js, and je. diff --git a/diag_manager/include/fms_diag_reduction_methods.inc b/diag_manager/include/fms_diag_reduction_methods.inc index ddb6b8c926..72332d650e 100644 --- a/diag_manager/include/fms_diag_reduction_methods.inc +++ b/diag_manager/include/fms_diag_reduction_methods.inc @@ -18,10 +18,11 @@ !*********************************************************************** !> @brief Do the time_none reduction method (i.e copy the correct portion of the input data) -subroutine DO_TIME_NONE_ (data_out, data_in, mask, bounds_in, bounds_out, missing_value) +subroutine DO_TIME_NONE_ (data_out, data_in, mask, is_masked, bounds_in, bounds_out, missing_value) real(FMS_TRM_KIND_), intent(inout) :: data_out(:,:,:,:,:) !< output data real(FMS_TRM_KIND_), intent(in) :: data_in(:,:,:,:) !< data to update the buffer with logical, intent(in) :: mask(:,:,:,:) !< mask + logical, intent(in) :: is_masked !< .True. if the field is using a mask type(fmsDiagIbounds_type), intent(in) :: bounds_in !< indices indicating the correct portion !! of the input buffer type(fmsDiagIbounds_type), intent(in) :: bounds_out !< indices indicating the correct portion @@ -47,11 +48,157 @@ subroutine DO_TIME_NONE_ (data_out, data_in, mask, bounds_in, bounds_out, missin ks_in = bounds_in%get_kmin() ke_in = bounds_in%get_kmax() - where (mask(is_in:ie_in, js_in:je_in, ks_in:ke_in, :)) + if (is_masked) then + where (mask(is_in:ie_in, js_in:je_in, ks_in:ke_in, :)) + data_out(is_out:ie_out, js_out:je_out, ks_out:ke_out, :, 1) = & + data_in(is_in:ie_in, js_in:je_in, ks_in:ke_in, :) + elsewhere + data_out(is_out:ie_out, js_out:je_out, ks_out:ke_out, :, 1) = missing_value + end where + else data_out(is_out:ie_out, js_out:je_out, ks_out:ke_out, :, 1) = & - data_in(is_in:ie_in, js_in:je_in, ks_in:ke_in, :) - elsewhere - data_out(is_out:ie_out, js_out:je_out, ks_out:ke_out, :, 1) = missing_value - end where + data_in(is_in:ie_in, js_in:je_in, ks_in:ke_in, :) + endif -end subroutine DO_TIME_NONE_ \ No newline at end of file +end subroutine DO_TIME_NONE_ + +!> @brief Do the time_min reduction method (i.e maintain the minimum value of the averaging time) +subroutine DO_TIME_MIN_ (data_out, data_in, mask, is_masked, bounds_in, bounds_out, missing_value) + real(FMS_TRM_KIND_), intent(inout) :: data_out(:,:,:,:,:) !< output data + real(FMS_TRM_KIND_), intent(in) :: data_in(:,:,:,:) !< data to update the buffer with + logical, intent(in) :: mask(:,:,:,:) !< mask + logical, intent(in) :: is_masked !< .True. if the field is using a mask + type(fmsDiagIbounds_type), intent(in) :: bounds_in !< indices indicating the correct portion + !! of the input buffer + type(fmsDiagIbounds_type), intent(in) :: bounds_out !< indices indicating the correct portion + !! of the output buffer + real(FMS_TRM_KIND_), intent(in) :: missing_value !< Missing_value for data points that are masked + + integer :: is_in, ie_in, js_in, je_in, ks_in, ke_in !< Starting and ending indices of each dimention for + !! the input buffer + integer :: is_out, ie_out, js_out, je_out, ks_out, ke_out !< Starting and ending indices of each dimention for + !! the output buffer + + integer :: i, j, k, l !< For looping + + is_out = bounds_out%get_imin() + ie_out = bounds_out%get_imax() + js_out = bounds_out%get_jmin() + je_out = bounds_out%get_jmax() + ks_out = bounds_out%get_kmin() + ke_out = bounds_out%get_kmax() + + is_in = bounds_in%get_imin() + ie_in = bounds_in%get_imax() + js_in = bounds_in%get_jmin() + je_in = bounds_in%get_jmax() + ks_in = bounds_in%get_kmin() + ke_in = bounds_in%get_kmax() + + !> Seperated this loops for performance. If is_masked = .false. (i.e "mask" and "rmask" were never passed in) + !! then mask will always be .True. so the if (mask) is redudant. + if (is_masked) then + do l = 0, size(data_out, 4) - 1 + do k = 0, ke_out - ks_out + do j = 0, je_out - js_out + do i = 0, ie_out - is_out + if (mask(is_in + i, js_in + j, ks_in + k, l + 1)) then + if (data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) .gt. & + data_in(is_in + i, js_in + j, ks_in + k, l + 1) ) then + data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) = & + data_in(is_in +i, js_in + j, ks_in + k, l + 1) + endif + else + data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) = missing_value + endif + enddo + enddo + enddo + enddo + else + do l = 0, size(data_out, 4) - 1 + do k = 0, ke_out - ks_out + do j = 0, je_out - js_out + do i = 0, ie_out - is_out + if (data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) .gt. & + data_in(is_in + i, js_in + j, ks_in + k, l + 1) ) then + data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) = & + data_in(is_in +i, js_in + j, ks_in + k, l + 1) + endif + enddo + enddo + enddo + enddo + endif + +end subroutine DO_TIME_MIN_ + +!> @brief Do the time_max reduction method (i.e maintain the maximum value of the averaging time) +subroutine DO_TIME_MAX_ (data_out, data_in, mask, is_masked, bounds_in, bounds_out, missing_value) + real(FMS_TRM_KIND_), intent(inout) :: data_out(:,:,:,:,:) !< output data + real(FMS_TRM_KIND_), intent(in) :: data_in(:,:,:,:) !< data to update the buffer with + logical, intent(in) :: mask(:,:,:,:) !< mask + logical, intent(in) :: is_masked !< .True. if the field is using a mask + type(fmsDiagIbounds_type), intent(in) :: bounds_in !< indices indicating the correct portion + !! of the input buffer + type(fmsDiagIbounds_type), intent(in) :: bounds_out !< indices indicating the correct portion + !! of the output buffer + real(FMS_TRM_KIND_), intent(in) :: missing_value !< Missing_value for data points that are masked + + integer :: is_in, ie_in, js_in, je_in, ks_in, ke_in !< Starting and ending indices of each dimention for + !! the input buffer + integer :: is_out, ie_out, js_out, je_out, ks_out, ke_out !< Starting and ending indices of each dimention for + !! the output buffer + + integer :: i, j, k, l !< For looping + + is_out = bounds_out%get_imin() + ie_out = bounds_out%get_imax() + js_out = bounds_out%get_jmin() + je_out = bounds_out%get_jmax() + ks_out = bounds_out%get_kmin() + ke_out = bounds_out%get_kmax() + + is_in = bounds_in%get_imin() + ie_in = bounds_in%get_imax() + js_in = bounds_in%get_jmin() + je_in = bounds_in%get_jmax() + ks_in = bounds_in%get_kmin() + ke_in = bounds_in%get_kmax() + + !> Seperated this loops for performance. If is_masked = .false. (i.e "mask" and "rmask" were never passed in) + !! then mask will always be .True. so the if (mask) is redudant. + if (is_masked) then + do l = 0, size(data_out, 4) - 1 + do k = 0, ke_out - ks_out + do j = 0, je_out - js_out + do i = 0, ie_out - is_out + if (mask(is_in + i, js_in + j, ks_in + k, l + 1)) then + if (data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) .lt. & + data_in(is_in + i, js_in + j, ks_in + k, l + 1) ) then + data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) = & + data_in(is_in +i, js_in + j, ks_in + k, l + 1) + endif + else + data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) = missing_value + endif + enddo + enddo + enddo + enddo + else + do l = 0, size(data_out, 4) - 1 + do k = 0, ke_out - ks_out + do j = 0, je_out - js_out + do i = 0, ie_out - is_out + if (data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) .lt. & + data_in(is_in + i, js_in + j, ks_in + k, l + 1) ) then + data_out(is_out + i, js_out + j, ks_out + k, l + 1, 1) = & + data_in(is_in +i, js_in + j, ks_in + k, l + 1) + endif + enddo + enddo + enddo + enddo + endif +end subroutine DO_TIME_MAX_ \ No newline at end of file diff --git a/diag_manager/include/fms_diag_reduction_methods_r4.fh b/diag_manager/include/fms_diag_reduction_methods_r4.fh index 922972cce3..c3bc29296a 100644 --- a/diag_manager/include/fms_diag_reduction_methods_r4.fh +++ b/diag_manager/include/fms_diag_reduction_methods_r4.fh @@ -29,6 +29,12 @@ #undef DO_TIME_NONE_ #define DO_TIME_NONE_ do_time_none_r4 +#undef DO_TIME_MIN_ +#define DO_TIME_MIN_ do_time_min_r4 + +#undef DO_TIME_MAX_ +#define DO_TIME_MAX_ do_time_max_r4 + #include "fms_diag_reduction_methods.inc" !> @} diff --git a/diag_manager/include/fms_diag_reduction_methods_r8.fh b/diag_manager/include/fms_diag_reduction_methods_r8.fh index 25c3031a22..a3e3d68376 100644 --- a/diag_manager/include/fms_diag_reduction_methods_r8.fh +++ b/diag_manager/include/fms_diag_reduction_methods_r8.fh @@ -29,6 +29,12 @@ #undef DO_TIME_NONE_ #define DO_TIME_NONE_ do_time_none_r8 +#undef DO_TIME_MIN_ +#define DO_TIME_MIN_ do_time_min_r8 + +#undef DO_TIME_MAX_ +#define DO_TIME_MAX_ do_time_max_r8 + #include "fms_diag_reduction_methods.inc" !> @} diff --git a/test_fms/diag_manager/check_time_max.F90 b/test_fms/diag_manager/check_time_max.F90 index e579bada4f..51e888541c 100644 --- a/test_fms/diag_manager/check_time_max.F90 +++ b/test_fms/diag_manager/check_time_max.F90 @@ -73,7 +73,7 @@ program check_time_max do i = 1, 8 cdata_out = -999_r4_kind print *, "Checking answers for var0_max - time_level:", string(i) - call read_data(fileobj, "var0_max", cdata_out(1:1,1,1,1), unlim_dim_level=i) !eyeroll + call read_data(fileobj, "var0_max", cdata_out(1,1,1,1), unlim_dim_level=i) call check_data_0d(cdata_out(1,1,1,1), i) cdata_out = -999_r4_kind diff --git a/test_fms/diag_manager/check_time_min.F90 b/test_fms/diag_manager/check_time_min.F90 index cb1406070c..e56e344144 100644 --- a/test_fms/diag_manager/check_time_min.F90 +++ b/test_fms/diag_manager/check_time_min.F90 @@ -73,7 +73,7 @@ program check_time_min do i = 1, 8 cdata_out = -999_r4_kind print *, "Checking answers for var0_min - time_level:", string(i) - call read_data(fileobj, "var0_min", cdata_out(1:1,1,1,1), unlim_dim_level=i) !eyeroll + call read_data(fileobj, "var0_min", cdata_out(1,1,1,1), unlim_dim_level=i) call check_data_0d(cdata_out(1,1,1,1), i) cdata_out = -999_r4_kind diff --git a/test_fms/diag_manager/test_time_max.sh b/test_fms/diag_manager/test_time_max.sh index 5a35179b2f..b9a62b4d74 100755 --- a/test_fms/diag_manager/test_time_max.sh +++ b/test_fms/diag_manager/test_time_max.sh @@ -29,25 +29,62 @@ if [ -z "${skipflag}" ]; then output_dir #TODO replace with yaml diag_table and set diag_manager_nml::use_modern_diag=.true. -cat <<_EOF > diag_table -test_max -2 1 1 0 0 0 - -"test_max", 6, "hours", 1, "hours", "time" -"test_max_regional", 6, "hours", 1, "hours", "time" - -"ocn_mod", "var0", "var0_max", "test_max", "all", "max", "none", 2 -"ocn_mod", "var1", "var1_max", "test_max", "all", "max", "none", 2 -"ocn_mod", "var2", "var2_max", "test_max", "all", "max", "none", 2 -"ocn_mod", "var3", "var3_max", "test_max", "all", "max", "none", 2 - -"ocn_mod", "var3", "var3_Z", "test_max", "all", "max", "-1 -1 -1 -1 2. 3.", 2 - -"ocn_mod", "var3", "var3_max", "test_max_regional", "all", "max", "78. 81. 78. 81. 2. 3.", 2 #chosen by MKL +cat <<_EOF > diag_table.yaml +title: test_max +base_date: 2 1 1 0 0 0 +diag_files: +- file_name: test_max + time_units: hours + unlimdim: time + freq: 6 hours + varlist: + - module: ocn_mod + var_name: var0 + output_name: var0_max + reduction: max + kind: r4 + - module: ocn_mod + var_name: var1 + output_name: var1_max + reduction: max + kind: r4 + - module: ocn_mod + var_name: var2 + output_name: var2_max + reduction: max + kind: r4 + - module: ocn_mod + var_name: var3 + output_name: var3_max + reduction: max + kind: r4 + - module: ocn_mod + var_name: var3 + output_name: var3_Z_max + reduction: max + zbounds: 2. 3. + kind: r4 +- file_name: test_max_regional + time_units: hours + unlimdim: time + sub_region: + - grid_type: latlon + corner1: 78. 78. + corner2: 78. 78. + corner3: 81. 81. + corner4: 81. 81. + freq: 6 hours + varlist: + - module: ocn_mod + var_name: var3 + output_name: var3_max + reduction: max + zbounds: 2. 3. + kind: r4 _EOF my_test_count=1 -printf "&test_reduction_methods_nml \n test_case = 0 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 0 \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -56,7 +93,7 @@ test_expect_success "Checking answers for the "max" reduction method (test $my_t ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 0 \n mask_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n &test_reduction_methods_nml \n test_case = 0 \n mask_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method, logical mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -65,7 +102,7 @@ test_expect_success "Checking answers for the "max" reduction method, logical ma ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 0 \n mask_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n &test_reduction_methods_nml \n test_case = 0 \n mask_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method, real mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -73,9 +110,9 @@ test_expect_success "Checking answers for the "max" reduction method, real mask mpirun -n 1 ../check_time_max ' -export OMP_NUM_THREADS=2 +export OMP_NUM_THREADS=1 my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method with openmp (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -84,7 +121,7 @@ test_expect_success "Checking answers for the "max" reduction method with openmp ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 1 \n mask_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 1 \n mask_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method with openmp, logical mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -93,17 +130,17 @@ test_expect_success "Checking answers for the "max" reduction method with openmp ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 1 \n mask_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 1 \n mask_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method with openmp, real mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' test_expect_success "Checking answers for the "max" reduction method with openmp, real mask (test $my_test_count)" ' mpirun -n 1 ../check_time_max ' -export OMP_NUM_THREADS=1 +export OMP_NUM_THREADS=2 my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method with halo output (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -112,7 +149,7 @@ test_expect_success "Checking answers for the "max" reduction method with halo o ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 2 \n mask_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 2 \n mask_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method with halo output with logical mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -121,7 +158,7 @@ test_expect_success "Checking answers for the "max" reduction method with halo o ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 2 \n mask_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 2 \n mask_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "max" reduction method with halo output with real mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' diff --git a/test_fms/diag_manager/test_time_min.sh b/test_fms/diag_manager/test_time_min.sh index 7049dc6abb..f0305d15a0 100755 --- a/test_fms/diag_manager/test_time_min.sh +++ b/test_fms/diag_manager/test_time_min.sh @@ -29,25 +29,62 @@ if [ -z "${skipflag}" ]; then output_dir #TODO replace with yaml diag_table and set diag_manager_nml::use_modern_diag=.true. -cat <<_EOF > diag_table -test_min -2 1 1 0 0 0 - -"test_min", 6, "hours", 1, "hours", "time" -"test_min_regional", 6, "hours", 1, "hours", "time" - -"ocn_mod", "var0", "var0_min", "test_min", "all", "min", "none", 2 -"ocn_mod", "var1", "var1_min", "test_min", "all", "min", "none", 2 -"ocn_mod", "var2", "var2_min", "test_min", "all", "min", "none", 2 -"ocn_mod", "var3", "var3_min", "test_min", "all", "min", "none", 2 - -"ocn_mod", "var3", "var3_Z", "test_min", "all", "min", "-1 -1 -1 -1 2. 3.", 2 - -"ocn_mod", "var3", "var3_min", "test_min_regional", "all", "min", "78. 81. 78. 81. 2. 3.", 2 #chosen by MKL +cat <<_EOF > diag_table.yaml +title: test_min +base_date: 2 1 1 0 0 0 +diag_files: +- file_name: test_min + time_units: hours + unlimdim: time + freq: 6 hours + varlist: + - module: ocn_mod + var_name: var0 + output_name: var0_min + reduction: min + kind: r4 + - module: ocn_mod + var_name: var1 + output_name: var1_min + reduction: min + kind: r4 + - module: ocn_mod + var_name: var2 + output_name: var2_min + reduction: min + kind: r4 + - module: ocn_mod + var_name: var3 + output_name: var3_min + reduction: min + kind: r4 + - module: ocn_mod + var_name: var3 + output_name: var3_Z_min + reduction: min + zbounds: 2. 3. + kind: r4 +- file_name: test_min_regional + time_units: hours + unlimdim: time + sub_region: + - grid_type: latlon + corner1: 78. 78. + corner2: 78. 78. + corner3: 81. 81. + corner4: 81. 81. + freq: 6 hours + varlist: + - module: ocn_mod + var_name: var3 + output_name: var3_min + reduction: min + zbounds: 2. 3. + kind: r4 _EOF my_test_count=1 -printf "&test_reduction_methods_nml \n test_case = 0 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 0 \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -56,7 +93,7 @@ test_expect_success "Checking answers for the "min" reduction method (test $my_t ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 0 \n mask_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n &test_reduction_methods_nml \n test_case = 0 \n mask_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method, logical mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -65,7 +102,7 @@ test_expect_success "Checking answers for the "min" reduction method, logical ma ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 0 \n mask_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n &test_reduction_methods_nml \n test_case = 0 \n mask_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method, real mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -75,7 +112,7 @@ test_expect_success "Checking answers for the "min" reduction method, real mask export OMP_NUM_THREADS=2 my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method with openmp (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -84,7 +121,7 @@ test_expect_success "Checking answers for the "min" reduction method with openmp ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 1 \n mask_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 1 \n mask_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method with openmp, logical mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -93,7 +130,7 @@ test_expect_success "Checking answers for the "min" reduction method with openmp ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 1 \n mask_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 1 \n mask_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method with openmp, real mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -103,7 +140,7 @@ test_expect_success "Checking answers for the "min" reduction method with openmp export OMP_NUM_THREADS=1 my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method with halo output (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -112,7 +149,7 @@ test_expect_success "Checking answers for the "min" reduction method with halo o ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 2 \n mask_case = 1 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 2 \n mask_case = 1 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method with halo output with logical mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods ' @@ -121,7 +158,7 @@ test_expect_success "Checking answers for the "min" reduction method with halo o ' my_test_count=`expr $my_test_count + 1` -printf "&test_reduction_methods_nml \n test_case = 2 \n mask_case = 2 \n \n/" | cat > input.nml +printf "&diag_manager_nml \n use_modern_diag=.true. \n / \n&test_reduction_methods_nml \n test_case = 2 \n mask_case = 2 \n \n/" | cat > input.nml test_expect_success "Running diag_manager with "min" reduction method with halo output with real mask (test $my_test_count)" ' mpirun -n 6 ../test_reduction_methods '