From 1e6bdd6a1788bdafa7842d66e47d7326e41764f1 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Sun, 3 Jan 2021 06:44:25 -0500 Subject: [PATCH 1/6] Remove unused module use statements Removed unused module use statements in various modules, to help eliminate apparent but inaccurate module dependencies, and to facilitate the migration to FMS2. All answers are bitwise identical. --- src/core/MOM_dynamics_split_RK2.F90 | 2 +- src/core/MOM_dynamics_unsplit.F90 | 1 - src/core/MOM_dynamics_unsplit_RK2.F90 | 1 - src/framework/MOM_diag_remap.F90 | 1 - src/framework/MOM_horizontal_regridding.F90 | 11 ++++----- src/framework/MOM_transform_FMS.F90 | 2 +- .../MOM_tracer_initialization_from_Z.F90 | 24 ++++++------------- src/tracer/advection_test_tracer.F90 | 2 +- src/tracer/boundary_impulse_tracer.F90 | 5 ++-- src/tracer/dye_example.F90 | 2 +- src/tracer/pseudo_salt_tracer.F90 | 5 ++-- src/user/BFB_surface_forcing.F90 | 1 - src/user/ISOMIP_initialization.F90 | 4 +--- src/user/dumbbell_surface_forcing.F90 | 1 - src/user/user_revise_forcing.F90 | 2 +- 15 files changed, 21 insertions(+), 43 deletions(-) diff --git a/src/core/MOM_dynamics_split_RK2.F90 b/src/core/MOM_dynamics_split_RK2.F90 index 519f510239..4ea6734511 100644 --- a/src/core/MOM_dynamics_split_RK2.F90 +++ b/src/core/MOM_dynamics_split_RK2.F90 @@ -27,7 +27,7 @@ module MOM_dynamics_split_RK2 use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_get_input, only : directories -use MOM_io, only : MOM_io_init, vardesc, var_desc +use MOM_io, only : vardesc, var_desc use MOM_restart, only : register_restart_field, register_restart_pair use MOM_restart, only : query_initialized, save_restart use MOM_restart, only : restart_init, is_new_run, MOM_restart_CS diff --git a/src/core/MOM_dynamics_unsplit.F90 b/src/core/MOM_dynamics_unsplit.F90 index 6b9aa8e759..30544b0193 100644 --- a/src/core/MOM_dynamics_unsplit.F90 +++ b/src/core/MOM_dynamics_unsplit.F90 @@ -68,7 +68,6 @@ module MOM_dynamics_unsplit use MOM_error_handler, only : MOM_error, MOM_mesg, FATAL, WARNING, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_get_input, only : directories -use MOM_io, only : MOM_io_init use MOM_restart, only : register_restart_field, query_initialized, save_restart use MOM_restart, only : restart_init, MOM_restart_CS use MOM_time_manager, only : time_type, real_to_time, operator(+) diff --git a/src/core/MOM_dynamics_unsplit_RK2.F90 b/src/core/MOM_dynamics_unsplit_RK2.F90 index 4181ab519d..2f93561c3f 100644 --- a/src/core/MOM_dynamics_unsplit_RK2.F90 +++ b/src/core/MOM_dynamics_unsplit_RK2.F90 @@ -67,7 +67,6 @@ module MOM_dynamics_unsplit_RK2 use MOM_error_handler, only : MOM_set_verbosity use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_get_input, only : directories -use MOM_io, only : MOM_io_init use MOM_restart, only : register_restart_field, query_initialized, save_restart use MOM_restart, only : restart_init, MOM_restart_CS use MOM_time_manager, only : time_type, time_type_to_real, operator(+) diff --git a/src/framework/MOM_diag_remap.F90 b/src/framework/MOM_diag_remap.F90 index 4e12abaa5b..6d1fa7b6fa 100644 --- a/src/framework/MOM_diag_remap.F90 +++ b/src/framework/MOM_diag_remap.F90 @@ -80,7 +80,6 @@ module MOM_diag_remap use coord_sigma, only : build_sigma_column use coord_rho, only : build_rho_column -use diag_axis_mod, only : get_diag_axis_name use diag_manager_mod, only : diag_axis_init use MOM_debugging, only : check_column_integrals diff --git a/src/framework/MOM_horizontal_regridding.F90 b/src/framework/MOM_horizontal_regridding.F90 index 66f58b5b9d..8af6129812 100644 --- a/src/framework/MOM_horizontal_regridding.F90 +++ b/src/framework/MOM_horizontal_regridding.F90 @@ -24,15 +24,12 @@ module MOM_horizontal_regridding use MOM_time_manager, only : get_external_field_axes, get_external_field_missing use MOM_transform_FMS, only : time_interp_external => rotated_time_interp_external use MOM_variables, only : thermo_var_ptrs -use mpp_io_mod, only : axistype -use mpp_domains_mod, only : mpp_global_field, mpp_get_compute_domain -use mpp_mod, only : mpp_broadcast,mpp_root_pe,mpp_sync,mpp_sync_self -use mpp_mod, only : mpp_max -use horiz_interp_mod, only : horiz_interp_new, horiz_interp,horiz_interp_type + +use mpp_io_mod, only : axistype, mpp_get_axis_data +use mpp_mod, only : mpp_broadcast, mpp_sync, mpp_sync_self, mpp_max +use horiz_interp_mod, only : horiz_interp_new, horiz_interp, horiz_interp_type use horiz_interp_mod, only : horiz_interp_init, horiz_interp_del -use mpp_io_mod, only : mpp_get_axis_data -use mpp_io_mod, only : MPP_SINGLE use netcdf implicit none ; private diff --git a/src/framework/MOM_transform_FMS.F90 b/src/framework/MOM_transform_FMS.F90 index 97e0be85f6..572a9717dc 100644 --- a/src/framework/MOM_transform_FMS.F90 +++ b/src/framework/MOM_transform_FMS.F90 @@ -7,7 +7,7 @@ module MOM_transform_FMS use MOM_error_handler, only : MOM_error, FATAL use MOM_io, only : fieldtype, write_field use mpp_domains_mod, only : domain2D -use fms_mod, only : mpp_chksum +use mpp_mod, only : mpp_chksum use time_manager_mod, only : time_type use time_interp_external_mod, only : time_interp_external diff --git a/src/initialization/MOM_tracer_initialization_from_Z.F90 b/src/initialization/MOM_tracer_initialization_from_Z.F90 index 1a4c5bd011..12235ddd87 100644 --- a/src/initialization/MOM_tracer_initialization_from_Z.F90 +++ b/src/initialization/MOM_tracer_initialization_from_Z.F90 @@ -4,27 +4,17 @@ module MOM_tracer_initialization_from_Z ! This file is part of MOM6. See LICENSE.md for the license. use MOM_debugging, only : hchksum -use MOM_coms, only : max_across_PEs, min_across_PEs use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end -use MOM_cpu_clock, only : CLOCK_ROUTINE, CLOCK_LOOP -use MOM_density_integrals, only : int_specific_vol_dp -use MOM_domains, only : pass_var, pass_vector, sum_across_PEs, broadcast -use MOM_domains, only : root_PE, To_All, SCALAR_PAIR, CGRID_NE, AGRID -use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING, is_root_pe +use MOM_cpu_clock, only : CLOCK_ROUTINE, CLOCK_LOOP +use MOM_domains, only : pass_var +use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint -use MOM_file_parser, only : get_param, read_param, log_param, param_file_type -use MOM_file_parser, only : log_version -use MOM_get_input, only : directories -use MOM_grid, only : ocean_grid_type, isPointInCell +use MOM_file_parser, only : get_param, param_file_type, log_version +use MOM_grid, only : ocean_grid_type use MOM_horizontal_regridding, only : myStats, horiz_interp_and_extrap_tracer -use MOM_regridding, only : regridding_CS use MOM_remapping, only : remapping_CS, initialize_remapping -use MOM_remapping, only : remapping_core_h -use MOM_string_functions, only : uppercase use MOM_unit_scaling, only : unit_scale_type -use MOM_variables, only : thermo_var_ptrs -use MOM_verticalGrid, only : verticalGrid_type, setVerticalGridAxes -use MOM_EOS, only : calculate_density, calculate_density_derivs, EOS_type +use MOM_verticalGrid, only : verticalGrid_type use MOM_ALE, only : ALE_remap_scalar implicit none ; private @@ -42,7 +32,7 @@ module MOM_tracer_initialization_from_Z contains -!> Initializes a tracer from a z-space data file. +!> Initializes a tracer from a z-space data file, including any lateral regridding that is needed. subroutine MOM_initialize_tracer_from_Z(h, tr, G, GV, US, PF, src_file, src_var_nam, & src_var_unit_conversion, src_var_record, homogenize, & useALEremapping, remappingScheme, src_var_gridspec ) diff --git a/src/tracer/advection_test_tracer.F90 b/src/tracer/advection_test_tracer.F90 index b1d657d6e2..3aa65e8b3c 100644 --- a/src/tracer/advection_test_tracer.F90 +++ b/src/tracer/advection_test_tracer.F90 @@ -9,7 +9,7 @@ module advection_test_tracer use MOM_forcing_type, only : forcing use MOM_grid, only : ocean_grid_type use MOM_hor_index, only : hor_index_type -use MOM_io, only : file_exists, read_data, slasher, vardesc, var_desc, query_vardesc +use MOM_io, only : slasher, vardesc, var_desc, query_vardesc use MOM_open_boundary, only : ocean_OBC_type use MOM_restart, only : query_initialized, MOM_restart_CS use MOM_sponge, only : set_up_sponge_field, sponge_CS diff --git a/src/tracer/boundary_impulse_tracer.F90 b/src/tracer/boundary_impulse_tracer.F90 index da76cb3026..fc85b5c3ec 100644 --- a/src/tracer/boundary_impulse_tracer.F90 +++ b/src/tracer/boundary_impulse_tracer.F90 @@ -9,7 +9,7 @@ module boundary_impulse_tracer use MOM_forcing_type, only : forcing use MOM_grid, only : ocean_grid_type use MOM_hor_index, only : hor_index_type -use MOM_io, only : file_exists, read_data, slasher, vardesc, var_desc, query_vardesc +use MOM_io, only : vardesc, var_desc, query_vardesc use MOM_open_boundary, only : ocean_OBC_type use MOM_restart, only : register_restart_field, query_initialized, MOM_restart_CS use MOM_sponge, only : set_up_sponge_field, sponge_CS @@ -18,8 +18,7 @@ module boundary_impulse_tracer use MOM_tracer_diabatic, only : tracer_vertdiff, applyTracerBoundaryFluxesInOut use MOM_tracer_Z_init, only : tracer_Z_init use MOM_unit_scaling, only : unit_scale_type -use MOM_variables, only : surface -use MOM_variables, only : thermo_var_ptrs +use MOM_variables, only : surface, thermo_var_ptrs use MOM_verticalGrid, only : verticalGrid_type use coupler_types_mod, only : coupler_type_set_data, ind_csurf diff --git a/src/tracer/dye_example.F90 b/src/tracer/dye_example.F90 index cd17415b21..8a970fa9ca 100644 --- a/src/tracer/dye_example.F90 +++ b/src/tracer/dye_example.F90 @@ -9,7 +9,7 @@ module regional_dyes use MOM_forcing_type, only : forcing use MOM_grid, only : ocean_grid_type use MOM_hor_index, only : hor_index_type -use MOM_io, only : file_exists, read_data, slasher, vardesc, var_desc, query_vardesc +use MOM_io, only : vardesc, var_desc, query_vardesc use MOM_open_boundary, only : ocean_OBC_type use MOM_restart, only : query_initialized, MOM_restart_CS use MOM_sponge, only : set_up_sponge_field, sponge_CS diff --git a/src/tracer/pseudo_salt_tracer.F90 b/src/tracer/pseudo_salt_tracer.F90 index 95396a3b58..11238fee89 100644 --- a/src/tracer/pseudo_salt_tracer.F90 +++ b/src/tracer/pseudo_salt_tracer.F90 @@ -11,7 +11,7 @@ module pseudo_salt_tracer use MOM_forcing_type, only : forcing use MOM_grid, only : ocean_grid_type use MOM_hor_index, only : hor_index_type -use MOM_io, only : file_exists, read_data, slasher, vardesc, var_desc, query_vardesc +use MOM_io, only : vardesc, var_desc, query_vardesc use MOM_open_boundary, only : ocean_OBC_type use MOM_restart, only : query_initialized, MOM_restart_CS use MOM_sponge, only : set_up_sponge_field, sponge_CS @@ -20,8 +20,7 @@ module pseudo_salt_tracer use MOM_tracer_diabatic, only : tracer_vertdiff, applyTracerBoundaryFluxesInOut use MOM_tracer_Z_init, only : tracer_Z_init use MOM_unit_scaling, only : unit_scale_type -use MOM_variables, only : surface -use MOM_variables, only : thermo_var_ptrs +use MOM_variables, only : surface, thermo_var_ptrs use MOM_verticalGrid, only : verticalGrid_type use coupler_types_mod, only : coupler_type_set_data, ind_csurf diff --git a/src/user/BFB_surface_forcing.F90 b/src/user/BFB_surface_forcing.F90 index d06262b7cf..3963d4d90d 100644 --- a/src/user/BFB_surface_forcing.F90 +++ b/src/user/BFB_surface_forcing.F90 @@ -10,7 +10,6 @@ module BFB_surface_forcing use MOM_file_parser, only : get_param, param_file_type, log_version use MOM_forcing_type, only : forcing, allocate_forcing_type use MOM_grid, only : ocean_grid_type -use MOM_io, only : file_exists, read_data use MOM_safe_alloc, only : safe_alloc_ptr use MOM_time_manager, only : time_type, operator(+), operator(/) use MOM_tracer_flow_control, only : call_tracer_set_forcing diff --git a/src/user/ISOMIP_initialization.F90 b/src/user/ISOMIP_initialization.F90 index d125495d7f..a0b8990e62 100644 --- a/src/user/ISOMIP_initialization.F90 +++ b/src/user/ISOMIP_initialization.F90 @@ -10,9 +10,7 @@ module ISOMIP_initialization use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_get_input, only : directories use MOM_grid, only : ocean_grid_type -use MOM_io, only : file_exists -use MOM_io, only : MOM_read_data -use MOM_io, only : slasher +use MOM_io, only : file_exists, MOM_read_data, slasher use MOM_unit_scaling, only : unit_scale_type use MOM_variables, only : thermo_var_ptrs use MOM_verticalGrid, only : verticalGrid_type diff --git a/src/user/dumbbell_surface_forcing.F90 b/src/user/dumbbell_surface_forcing.F90 index 4b5bf5a2fb..ea27d01cdc 100644 --- a/src/user/dumbbell_surface_forcing.F90 +++ b/src/user/dumbbell_surface_forcing.F90 @@ -10,7 +10,6 @@ module dumbbell_surface_forcing use MOM_file_parser, only : get_param, param_file_type, log_version use MOM_forcing_type, only : forcing, allocate_forcing_type use MOM_grid, only : ocean_grid_type -use MOM_io, only : file_exists, read_data use MOM_safe_alloc, only : safe_alloc_ptr use MOM_time_manager, only : time_type, operator(+), operator(/), get_time use MOM_tracer_flow_control, only : call_tracer_set_forcing diff --git a/src/user/user_revise_forcing.F90 b/src/user/user_revise_forcing.F90 index c53451f4e8..bf31ca02f8 100644 --- a/src/user/user_revise_forcing.F90 +++ b/src/user/user_revise_forcing.F90 @@ -8,7 +8,7 @@ module user_revise_forcing use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_forcing_type, only : forcing use MOM_grid, only : ocean_grid_type -use MOM_io, only : file_exists, read_data +use MOM_io, only : file_exists, MOM_read_data use MOM_restart, only : register_restart_field, MOM_restart_CS use MOM_time_manager, only : time_type, operator(+), operator(/) use MOM_tracer_flow_control, only : call_tracer_set_forcing From 9b0b8db88ad92a62b36afbd8005cab182e60fb77 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Sun, 3 Jan 2021 09:45:39 -0500 Subject: [PATCH 2/6] Use MOM framework routines in MOM_open_boundary Use MOM framework interfaces in MOM_open_boundary in place of direct calls to mpp routines, to facilitate the migration to FMS2. All answers are bitwise identical. --- src/core/MOM_open_boundary.F90 | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/MOM_open_boundary.F90 b/src/core/MOM_open_boundary.F90 index 46d144a8c6..0232ff91ff 100644 --- a/src/core/MOM_open_boundary.F90 +++ b/src/core/MOM_open_boundary.F90 @@ -5,13 +5,12 @@ module MOM_open_boundary use MOM_array_transform, only : rotate_array, rotate_array_pair use MOM_array_transform, only : allocate_rotated_array -use MOM_coms, only : sum_across_PEs +use MOM_coms, only : sum_across_PEs, Set_PElist, Get_PElist, PE_here, num_PEs use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, CLOCK_ROUTINE use MOM_diag_mediator, only : diag_ctrl, time_type use MOM_domains, only : pass_var, pass_vector use MOM_domains, only : To_All, SCALAR_PAIR, CGRID_NE, CORNER -use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING, is_root_pe -use MOM_error_handler, only : NOTE +use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING, NOTE, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type, log_param use MOM_grid, only : ocean_grid_type, hor_index_type use MOM_dyn_horgrid, only : dyn_horgrid_type @@ -651,13 +650,11 @@ end subroutine open_boundary_config !> Allocate space for reading OBC data from files. It sets up the required vertical !! remapping. In the process, it does funky stuff with the MPI processes. subroutine initialize_segment_data(G, OBC, PF) - use mpp_mod, only : mpp_pe, mpp_set_current_pelist, mpp_get_current_pelist,mpp_npes - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(ocean_OBC_type), intent(inout) :: OBC !< Open boundary control structure - type(param_file_type), intent(in) :: PF !< Parameter file handle + type(ocean_OBC_type), intent(inout) :: OBC !< Open boundary control structure + type(param_file_type), intent(in) :: PF !< Parameter file handle - integer :: n,m,num_fields + integer :: n, m, num_fields character(len=1024) :: segstr character(len=256) :: filename character(len=20) :: segnam, suffix @@ -697,11 +694,11 @@ subroutine initialize_segment_data(G, OBC, PF) !< temporarily disable communication in order to read segment data independently - allocate(saved_pelist(0:mpp_npes()-1)) - call mpp_get_current_pelist(saved_pelist) - current_pe = mpp_pe() + allocate(saved_pelist(0:num_PEs()-1)) + call Get_PElist(saved_pelist) + current_pe = PE_here() single_pelist(1) = current_pe - call mpp_set_current_pelist(single_pelist) + call Set_PElist(single_pelist) do n=1, OBC%number_of_segments segment => OBC%segment(n) @@ -955,7 +952,7 @@ subroutine initialize_segment_data(G, OBC, PF) endif enddo - call mpp_set_current_pelist(saved_pelist) + call Set_PElist(saved_pelist) end subroutine initialize_segment_data From 611132731dd731b7f2f4d26bcde2188b218fafef Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Sun, 3 Jan 2021 09:46:01 -0500 Subject: [PATCH 3/6] Use MOM_read_data in RGC_initialization Use MOM_read_data in place of read_data in RGC_initialization to match the routines used in other modules and facilitate migration to FMS2. All answers are bitwise identical. --- src/user/RGC_initialization.F90 | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/user/RGC_initialization.F90 b/src/user/RGC_initialization.F90 index 70b9fcd4dc..1600aca5bd 100644 --- a/src/user/RGC_initialization.F90 +++ b/src/user/RGC_initialization.F90 @@ -28,8 +28,7 @@ module RGC_initialization use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_get_input, only : directories use MOM_grid, only : ocean_grid_type -use MOM_io, only : file_exists, read_data -use MOM_io, only : slasher +use MOM_io, only : file_exists, MOM_read_data, slasher use MOM_sponge, only : sponge_CS, set_up_sponge_field, initialize_sponge use MOM_sponge, only : set_up_sponge_ML_density use MOM_unit_scaling, only : unit_scale_type @@ -173,12 +172,12 @@ subroutine RGC_initialize_sponges(G, GV, US, tv, u, v, PF, use_ALE, CSp, ACSp) filename = trim(inputdir)//trim(state_file) if (.not.file_exists(filename, G%Domain)) & call MOM_error(FATAL, " RGC_initialize_sponges: Unable to open "//trim(filename)) - call read_data(filename,temp_var,T(:,:,:), domain=G%Domain%mpp_domain) - call read_data(filename,salt_var,S(:,:,:), domain=G%Domain%mpp_domain) + call MOM_read_data(filename, temp_var, T(:,:,:), G%Domain) + call MOM_read_data(filename, salt_var, S(:,:,:), G%Domain) if (use_ALE) then - call read_data(filename,h_var,h(:,:,:), domain=G%Domain%mpp_domain) + call MOM_read_data(filename, h_var, h(:,:,:), G%Domain) call pass_var(h, G%domain) !call initialize_ALE_sponge(Idamp, h, nz, G, PF, ACSp) @@ -201,7 +200,7 @@ subroutine RGC_initialize_sponges(G, GV, US, tv, u, v, PF, use_ALE, CSp, ACSp) else ! layer mode !read eta - call read_data(filename,eta_var,eta(:,:,:), domain=G%Domain%mpp_domain) + call MOM_read_data(filename, eta_var, eta(:,:,:), G%Domain) ! Set the inverse damping rates so that the model will know where to ! apply the sponges, along with the interface heights. From 0b019b66773b6b8589b68fe565193cab10e6307f Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Sun, 3 Jan 2021 09:58:00 -0500 Subject: [PATCH 4/6] Avoid using memory macros in MOM_random.F90 Expanded the SZI_ and SZJ_ macros in random_2d_ routines to eliminate any dependence on MOM_memory.h and facilitate the future compilation of MOM_random as a part of a MOM framework library. All answers are bitwise identical. --- src/framework/MOM_random.F90 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/framework/MOM_random.F90 b/src/framework/MOM_random.F90 index 161236572c..21e3223a03 100644 --- a/src/framework/MOM_random.F90 +++ b/src/framework/MOM_random.F90 @@ -11,7 +11,7 @@ module MOM_random use MersenneTwister_mod, only : getRandomReal ! Generates a random number use MersenneTwister_mod, only : getRandomPositiveInt ! Generates a random positive integer -use MOM_io, only : stdout, stderr +use iso_fortran_env, only : stdout=>output_unit, stderr=>error_unit implicit none ; private @@ -23,8 +23,6 @@ module MOM_random public :: random_2d_norm public :: random_unit_tests -#include - !> Container for pseudo-random number generators type, public :: PRNG ; private @@ -63,7 +61,7 @@ end function random_norm subroutine random_2d_01(CS, HI, rand) type(PRNG), intent(inout) :: CS !< Container for pseudo-random number generators type(hor_index_type), intent(in) :: HI !< Horizontal index structure - real, dimension(SZI_(HI),SZJ_(HI)), intent(out) :: rand !< Random numbers between 0 and 1 + real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), intent(out) :: rand !< Random numbers between 0 and 1 ! Local variables integer :: i,j @@ -80,7 +78,7 @@ end subroutine random_2d_01 subroutine random_2d_norm(CS, HI, rand) type(PRNG), intent(inout) :: CS !< Container for pseudo-random number generators type(hor_index_type), intent(in) :: HI !< Horizontal index structure - real, dimension(SZI_(HI),SZJ_(HI)), intent(out) :: rand !< Random numbers between 0 and 1 + real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), intent(out) :: rand !< Random numbers between 0 and 1 ! Local variables integer :: i,j,n From aed5a680babcf4123c79df1fb4dd4758dbd79ef8 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Sun, 3 Jan 2021 10:28:46 -0500 Subject: [PATCH 5/6] +Add the new routine read_field_chksum to MOM_io Added the new routine read_field_chksum to MOM_io.F90, so that all calls to the FMS i/o layer can be directed via MOM_io.F90, in order to facilitate the painless and compartmentalized migration to FMS2. Also added a 0-d variant for MOM_read_data, and standardized the control-flag and subroutine aliases used in MOM_io.F90. All answers are bitwise identical, but there are new public interfaces. --- src/framework/MOM_io.F90 | 78 +++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/src/framework/MOM_io.F90 b/src/framework/MOM_io.F90 index d13dddc3c7..529c725274 100644 --- a/src/framework/MOM_io.F90 +++ b/src/framework/MOM_io.F90 @@ -16,19 +16,19 @@ module MOM_io use ensemble_manager_mod, only : get_ensemble_id use fms_mod, only : write_version_number, open_namelist_file, check_nml_error use fms_io_mod, only : file_exist, field_size, read_data -use fms_io_mod, only : field_exists => field_exist, io_infra_end=>fms_io_exit -use fms_io_mod, only : get_filename_appendix => get_filename_appendix +use fms_io_mod, only : field_exists=>field_exist, io_infra_end=>fms_io_exit +use fms_io_mod, only : get_filename_appendix=>get_filename_appendix use mpp_domains_mod, only : domain1d, domain2d, mpp_get_domain_components use mpp_domains_mod, only : CENTER, CORNER, NORTH_FACE=>NORTH, EAST_FACE=>EAST use mpp_io_mod, only : open_file => mpp_open, close_file => mpp_close -use mpp_io_mod, only : mpp_write_meta, write_field => mpp_write, mpp_get_info -use mpp_io_mod, only : mpp_get_atts, mpp_get_axes, get_axis_data=>mpp_get_axis_data, axistype -use mpp_io_mod, only : mpp_get_fields, fieldtype, axistype, flush_file => mpp_flush +use mpp_io_mod, only : mpp_write_meta, write_field => mpp_write +use mpp_io_mod, only : mpp_get_atts, mpp_attribute_exist +use mpp_io_mod, only : mpp_get_axes, axistype, get_axis_data=>mpp_get_axis_data +use mpp_io_mod, only : mpp_get_fields, fieldtype, flush_file=>mpp_flush use mpp_io_mod, only : APPEND_FILE=>MPP_APPEND, ASCII_FILE=>MPP_ASCII use mpp_io_mod, only : MULTIPLE=>MPP_MULTI, NETCDF_FILE=>MPP_NETCDF use mpp_io_mod, only : OVERWRITE_FILE=>MPP_OVERWR, READONLY_FILE=>MPP_RDONLY use mpp_io_mod, only : SINGLE_FILE=>MPP_SINGLE, WRITEONLY_FILE=>MPP_WRONLY -use mpp_io_mod, only : MPP_APPEND, MPP_MULTI, MPP_OVERWR, MPP_NETCDF, MPP_RDONLY use mpp_io_mod, only : get_file_info=>mpp_get_info, get_file_atts=>mpp_get_atts use mpp_io_mod, only : get_file_fields=>mpp_get_fields, get_file_times=>mpp_get_times use mpp_io_mod, only : io_infra_init=>mpp_io_init @@ -40,7 +40,7 @@ module MOM_io public :: close_file, create_file, field_exists, field_size, fieldtype, get_filename_appendix public :: file_exists, flush_file, get_file_info, get_file_atts, get_file_fields -public :: get_file_times, open_file, read_axis_data, read_data +public :: get_file_times, open_file, read_axis_data, read_data, read_field_chksum public :: num_timelevels, MOM_read_data, MOM_read_vector, ensembler public :: reopen_file, slasher, write_field, write_version_number, MOM_io_init public :: open_namelist_file, check_nml_error, io_infra_init, io_infra_end @@ -77,6 +77,7 @@ module MOM_io module procedure MOM_read_data_3d module procedure MOM_read_data_2d module procedure MOM_read_data_1d + module procedure MOM_read_data_0d end interface !> Read a pair of data fields representing the two components of a vector from a file @@ -162,9 +163,9 @@ subroutine create_file(unit, filename, vars, novars, fields, threading, timeunit if (domain_set) one_file = (thread == SINGLE_FILE) if (one_file) then - call open_file(unit, filename, MPP_OVERWR, MPP_NETCDF, threading=thread) + call open_file(unit, filename, OVERWRITE_FILE, NETCDF_FILE, threading=thread) else - call open_file(unit, filename, MPP_OVERWR, MPP_NETCDF, domain=Domain%mpp_domain) + call open_file(unit, filename, OVERWRITE_FILE, NETCDF_FILE, domain=Domain%mpp_domain) endif ! Define the coordinates. @@ -404,13 +405,13 @@ subroutine reopen_file(unit, filename, vars, novars, fields, threading, timeunit if (domain_set) one_file = (thread == SINGLE_FILE) if (one_file) then - call open_file(unit, filename, MPP_APPEND, MPP_NETCDF, threading=thread) + call open_file(unit, filename, APPEND_FILE, NETCDF_FILE, threading=thread) else - call open_file(unit, filename, MPP_APPEND, MPP_NETCDF, domain=Domain%mpp_domain) + call open_file(unit, filename, APPEND_FILE, NETCDF_FILE, domain=Domain%mpp_domain) endif if (unit < 0) return - call mpp_get_info(unit, ndim, nvar, natt, ntime) + call get_file_info(unit, ndim, nvar, natt, ntime) if (nvar == -1) then write (mesg,*) "Reopening file ",trim(filename)," apparently had ",nvar,& @@ -449,11 +450,11 @@ subroutine read_axis_data(filename, axis_name, var) type(axistype) :: time_axis character(len=32) :: name, units - call open_file(unit, trim(filename), action=MPP_RDONLY, form=MPP_NETCDF, & - threading=MPP_MULTI, fileset=SINGLE_FILE) + call open_file(unit, trim(filename), action=READONLY_FILE, form=NETCDF_FILE, & + threading=MULTIPLE, fileset=SINGLE_FILE) !Find the number of variables (nvar) in this file - call mpp_get_info(unit, ndim, nvar, natt, ntime) + call get_file_info(unit, ndim, nvar, natt, ntime) ! ------------------------------------------------------------------- ! Allocate space for the number of axes in the data file. ! ------------------------------------------------------------------- @@ -462,7 +463,7 @@ subroutine read_axis_data(filename, axis_name, var) axis_found = .false. do i = 1, ndim - call mpp_get_atts(axes(i), name=name,len=len,units=units) + call get_file_atts(axes(i), name=name, len=len, units=units) if (name == axis_name) then axis_found = .true. call get_axis_data(axes(i),var) @@ -477,6 +478,23 @@ subroutine read_axis_data(filename, axis_name, var) end subroutine read_axis_data +subroutine read_field_chksum(field, chksum, valid_chksum) + type(fieldtype), intent(in) :: field !< The field whose checksum attribute is to be read. + integer(kind=8), intent(out) :: chksum !< The checksum for the field. + logical, intent(out) :: valid_chksum !< If true, chksum has been successfully read. + ! Local variables + integer(kind=8), dimension(3) :: checksum_file + + checksum_file(:) = -1 + valid_chksum = mpp_attribute_exist(field, "checksum") + if (valid_chksum) then + call mpp_get_atts(field, checksum=checksum_file) + chksum = checksum_file(1) + else + chksum = -1 + endif +end subroutine read_field_chksum + !> This function determines how many time levels a variable has. function num_timelevels(filename, varname, min_dims) result(n_time) character(len=*), intent(in) :: filename !< name of the file to read @@ -519,7 +537,6 @@ function num_timelevels(filename, varname, min_dims) result(n_time) return endif - allocate(varids(nvars)) status = nf90_inq_varids(ncid, nvars, varids) @@ -848,7 +865,26 @@ function FMS_file_exists(filename, domain, no_domain) end function FMS_file_exists -!> This function uses the fms_io function read_data to read 1-D + +!> This function uses the fms_io function read_data to read a scalar +!! data field named "fieldname" from file "filename". +subroutine MOM_read_data_0d(filename, fieldname, data, timelevel, scale) + character(len=*), intent(in) :: filename !< The name of the file to read + character(len=*), intent(in) :: fieldname !< The variable name of the data in the file + real, intent(inout) :: data !< The 1-dimensional array into which the data + integer, optional, intent(in) :: timelevel !< The time level in the file to read + real, optional, intent(in) :: scale !< A scaling factor that the field is multiplied + !! by before it is returned. + + call read_data(filename, fieldname, data, timelevel=timelevel, no_domain=.true.) + + if (present(scale)) then ; if (scale /= 1.0) then + data = scale*data + endif ; endif + +end subroutine MOM_read_data_0d + +!> This function uses the fms_io function read_data to read a 1-D !! data field named "fieldname" from file "filename". subroutine MOM_read_data_1d(filename, fieldname, data, timelevel, scale) character(len=*), intent(in) :: filename !< The name of the file to read @@ -879,7 +915,7 @@ subroutine MOM_read_data_2d(filename, fieldname, data, MOM_Domain, & integer, optional, intent(in) :: timelevel !< The time level in the file to read integer, optional, intent(in) :: position !< A flag indicating where this data is located real, optional, intent(in) :: scale !< A scaling factor that the field is multiplied - !! by before they are returned. + !! by before it is returned. integer :: is, ie, js, je @@ -907,7 +943,7 @@ subroutine MOM_read_data_3d(filename, fieldname, data, MOM_Domain, & integer, optional, intent(in) :: timelevel !< The time level in the file to read integer, optional, intent(in) :: position !< A flag indicating where this data is located real, optional, intent(in) :: scale !< A scaling factor that the field is multiplied - !! by before they are returned. + !! by before it is returned. integer :: is, ie, js, je @@ -935,7 +971,7 @@ subroutine MOM_read_data_4d(filename, fieldname, data, MOM_Domain, & integer, optional, intent(in) :: timelevel !< The time level in the file to read integer, optional, intent(in) :: position !< A flag indicating where this data is located real, optional, intent(in) :: scale !< A scaling factor that the field is multiplied - !! by before they are returned. + !! by before it is returned. integer :: is, ie, js, je From aea16f7302d52fed890b8c4e79876029a4ebbb5c Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Sun, 3 Jan 2021 11:43:23 -0500 Subject: [PATCH 6/6] Use read_field_chksum in MOM_restart Use read_field_chksum and MOM_read_data in MOM_restart. Also internally renamed mpp_chksum to just chksum in MOM_restart to aid in identifying unfiltered dependencies on FMS in MOM_restart.F90. All answers are bitwise identical. --- src/framework/MOM_restart.F90 | 71 +++++++++++++++-------------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/src/framework/MOM_restart.F90 b/src/framework/MOM_restart.F90 index 7181a1f1b9..6e4e3d745b 100644 --- a/src/framework/MOM_restart.F90 +++ b/src/framework/MOM_restart.F90 @@ -3,24 +3,22 @@ module MOM_restart ! This file is part of MOM6. See LICENSE.md for the license. -use MOM_domains, only : pe_here, num_PEs +use MOM_domains, only : PE_here, num_PEs use MOM_error_handler, only : MOM_error, FATAL, WARNING, NOTE, is_root_pe use MOM_file_parser, only : get_param, log_param, log_version, param_file_type use MOM_string_functions, only : lowercase use MOM_grid, only : ocean_grid_type use MOM_io, only : create_file, fieldtype, file_exists, open_file, close_file -use MOM_io, only : MOM_read_data, read_data, get_filename_appendix +use MOM_io, only : MOM_read_data, read_data, get_filename_appendix, read_field_chksum use MOM_io, only : get_file_info, get_file_atts, get_file_fields, get_file_times use MOM_io, only : vardesc, var_desc, query_vardesc, modify_vardesc use MOM_io, only : MULTIPLE, NETCDF_FILE, READONLY_FILE, SINGLE_FILE use MOM_io, only : CENTER, CORNER, NORTH_FACE, EAST_FACE -use MOM_time_manager, only : time_type, time_type_to_real, real_to_time -use MOM_time_manager, only : days_in_month, get_date, set_date -use MOM_transform_FMS, only : mpp_chksum => rotated_mpp_chksum +use MOM_time_manager, only : time_type, time_type_to_real, real_to_time +use MOM_time_manager, only : days_in_month, get_date, set_date +use MOM_transform_FMS, only : chksum => rotated_mpp_chksum use MOM_transform_FMS, only : write_field => rotated_write_field -use MOM_verticalGrid, only : verticalGrid_type -use mpp_io_mod, only : mpp_attribute_exist, mpp_get_atts -use mpp_mod, only : mpp_pe +use MOM_verticalGrid, only : verticalGrid_type implicit none ; private @@ -116,7 +114,7 @@ module MOM_restart module procedure register_restart_field_ptr0d, register_restart_field_0d end interface -!> Register a pair of restart fieilds whose rotations map onto each other +!> Register a pair of restart fields whose rotations map onto each other interface register_restart_pair module procedure register_restart_pair_ptr2d module procedure register_restart_pair_ptr3d @@ -1010,18 +1008,15 @@ subroutine save_restart(directory, time, G, CS, time_stamped, filename, GV, num_ endif do m=start_var,next_var-1 if (associated(CS%var_ptr3d(m)%p)) then - check_val(m-start_var+1,1) = & - mpp_chksum(CS%var_ptr3d(m)%p(isL:ieL,jsL:jeL,:), turns=-turns) + check_val(m-start_var+1,1) = chksum(CS%var_ptr3d(m)%p(isL:ieL,jsL:jeL,:), turns=-turns) elseif (associated(CS%var_ptr2d(m)%p)) then - check_val(m-start_var+1,1) = & - mpp_chksum(CS%var_ptr2d(m)%p(isL:ieL,jsL:jeL), turns=-turns) + check_val(m-start_var+1,1) = chksum(CS%var_ptr2d(m)%p(isL:ieL,jsL:jeL), turns=-turns) elseif (associated(CS%var_ptr4d(m)%p)) then - check_val(m-start_var+1,1) = & - mpp_chksum(CS%var_ptr4d(m)%p(isL:ieL,jsL:jeL,:,:), turns=-turns) + check_val(m-start_var+1,1) = chksum(CS%var_ptr4d(m)%p(isL:ieL,jsL:jeL,:,:), turns=-turns) elseif (associated(CS%var_ptr1d(m)%p)) then - check_val(m-start_var+1,1) = mpp_chksum(CS%var_ptr1d(m)%p) + check_val(m-start_var+1,1) = chksum(CS%var_ptr1d(m)%p) elseif (associated(CS%var_ptr0d(m)%p)) then - check_val(m-start_var+1,1) = mpp_chksum(CS%var_ptr0d(m)%p,pelist=(/mpp_pe()/)) + check_val(m-start_var+1,1) = chksum(CS%var_ptr0d(m)%p, pelist=(/PE_here()/)) endif enddo @@ -1100,9 +1095,9 @@ subroutine restore_state(filename, directory, day, G, CS) real :: t1, t2 ! Two times. real, allocatable :: time_vals(:) type(fieldtype), allocatable :: fields(:) - logical :: check_exist, is_there_a_checksum - integer(kind=8),dimension(3) :: checksum_file - integer(kind=8) :: checksum_data + logical :: is_there_a_checksum ! Is there a valid checksum that should be checked. + integer(kind=8) :: checksum_file ! The checksum value recorded in the input file. + integer(kind=8) :: checksum_data ! The checksum value for the data that was read in. if (.not.associated(CS)) call MOM_error(FATAL, "MOM_restart " // & "restore_state: Module must be initialized before it is used.") @@ -1202,25 +1197,21 @@ subroutine restore_state(filename, directory, day, G, CS) do i=1, nvar call get_file_atts(fields(i),name=varname) if (lowercase(trim(varname)) == lowercase(trim(CS%restart_field(m)%var_name))) then - check_exist = mpp_attribute_exist(fields(i),"checksum") - checksum_file(:) = -1 checksum_data = -1 - is_there_a_checksum = .false. - if ( check_exist ) then - call mpp_get_atts(fields(i),checksum=checksum_file) - is_there_a_checksum = .true. + if (CS%checksum_required) then + call read_field_chksum(fields(i), checksum_file, is_there_a_checksum) + else + checksum_file = -1 + is_there_a_checksum = .false. ! Do not need to do data checksumming. endif - if (.NOT. CS%checksum_required) is_there_a_checksum = .false. ! Do not need to do data checksumming. if (associated(CS%var_ptr1d(m)%p)) then ! Read a 1d array, which should be invariant to domain decomposition. - call read_data(unit_path(n), varname, CS%var_ptr1d(m)%p, & - G%Domain%mpp_domain, timelevel=1) - if (is_there_a_checksum) checksum_data = mpp_chksum(CS%var_ptr1d(m)%p) + call MOM_read_data(unit_path(n), varname, CS%var_ptr1d(m)%p, timelevel=1) + if (is_there_a_checksum) checksum_data = chksum(CS%var_ptr1d(m)%p) elseif (associated(CS%var_ptr0d(m)%p)) then ! Read a scalar... - call read_data(unit_path(n), varname, CS%var_ptr0d(m)%p, & - G%Domain%mpp_domain, timelevel=1) - if (is_there_a_checksum) checksum_data = mpp_chksum(CS%var_ptr0d(m)%p,pelist=(/mpp_pe()/)) + call MOM_read_data(unit_path(n), varname, CS%var_ptr0d(m)%p, timelevel=1) + if (is_there_a_checksum) checksum_data = chksum(CS%var_ptr0d(m)%p, pelist=(/PE_here()/)) elseif (associated(CS%var_ptr2d(m)%p)) then ! Read a 2d array. if (pos /= 0) then call MOM_read_data(unit_path(n), varname, CS%var_ptr2d(m)%p, & @@ -1229,7 +1220,7 @@ subroutine restore_state(filename, directory, day, G, CS) call read_data(unit_path(n), varname, CS%var_ptr2d(m)%p, & no_domain=.true., timelevel=1) endif - if (is_there_a_checksum) checksum_data = mpp_chksum(CS%var_ptr2d(m)%p(isL:ieL,jsL:jeL)) + if (is_there_a_checksum) checksum_data = chksum(CS%var_ptr2d(m)%p(isL:ieL,jsL:jeL)) elseif (associated(CS%var_ptr3d(m)%p)) then ! Read a 3d array. if (pos /= 0) then call MOM_read_data(unit_path(n), varname, CS%var_ptr3d(m)%p, & @@ -1238,7 +1229,7 @@ subroutine restore_state(filename, directory, day, G, CS) call read_data(unit_path(n), varname, CS%var_ptr3d(m)%p, & no_domain=.true., timelevel=1) endif - if (is_there_a_checksum) checksum_data = mpp_chksum(CS%var_ptr3d(m)%p(isL:ieL,jsL:jeL,:)) + if (is_there_a_checksum) checksum_data = chksum(CS%var_ptr3d(m)%p(isL:ieL,jsL:jeL,:)) elseif (associated(CS%var_ptr4d(m)%p)) then ! Read a 4d array. if (pos /= 0) then call MOM_read_data(unit_path(n), varname, CS%var_ptr4d(m)%p, & @@ -1247,14 +1238,14 @@ subroutine restore_state(filename, directory, day, G, CS) call read_data(unit_path(n), varname, CS%var_ptr4d(m)%p, & no_domain=.true., timelevel=1) endif - if (is_there_a_checksum) checksum_data = mpp_chksum(CS%var_ptr4d(m)%p(isL:ieL,jsL:jeL,:,:)) + if (is_there_a_checksum) checksum_data = chksum(CS%var_ptr4d(m)%p(isL:ieL,jsL:jeL,:,:)) else call MOM_error(FATAL, "MOM_restart restore_state: No pointers set for "//trim(varname)) endif - if (is_root_pe() .and. is_there_a_checksum .and. (checksum_file(1) /= checksum_data)) then + if (is_root_pe() .and. is_there_a_checksum .and. (checksum_file /= checksum_data)) then write (mesg,'(a,Z16,a,Z16,a)') "Checksum of input field "// trim(varname)//" ",checksum_data,& - " does not match value ", checksum_file(1), & + " does not match value ", checksum_file, & " stored in "//trim(unit_path(n)//"." ) call MOM_error(FATAL, "MOM_restart(restore_state): "//trim(mesg) ) endif @@ -1455,7 +1446,7 @@ function open_restart_units(filename, directory, G, CS, units, file_paths, & if (fexists) then if (present(units)) & call open_file(units(n), trim(filepath), READONLY_FILE, NETCDF_FILE, & - threading = MULTIPLE, fileset = SINGLE_FILE) + threading=MULTIPLE, fileset=SINGLE_FILE) if (present(global_files)) global_files(n) = .true. elseif (CS%parallel_restartfiles) then ! Look for decomposed files using the I/O Layout. @@ -1484,7 +1475,7 @@ function open_restart_units(filename, directory, G, CS, units, file_paths, & if (fexists) then if (present(units)) & call open_file(units(n), trim(filepath), READONLY_FILE, NETCDF_FILE, & - threading = MULTIPLE, fileset = SINGLE_FILE) + threading=MULTIPLE, fileset=SINGLE_FILE) if (present(global_files)) global_files(n) = .true. if (present(file_paths)) file_paths(n) = filepath n = n + 1