From 4960fff16d1190350bbebc3e19bf38135bca1db6 Mon Sep 17 00:00:00 2001 From: Andrew Shao Date: Wed, 6 Jul 2022 18:57:26 -0500 Subject: [PATCH] Fix problems detected by CI Should fix the following tests: - Failure to compile NUOPC cap. Suggested change requires consultation with NCAR to understand how to inherit a common object from a module - Style violations: Ensures that all undocumented procedures and excess line lengths in client.F90 are resolved - Accidental change of timestep interval when call step_forward_MEKE --- .../nuopc_cap/mom_ocean_model_nuopc.F90 | 7 +- .../smartredis/MOM_MEKE_smartredis.F90 | 7 +- config_src/external/smartredis/client.F90 | 82 ++++++++++------- src/core/MOM.F90 | 16 ++-- src/parameterizations/lateral/MOM_MEKE.F90 | 91 +++++++++---------- 5 files changed, 110 insertions(+), 93 deletions(-) diff --git a/config_src/drivers/nuopc_cap/mom_ocean_model_nuopc.F90 b/config_src/drivers/nuopc_cap/mom_ocean_model_nuopc.F90 index 36b7488fd9..cac9da9c2b 100644 --- a/config_src/drivers/nuopc_cap/mom_ocean_model_nuopc.F90 +++ b/config_src/drivers/nuopc_cap/mom_ocean_model_nuopc.F90 @@ -62,7 +62,8 @@ module MOM_ocean_model_nuopc use MOM_surface_forcing_nuopc, only : convert_IOB_to_forces, ice_ocn_bnd_type_chksum use MOM_surface_forcing_nuopc, only : ice_ocean_boundary_type, surface_forcing_CS use MOM_surface_forcing_nuopc, only : forcing_save_restart -use nuopc_shr_methods, only : sr_client +! AES: Following line is commented out for now until after discussion with NCAR +! use nuopc_shr_methods, only : sr_client use get_stochy_pattern_mod, only : write_stoch_restart_ocn use iso_fortran_env, only : int64 @@ -285,7 +286,9 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, i call initialize_MOM(OS%Time, Time_init, param_file, OS%dirs, OS%MOM_CSp, & OS%restart_CSp, Time_in, offline_tracer_mode=OS%offline_tracer_mode, & input_restart_file=input_restart_file, & - diag_ptr=OS%diag, count_calls=.true., client_in=sr_client, waves_CSp=OS%Waves) + diag_ptr=OS%diag, count_calls=.true., waves_CSp=OS%Waves) + ! AES Following line commented out pending discussions with NCAR + ! diag_ptr=OS%diag, count_calls=.true., client_in=sr_client, waves_CSp=OS%Waves) call get_MOM_state_elements(OS%MOM_CSp, G=OS%grid, GV=OS%GV, US=OS%US, C_p=OS%C_p, & C_p_scaled=OS%fluxes%C_p, use_temp=use_temperature) diff --git a/config_src/external/smartredis/MOM_MEKE_smartredis.F90 b/config_src/external/smartredis/MOM_MEKE_smartredis.F90 index 61c92b5663..bc1b6a7886 100644 --- a/config_src/external/smartredis/MOM_MEKE_smartredis.F90 +++ b/config_src/external/smartredis/MOM_MEKE_smartredis.F90 @@ -40,12 +40,13 @@ subroutine infer_meke(G, GV, MEKE, u, v, tv, h, dt, CS) type(ocean_grid_type), intent(inout) :: G !< Ocean grid type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G)), intent( out) :: MEKE !< Vertically averaged eddy kinetic energy [L2 T-2 ~> m2 s-2] - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< Zonal velocity [L T-1 ~> m s-1] - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< Meridional velocity [L T-1 ~> m s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity [L T-1 ~> m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity [L T-1 ~> m s-1] type(thermo_var_ptrs), intent(in) :: tv !< Type containing thermodynamic variables real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. real, intent(in) :: dt !< Model(baroclinic) time-step [T ~> s]. - type(meke_smartredis_CS_type), intent(in) :: CS !< Control structure for inferring MEKE using SmartRedis + type(meke_smartredis_CS_type), intent(in) :: CS !< Control structure for inferring MEKE + !! using SmartRedis call MOM_error(FATAL,"infer_meke was compiled using the dummy module. Recompile"//& "with source code from https://github.com/CrayLabs/MOM6-smartredis") diff --git a/config_src/external/smartredis/client.F90 b/config_src/external/smartredis/client.F90 index 1d0beb1ff4..30bb991b00 100644 --- a/config_src/external/smartredis/client.F90 +++ b/config_src/external/smartredis/client.F90 @@ -138,18 +138,18 @@ module smartredis_client procedure :: get_datasets_from_list ! Private procedures - procedure, private :: put_tensor_i8 - procedure, private :: put_tensor_i16 - procedure, private :: put_tensor_i32 - procedure, private :: put_tensor_i64 - procedure, private :: put_tensor_float - procedure, private :: put_tensor_double - procedure, private :: unpack_tensor_i8 - procedure, private :: unpack_tensor_i16 - procedure, private :: unpack_tensor_i32 - procedure, private :: unpack_tensor_i64 - procedure, private :: unpack_tensor_float - procedure, private :: unpack_tensor_double + procedure, private :: put_tensor_i8 !< Put 8-bit integer tensor into database + procedure, private :: put_tensor_i16 !< Put 16-bit integer tensor into database + procedure, private :: put_tensor_i32 !< Put 32-bit integer tensor into database + procedure, private :: put_tensor_i64 !< Put 64-bit tensor into database + procedure, private :: put_tensor_float !< Put 32-bit real tensor into database + procedure, private :: put_tensor_double !< Put 64-bit real tensor into database + procedure, private :: unpack_tensor_i8 !< Unpack a 8-bit integer tensor into memory + procedure, private :: unpack_tensor_i16 !< Unpack a 16-bit integer tensor into memory + procedure, private :: unpack_tensor_i32 !< Unpack a 32-bit integer tensor into memory + procedure, private :: unpack_tensor_i64 !< Unpack a 64-bit integer tensor into memory + procedure, private :: unpack_tensor_float !< Unpack a 32-bit real tensor into memory + procedure, private :: unpack_tensor_double !< Unpack a 64-bit real tensor into memory end type client_type @@ -454,36 +454,42 @@ function set_model_from_file(self, name, model_file, backend, device, batch_size class(client_type), intent(in) :: self !< An initialized SmartRedis client character(len=*), intent(in) :: name !< The name to use to place the model character(len=*), intent(in) :: model_file !< The file storing the model - character(len=*), intent(in) :: backend !< The name of the backend (TF, TFLITE, TORCH, ONNX) - character(len=*), intent(in) :: device !< The name of the device (CPU, GPU, GPU:0, GPU:1...) + character(len=*), intent(in) :: backend !< The name of the backend + !! (TF, TFLITE, TORCH, ONNX) + character(len=*), intent(in) :: device !< The name of the device + !! (CPU, GPU, GPU:0, GPU:1...) integer, optional, intent(in) :: batch_size !< The batch size for model execution integer, optional, intent(in) :: min_batch_size !< The minimum batch size for model execution character(len=*), optional, intent(in) :: tag !< A tag to attach to the model for !! information purposes - character(len=*), dimension(:), optional, intent(in) :: inputs !< One or more names of model input nodes (TF - !! models) - character(len=*), dimension(:), optional, intent(in) :: outputs !< One or more names of model output nodes (TF models) + character(len=*), dimension(:), optional, intent(in) :: inputs !< One or more names of model + !! input nodes (TF models) + character(len=*), dimension(:), optional, intent(in) :: outputs !< One or more names of model + !! output nodes (TF models) integer(kind=enum_kind) :: code code = -1 end function set_model_from_file !> Load the machine learning model from a file and set the configuration for use in multi-GPU systems - function set_model_from_file_multigpu(self, name, model_file, backend, first_gpu, num_gpus, batch_size, min_batch_size, & - tag, inputs, outputs) result(code) + function set_model_from_file_multigpu(self, name, model_file, backend, first_gpu, num_gpus, batch_size, & + min_batch_size, tag, inputs, outputs) result(code) class(client_type), intent(in) :: self !< An initialized SmartRedis client character(len=*), intent(in) :: name !< The name to use to place the model character(len=*), intent(in) :: model_file !< The file storing the model - character(len=*), intent(in) :: backend !< The name of the backend (TF, TFLITE, TORCH, ONNX) - integer, intent(in) :: first_gpu !< The first GPU (zero-based) to use with the model + character(len=*), intent(in) :: backend !< The name of the backend + !! (TF, TFLITE, TORCH, ONNX) + integer, intent(in) :: first_gpu !< The first GPU (zero-based) + !! to use with the model integer, intent(in) :: num_gpus !< The number of GPUs to use with the model integer, optional, intent(in) :: batch_size !< The batch size for model execution integer, optional, intent(in) :: min_batch_size !< The minimum batch size for model execution character(len=*), optional, intent(in) :: tag !< A tag to attach to the model for !! information purposes - character(len=*), dimension(:), optional, intent(in) :: inputs !< One or more names of model input nodes (TF - !! models) - character(len=*), dimension(:), optional, intent(in) :: outputs !< One or more names of model output nodes (TF models) + character(len=*), dimension(:), optional, intent(in) :: inputs !< One or more names of model + !! input nodes (TF models) + character(len=*), dimension(:), optional, intent(in) :: outputs !< One or more names of model + !! output nodes (TF models) integer(kind=enum_kind) :: code code = -1 @@ -499,7 +505,8 @@ function set_model(self, name, model, backend, device, batch_size, min_batch_siz character(len=*), intent(in) :: device !< The name of the device (CPU, GPU, GPU:0, GPU:1...) integer, intent(in) :: batch_size !< The batch size for model execution integer, intent(in) :: min_batch_size !< The minimum batch size for model execution - character(len=*), intent(in) :: tag !< A tag to attach to the model for information purposes + character(len=*), intent(in) :: tag !< A tag to attach to the model for + !! information purposes character(len=*), dimension(:), intent(in) :: inputs !< One or more names of model input nodes (TF models) character(len=*), dimension(:), intent(in) :: outputs !< One or more names of model output nodes (TF models) integer(kind=enum_kind) :: code @@ -518,7 +525,8 @@ function set_model_multigpu(self, name, model, backend, first_gpu, num_gpus, bat integer, intent(in) :: num_gpus !< The number of GPUs to use with the model integer, intent(in) :: batch_size !< The batch size for model execution integer, intent(in) :: min_batch_size !< The minimum batch size for model execution - character(len=*), intent(in) :: tag !< A tag to attach to the model for information purposes + character(len=*), intent(in) :: tag !< A tag to attach to the model for + !! information purposes character(len=*), dimension(:), intent(in) :: inputs !< One or more names of model input nodes (TF models) character(len=*), dimension(:), intent(in) :: outputs !< One or more names of model output nodes (TF models) integer(kind=enum_kind) :: code @@ -632,8 +640,10 @@ function run_script(self, name, func, inputs, outputs) result(code) class(client_type), intent(in) :: self !< An initialized SmartRedis client character(len=*), intent(in) :: name !< The name to use to place the script character(len=*), intent(in) :: func !< The name of the function in the script to call - character(len=*), dimension(:), intent(in) :: inputs !< One or more names of script input nodes (TF scripts) - character(len=*), dimension(:), intent(in) :: outputs !< One or more names of script output nodes (TF scripts) + character(len=*), dimension(:), intent(in) :: inputs !< One or more names of script + !! input nodes (TF scripts) + character(len=*), dimension(:), intent(in) :: outputs !< One or more names of script + !! output nodes (TF scripts) integer(kind=enum_kind) :: code code = -1 @@ -643,8 +653,10 @@ function run_script_multigpu(self, name, func, inputs, outputs, offset, first_gp class(client_type), intent(in) :: self !< An initialized SmartRedis client character(len=*), intent(in) :: name !< The name to use to place the script character(len=*), intent(in) :: func !< The name of the function in the script to call - character(len=*), dimension(:), intent(in) :: inputs !< One or more names of script input nodes (TF scripts) - character(len=*), dimension(:), intent(in) :: outputs !< One or more names of script output nodes (TF scripts) + character(len=*), dimension(:), intent(in) :: inputs !< One or more names of script + !! input nodes (TF scripts) + character(len=*), dimension(:), intent(in) :: outputs !< One or more names of script + !! output nodes (TF scripts) integer, intent(in) :: offset !< Index of the current image, such as a processor ID !! or MPI rank integer, intent(in) :: first_gpu !< The first GPU (zero-based) to use with the model @@ -836,7 +848,8 @@ function poll_list_length(self, list_name, list_length, poll_frequency_ms, num_t integer, intent(in ) :: list_length !< The desired length of the list integer, intent(in ) :: poll_frequency_ms !< Frequency at which to poll the database (ms) integer, intent(in ) :: num_tries !< Number of times to poll the database before failing - logical(kind=c_bool), intent( out) :: poll_result !< True if the list is the requested length, False if not after num_tries. + logical(kind=c_bool), intent( out) :: poll_result !< True if the list is the requested length, + !! False if not after num_tries. integer(kind=enum_kind) :: code code = -1 @@ -849,7 +862,8 @@ function poll_list_length_gte(self, list_name, list_length, poll_frequency_ms, n integer, intent(in ) :: list_length !< The desired length of the list integer, intent(in ) :: poll_frequency_ms !< Frequency at which to poll the database (ms) integer, intent(in ) :: num_tries !< Number of times to poll the database before failing - logical(kind=c_bool), intent( out) :: poll_result !< True if the list is the requested length, False if not after num_tries. + logical(kind=c_bool), intent( out) :: poll_result !< True if the list is the requested length, + !! False if not after num_tries. integer(kind=enum_kind) :: code code = -1 @@ -862,7 +876,9 @@ function poll_list_length_lte(self, list_name, list_length, poll_frequency_ms, n integer, intent(in) :: list_length !< The desired length of the list integer, intent(in) :: poll_frequency_ms !< Frequency at which to poll the database (ms) integer, intent(in) :: num_tries !< Number of times to poll the database before failing - logical(kind=c_bool), intent(out) :: poll_result !< True if the list is the requested length, False if not after num_tries. + logical(kind=c_bool), intent( out) :: poll_result !< True if the list is the requested length, + !! False if not after num_tries. + integer(kind=enum_kind) :: code code = -1 diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 21eb42b212..7148d5122a 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -410,14 +410,12 @@ module MOM !! increments and priors type(smartredis_CS_type) :: smartredis_CS !< SmartRedis control structure for online ML/AI type(porous_barrier_ptrs) :: pbv !< porous barrier fractional cell metrics - real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) & - :: por_face_areaU !< fractional open area of U-faces [nondim] - real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) & - :: por_face_areaV !< fractional open area of V-faces [nondim] - real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NK_INTERFACE_) & - :: por_layer_widthU !< fractional open width of U-faces [nondim] - real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NK_INTERFACE_) & - :: por_layer_widthV !< fractional open width of V-faces [nondim] + real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: por_face_areaU !< fractional open area of U-faces [nondim] + real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: por_face_areaV !< fractional open area of V-faces [nondim] + real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NK_INTERFACE_) :: por_layer_widthU !< fractional open width + !! of U-faces [nondim] + real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NK_INTERFACE_) :: por_layer_widthV !< fractional open width + !! of V-faces [nondim] type(particles), pointer :: particles => NULL() ! NULL() !< a pointer to the stochastics control structure end type MOM_control_struct @@ -1221,7 +1219,7 @@ subroutine step_MOM_dynamics(forces, p_surf_begin, p_surf_end, dt, dt_thermo, & if (CS%useMEKE .and. CS%MEKE_in_dynamics) then call step_forward_MEKE(CS%MEKE, h, CS%VarMix%SN_u, CS%VarMix%SN_v, & - CS%visc, CS%t_dyn_rel_adv, G, GV, US, CS%MEKE_CSp, CS%uhtr, CS%vhtr, & + CS%visc, dt, G, GV, US, CS%MEKE_CSp, CS%uhtr, CS%vhtr, & CS%u, CS%v, CS%tv, Time_local) endif call disable_averaging(CS%diag) diff --git a/src/parameterizations/lateral/MOM_MEKE.F90 b/src/parameterizations/lateral/MOM_MEKE.F90 index e454e2aef5..31e7a2256e 100644 --- a/src/parameterizations/lateral/MOM_MEKE.F90 +++ b/src/parameterizations/lateral/MOM_MEKE.F90 @@ -35,11 +35,9 @@ module MOM_MEKE !> Private enum to define the source of the EKE used in MEKE enum, bind(c) - - enumerator :: EKE_PROG - enumerator :: EKE_FILE - enumerator :: EKE_SMARTREDIS - + enumerator :: EKE_PROG !< Use prognostic equation to calcualte EKE + enumerator :: EKE_FILE !< Read in EKE from a file + enumerator :: EKE_SMARTREDIS !< Infer EKE using a neural network end enum !> Control structure that contains MEKE parameters and diagnostics handles @@ -59,7 +57,6 @@ module MOM_MEKE logical :: visc_drag !< If true use the vertvisc_type to calculate bottom drag. logical :: MEKE_GEOMETRIC !< If true, uses the GM coefficient formulation from the GEOMETRIC !! framework (Marshall et al., 2012) - logical :: MEKE_from_file !< If true, reads EKE from a netCDF file real :: MEKE_GEOMETRIC_alpha !< The nondimensional coefficient governing the efficiency of the !! GEOMETRIC thickness diffusion. logical :: MEKE_equilibrium_alt !< If true, use an alternative calculation for the @@ -119,7 +116,7 @@ module MOM_MEKE integer :: id_Lrhines = -1, id_Leady = -1 integer :: id_MEKE_equilibrium = -1 !>@} - integer :: id_eke = -1 + integer :: id_eke = -1 !< Handle for reading in EKE from a file ! Infrastructure integer :: id_clock_pass !< Clock for group pass calls type(group_pass_type) :: pass_MEKE !< Group halo pass handle for MEKE%MEKE and maybe MEKE%Kh_diff @@ -144,10 +141,10 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h type(vertvisc_type), intent(in) :: visc !< The vertical viscosity type. real, intent(in) :: dt !< Model(baroclinic) time-step [T ~> s]. type(MEKE_CS), intent(inout) :: CS !< MEKE control structure. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: hu !< Accumlated zonal mass flux [H L2 ~> m3 or kg]. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: hv !< Accumlated meridional mass flux [H L2 ~> m3 or kg] - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< Zonal velocity - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< Meridional velocity + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: hu !< Accumlated zonal mass flux [H L2 ~> m3 or kg]. + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: hv !< Accumlated meridional mass flux [H L2 ~> m3 or kg] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: u !< Zonal velocity + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: v !< Meridional velocity type(thermo_var_ptrs), intent(in) :: tv !< Type containing thermodynamic variables type(time_type), intent(in) :: Time !< The time used for interpolating EKE @@ -217,37 +214,6 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h return endif - ! Calculations common to all methods - sdt = dt*CS%MEKE_dtScale ! Scaled dt to use for time-stepping - Rho0 = GV%Rho0 - I_Rho0 = 1.0 / GV%Rho0 - mass_neglect = GV%H_to_RZ * GV%H_subroundoff - cdrag2 = CS%cdrag**2 - - !$OMP parallel do default(shared) - do j=js-1,je+1 - do i=is-1,ie+1 ; mass(i,j) = 0.0 ; enddo - do k=1,nz ; do i=is-1,ie+1 - mass(i,j) = mass(i,j) + G%mask2dT(i,j) * (GV%H_to_RZ * h(i,j,k)) ! [R Z ~> kg m-2] - enddo ; enddo - do i=is-1,ie+1 - I_mass(i,j) = 0.0 - if (mass(i,j) > 0.0) I_mass(i,j) = 1.0 / mass(i,j) ! [R-1 Z-1 ~> m2 kg-1] - enddo - enddo - - if (CS%fixed_total_depth) then - !$OMP parallel do default(shared) - do j=js-1,je+1 ; do i=is-1,ie+1 - depth_tot(i,j) = G%bathyT(i,j) + G%Z_ref - enddo ; enddo - else - !$OMP parallel do default(shared) - do j=js-1,je+1 ; do i=is-1,ie+1 - depth_tot(i,j) = mass(i,j) * I_Rho0 - enddo ; enddo - endif - select case(CS%eke_src) case(EKE_PROG) if (CS%debug) then @@ -265,6 +231,12 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h scale=GV%H_to_m*(US%L_to_m**2)) endif + sdt = dt*CS%MEKE_dtScale ! Scaled dt to use for time-stepping + Rho0 = GV%Rho0 + I_Rho0 = 1.0 / GV%Rho0 + mass_neglect = GV%H_to_RZ * GV%H_subroundoff + cdrag2 = CS%cdrag**2 + ! With a depth-dependent (and possibly strong) damping, it seems ! advisable to use Strang splitting between the damping and diffusion. sdt_damp = sdt ; if (CS%MEKE_KH >= 0.0 .or. CS%MEKE_K4 >= 0.) sdt_damp = 0.5*sdt @@ -299,7 +271,6 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h endif endif - ! Calculate drag_rate_visc(i,j) which accounts for the model bottom mean flow if (CS%visc_drag) then !$OMP parallel do default(shared) @@ -330,6 +301,30 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h enddo ; enddo endif + !$OMP parallel do default(shared) + do j=js-1,je+1 + do i=is-1,ie+1 ; mass(i,j) = 0.0 ; enddo + do k=1,nz ; do i=is-1,ie+1 + mass(i,j) = mass(i,j) + G%mask2dT(i,j) * (GV%H_to_RZ * h(i,j,k)) ! [R Z ~> kg m-2] + enddo ; enddo + do i=is-1,ie+1 + I_mass(i,j) = 0.0 + if (mass(i,j) > 0.0) I_mass(i,j) = 1.0 / mass(i,j) ! [R-1 Z-1 ~> m2 kg-1] + enddo + enddo + + if (CS%fixed_total_depth) then + !$OMP parallel do default(shared) + do j=js-1,je+1 ; do i=is-1,ie+1 + depth_tot(i,j) = G%bathyT(i,j) + G%Z_ref + enddo ; enddo + else + !$OMP parallel do default(shared) + do j=js-1,je+1 ; do i=is-1,ie+1 + depth_tot(i,j) = mass(i,j) * I_Rho0 + enddo ; enddo + endif + if (CS%initialize) then call MEKE_equilibrium(CS, MEKE, G, GV, US, SN_u, SN_v, drag_rate_visc, I_mass, depth_tot) CS%initialize = .false. @@ -607,6 +602,8 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h case(EKE_SMARTREDIS) call MEKE_lengthScales(CS, MEKE, G, GV, US, SN_u, SN_v, MEKE%MEKE, depth_tot, bottomFac2, barotrFac2, LmixScale) call infer_meke(G, GV, MEKE%MEKE, u, v, tv, h, dt, CS%meke_smartredis_CS) + case default + call MOM_error(FATAL,"Invalid method specified for calculating EKE") end select call cpu_clock_begin(CS%id_clock_pass) @@ -1097,8 +1094,8 @@ logical function MEKE_init(Time, G, US, param_file, diag, smartredis_CS, CS, MEK if (.not. MEKE_init) return CS%initialized = .true. call get_param(param_file, mdl, "MEKE_IN_DYNAMICS", meke_in_dynamics, & - "If true, turns on the MEKE scheme which calculates "// & - "a sub-grid mesoscale eddy kinetic energy budget.", & + "If true, step MEKE forward with the dynamics"// & + "otherwise with the tracer timestep.", & default=.true.) call get_param(param_file, mdl, "EKE_SOURCE", eke_source_str, & @@ -1169,7 +1166,7 @@ logical function MEKE_init(Time, G, US, param_file, diag, smartredis_CS, CS, MEK if (CS%MEKE_equilibrium_restoring) then call get_param(param_file, mdl, "MEKE_RESTORING_TIMESCALE", MEKE_restoring_timescale, & "The timescale used to nudge MEKE toward its equilibrium value.", units="s", & - default=1e6, scale=US%T_to_s) + default=1e6, scale=US%s_to_T) CS%MEKE_restoring_rate = 1.0 / MEKE_restoring_timescale endif @@ -1198,6 +1195,8 @@ logical function MEKE_init(Time, G, US, param_file, diag, smartredis_CS, CS, MEK case("smartredis") CS%eke_src = EKE_SMARTREDIS call meke_smartredis_init(diag, G, US, param_file, smartredis_CS, CS%meke_smartredis_CS) + case default + call MOM_error(FATAL, "Invalid method selected for calculating EKE") end select ! GMM, make sure all params used to calculated MEKE are within the above if