MOM6
MOM_dynamics_legacy_split.F90
Go to the documentation of this file.
2 
3 !***********************************************************************
4 !* GNU General Public License *
5 !* This file is a part of MOM. *
6 !* *
7 !* MOM is free software; you can redistribute it and/or modify it and *
8 !* are expected to follow the terms of the GNU General Public License *
9 !* as published by the Free Software Foundation; either version 2 of *
10 !* the License, or (at your option) any later version. *
11 !* *
12 !* MOM is distributed in the hope that it will be useful, but WITHOUT *
13 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
14 !* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
15 !* License for more details. *
16 !* *
17 !* For the full text of the GNU General Public License, *
18 !* write to: Free Software Foundation, Inc., *
19 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
20 !* or see: http://www.gnu.org/licenses/gpl.html *
21 !***********************************************************************
22 
23 !********+*********+*********+*********+*********+*********+*********+**
24 !* *
25 !* By Robert Hallberg and Alistair Adcroft, 1996-2012 *
26 !* *
27 !* This file contains code that does the time-stepping of the *
28 !* adiabatic dynamic core, in this case with mode-splitting between *
29 !* the baroclinic and barotropic modes and a pseudo-second order *
30 !* Runge-Kutta time stepping scheme for the baroclinic momentum *
31 !* equation and a forward-backward coupling between the baroclinic *
32 !* momentum and continuity equations. This split time-stepping *
33 !* scheme is described in detail in Hallberg (JCP, 1997), with the *
34 !* primary issues related to exact tracer conservation and how to *
35 !* ensure consistency between the barotropic and layered estimates *
36 !* of the free surface height described carefully in Hallberg and *
37 !* Adcroft (Ocean Modelling, 2009). This was the time stepping code *
38 !* that is used for most GOLD applications, including GFDL's ESM2G *
39 !* Earth system model, and all of the examples provided with the *
40 !* MOM code (although several of these solutions are routinely *
41 !* verified by comparison with the slower unsplit schemes). *
42 !* *
43 !* The subroutine step_MOM_dyn_legacy_split actually does the time *
44 !* stepping, while register_restarts_dyn_legacy_split sets the fields *
45 !* that are found in a full restart file with this scheme, and *
46 !* initialize_dyn_legacy_split initializes the cpu clocks that are * *
47 !* used in this module. For largely historical reasons, this module *
48 !* does not have its own control structure, but shares the same *
49 !* control structure with MOM.F90 and the other MOM_dynamics_... *
50 !* modules. *
51 !* *
52 !* Macros written all in capital letters are defined in MOM_memory.h. *
53 !* *
54 !* A small fragment of the grid is shown below: *
55 !* *
56 !* j+1 x ^ x ^ x At x: q, CoriolisBu *
57 !* j+1 > o > o > At ^: v, PFv, CAv, vh, diffv, tauy, vbt, vhtr *
58 !* j x ^ x ^ x At >: u, PFu, CAu, uh, diffu, taux, ubt, uhtr *
59 !* j > o > o > At o: h, bathyT, eta, T, S, tr *
60 !* j-1 x ^ x ^ x *
61 !* i-1 i i+1 *
62 !* i i+1 *
63 !* *
64 !* The boundaries always run through q grid points (x). *
65 !* *
66 !********+*********+*********+*********+*********+*********+*********+**
67 
68 
72 use mom_forcing_type, only : forcing
73 
75 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
76 use mom_cpu_clock, only : clock_component, clock_subcomponent
77 use mom_cpu_clock, only : clock_module_driver, clock_module, clock_routine
79 use mom_diag_mediator, only : disable_averaging, post_data, safe_alloc_ptr
85 use mom_domains, only : to_south, to_west, to_all, cgrid_ne, scalar_pair
86 use mom_debugging, only : hchksum, uvchksum
87 use mom_error_handler, only : mom_error, mom_mesg, fatal, warning, is_root_pe
90 use mom_get_input, only : directories
91 use mom_io, only : mom_io_init, vardesc, var_desc
94 use mom_time_manager, only : time_type, set_time, time_type_to_real, operator(+)
95 use mom_time_manager, only : operator(-), operator(>), operator(*), operator(/)
96 
97 use mom_ale, only : ale_cs
105 use mom_debugging, only : check_redundant
106 use mom_grid, only : ocean_grid_type
107 use mom_hor_index, only : hor_index_type
111 use mom_meke_types, only : meke_type
123 
124 implicit none ; private
125 
126 #include <MOM_memory.h>
127 
128 type, public :: mom_dyn_legacy_split_cs ; private
129  real allocable_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: &
130  cau, & ! CAu = f*v - u.grad(u) in m s-2.
131  pfu, & ! PFu = -dM/dx, in m s-2.
132  diffu, & ! Zonal acceleration due to convergence of the along-isopycnal
133  ! stress tensor, in m s-2.
134  visc_rem_u, & ! Both the fraction of the zonal momentum originally in a
135  ! layer that remains after a time-step of viscosity, and the
136  ! fraction of a time-step's worth of a barotropic acceleration
137  ! that a layer experiences after viscosity is applied.
138  ! Nondimensional between 0 (at the bottom) and 1 (far above).
139  u_accel_bt ! The layers' zonal accelerations due to the difference between
140  ! the barotropic accelerations and the baroclinic accelerations
141  ! that were fed into the barotopic calculation, in m s-2.
142  real allocable_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: &
143  cav, & ! CAv = -f*u - u.grad(v) in m s-2.
144  pfv, & ! PFv = -dM/dy, in m s-2.
145  diffv, & ! Meridional acceleration due to convergence of the
146  ! along-isopycnal stress tensor, in m s-2.
147  visc_rem_v, & ! Both the fraction of the meridional momentum originally in
148  ! a layer that remains after a time-step of viscosity, and the
149  ! fraction of a time-step's worth of a barotropic acceleration
150  ! that a layer experiences after viscosity is applied.
151  ! Nondimensional between 0 (at the bottom) and 1 (far above).
152  v_accel_bt ! The layers' meridional accelerations due to the difference between
153  ! the barotropic accelerations and the baroclinic accelerations
154  ! that were fed into the barotopic calculation, in m s-2.
155 
156 ! The following variables are only used with the split time stepping scheme.
157  real allocable_, dimension(NIMEM_,NJMEM_) :: &
158  eta ! Instantaneous free surface height, in m.
159  real allocable_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: u_av
160  real allocable_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: v_av
161  ! u_av and v_av are the layer velocities with the vertical mean replaced by
162  ! the time-mean barotropic velocity over a baroclinic timestep, in m s-1.
163  real allocable_, dimension(NIMEM_,NJMEM_,NKMEM_) :: h_av
164  ! The arithmetic mean of two successive layer thicknesses, in m or kg m-2.
165  real allocable_, dimension(NIMEM_,NJMEM_) :: &
166  eta_pf ! The instantaneous SSH used in calculating PFu and PFv, in m.
167  real allocable_, dimension(NIMEMB_PTR_,NJMEM_) :: uhbt
168  real allocable_, dimension(NIMEM_,NJMEMB_PTR_) :: vhbt
169  ! uhbt and vhbt are the average volume or mass fluxes determined by the
170  ! barotropic solver in m3 s-1 or kg s-1. uhbt and vhbt should (roughly?)
171  ! equal the verticals sum of uh and vh, respectively.
172  real allocable_, dimension(NIMEMB_PTR_,NJMEM_) :: uhbt_in
173  real allocable_, dimension(NIMEM_,NJMEMB_PTR_) :: vhbt_in
174  ! uhbt_in and vhbt_in are the vertically summed transports from based on
175  ! the final thicknessses and velocities from the previous dynamics time
176  ! step, both in units of m3 s-1 or kg s-1.
177  real allocable_, dimension(NIMEM_,NJMEM_,NKMEM_) :: pbce
178  ! pbce times eta gives the baroclinic pressure anomaly in each layer due
179  ! to free surface height anomalies. pbce has units of m2 H-1 s-2.
180 
181  real, pointer, dimension(:,:) :: taux_bot => null(), tauy_bot => null()
182  ! The frictional bottom stresses from the ocean to the seafloor, in Pa.
183  type(bt_cont_type), pointer :: bt_cont => null()
184  ! A structure with elements that describe the
185  ! effective summed open face areas as a function
186  ! of barotropic flow.
187 
188  ! This is to allow the previous, velocity-based coupling with between the
189  ! baroclinic and barotropic modes.
190  logical :: flux_bt_coupling ! If true, use volume fluxes, not velocities,
191  ! to couple the baroclinic and barotropic modes.
192  logical :: bt_use_layer_fluxes ! If true, use the summed layered fluxes plus
193  ! an adjustment due to a changed barotropic
194  ! velocity in the barotropic continuity equation.
195  logical :: split_bottom_stress ! If true, provide the bottom stress
196  ! calculated by the vertical viscosity to the
197  ! barotropic solver.
198  logical :: readjust_bt_trans ! If true, readjust the barotropic transport of
199  ! the input velocities to agree with CS%uhbt_in
200  ! and CS%vhbt_in after the diabatic step.
201  logical :: readjust_velocity ! A flag that varies with time that determines
202  ! whether the velocities currently need to be
203  ! readjusted to agree with CS%uhbt_in and
204  ! CS%vhbt_in. This is only used if
205  ! CS%readjust_BT_trans is true.
206  logical :: calc_dtbt ! If true, calculate the barotropic time-step
207  ! dynamically.
208 
209  real :: be ! A nondimensional number from 0.5 to 1 that controls
210  ! the backward weighting of the time stepping scheme.
211  real :: begw ! A nondimensional number from 0 to 1 that controls
212  ! the extent to which the treatment of gravity waves
213  ! is forward-backward (0) or simulated backward
214  ! Euler (1). 0 is almost always used.
215  logical :: debug ! If true, write verbose checksums for debugging purposes.
216 
217  logical :: module_is_initialized = .false.
218 
219  integer :: id_uh = -1, id_vh = -1
220  integer :: id_pfu = -1, id_pfv = -1, id_cau = -1, id_cav = -1
221 
222 ! Split scheme only.
223  integer :: id_uav = -1, id_vav = -1
224  integer :: id_du_adj = -1, id_dv_adj = -1, id_du_adj2 = -1, id_dv_adj2 = -1
225  integer :: id_u_bt_accel = -1, id_v_bt_accel = -1
226 
227  type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the
228  ! timing of diagnostic output.
229  type(accel_diag_ptrs), pointer :: adp ! A structure pointing to the various
230  ! accelerations in the momentum equations,
231  ! which can later be used to calculate
232  ! derived diagnostics like energy budgets.
233  type(cont_diag_ptrs), pointer :: cdp ! A structure with pointers to various
234  ! terms in the continuity equations,
235  ! which can later be used to calculate
236  ! derived diagnostics like energy budgets.
237 ! The remainder of the structure is pointers to child subroutines' control strings.
238  type(hor_visc_cs), pointer :: hor_visc_csp => null()
239  type(continuity_cs), pointer :: continuity_csp => null()
240  type(coriolisadv_cs), pointer :: coriolisadv_csp => null()
241  type(pressureforce_cs), pointer :: pressureforce_csp => null()
242  type(legacy_barotropic_cs), pointer :: barotropic_csp => null()
243  type(vertvisc_cs), pointer :: vertvisc_csp => null()
244  type(set_visc_cs), pointer :: set_visc_csp => null()
245  type(ocean_obc_type), pointer :: obc => null() ! A pointer to an open boundary
246  ! condition type that specifies whether, where, and what open boundary
247  ! conditions are used. If no open BCs are used, this pointer stays
248  ! nullified. Flather OBCs use open boundary_CS as well.
249  type(update_obc_cs), pointer :: update_obc_csp => null()
250  type(tidal_forcing_cs), pointer :: tides_csp => null()
251 
252 ! This is a copy of the pointer in the top-level control structure.
253  type(ale_cs), pointer :: ale_csp => null()
254 
256 
260 
266 
267 contains
268 
269 ! =============================================================================
270 
271 subroutine step_mom_dyn_legacy_split(u, v, h, tv, visc, &
272  Time_local, dt, fluxes, p_surf_begin, p_surf_end, &
273  dt_since_flux, dt_therm, uh, vh, uhtr, vhtr, eta_av, &
274  G, GV, CS, calc_dtbt, VarMix, MEKE)
275  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
276  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
277  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
278  target, intent(inout) :: u !< The zonal velocity, in m s-1.
279  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
280  target, intent(inout) :: v !< The meridional velocity, in m s-1.
281  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
282  intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2).
283  type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various.
284  !! thermodynamic variables.
285  type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical viscosities,
286  !! bottom drag viscosities, and related fields.
287  type(time_type), intent(in) :: Time_local !< The model time at the end
288  !! of the time step.
289  real, intent(in) :: dt !< The baroclinic dynamics time step, in s
290  type(forcing), intent(in) :: fluxes !< A structure containing pointers to any
291  !! possible forcing fields. Unused fields
292  !! have NULL ptrs.
293  real, dimension(:,:), pointer :: p_surf_begin !< A pointer (perhaps NULL) to the
294  !! surface pressure at the beginning
295  !! of this dynamic step, in Pa.
296  real, dimension(:,:), pointer :: p_surf_end !< A pointer (perhaps NULL) to the
297  !! surface pressure at the end of
298  !! this dynamic step, in Pa.
299  real, intent(in) :: dt_since_flux !< The elapsed time since fluxes
300  !! were applied, in s.
301  real, intent(in) :: dt_therm !< The thermodynamic time step, in s.
302  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
303  target, intent(inout) :: uh !< The zonal volume or mass transport,
304  !! in m3 s-1 or kg s-1.
305  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
306  target, intent(inout) :: vh !< The meridional volume or mass transport,
307  !! in m3 s-1 or kg s-1.
308  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
309  intent(inout) :: uhtr !< The accumulated zonal volume or mass
310  !! transport since the last tracer advection,
311  !! in m3 or kg.
312  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
313  intent(inout) :: vhtr !< The accumulated meridional volume or mass
314  !! transport since the last tracer advection,
315  !! in m3 or kg.
316  real, dimension(SZI_(G),SZJ_(G)), &
317  intent(out) :: eta_av !< The free surface height or column mass
318  !! time-averaged over a time step,
319  !! in m or kg m-2.
320  type(mom_dyn_legacy_split_cs), &
321  pointer :: CS !< The control structure set up by
322  !! initialize_dyn_legacy_split.
323  logical, intent(in) :: calc_dtbt !< If true, recalculate the
324  !! barotropic time step.
325  type(varmix_cs), pointer :: VarMix !<A pointer to a structure with fields that
326  !! specify the spatially variable viscosities.
327  type(meke_type), pointer :: MEKE !< A pointer to a structure containing fields
328  !! related to the Mesoscale Eddy Kinetic Energy.
329 ! Arguments: u - The zonal velocity, in m s-1.
330 ! (inout) v - The meridional velocity, in m s-1.
331 ! (inout) h - The layer thicknesses, in m or kg m-2, depending on
332 ! whether the Boussinesq approximation is made.
333 ! (in) tv - a structure pointing to various thermodynamic variables.
334 ! (inout) visc - A structure containing vertical viscosities, bottom drag
335 ! viscosities, and related fields.
336 ! (in) Time_local - The model time at the end of the time step.
337 ! (in) dt - The time step in s.
338 ! (in) fluxes - A structure containing pointers to any possible
339 ! forcing fields. Unused fields have NULL ptrs.
340 ! (in) p_surf_begin - A pointer (perhaps NULL) to the surface pressure
341 ! at the beginning of this dynamic step, in Pa.
342 ! (in) p_surf_end - A pointer (perhaps NULL) to the surface pressure
343 ! at the end of this dynamic step, in Pa.
344 ! (in) dt_since_flux - The elapsed time since fluxes were applied, in s.
345 ! (in) dt_therm - The thermodynamic time step, in s.
346 ! (inout) uh - The zonal volume or mass transport, in m3 s-1 or kg s-1.
347 ! (inout) vh - The meridional volume or mass transport, in m3 s-1 or kg s-1.
348 ! (inout) uhtr - The accumulated zonal volume or mass transport since the last
349 ! tracer advection, in m3 or kg.
350 ! (inout) vhtr - The accumulated meridional volume or mass transport since the last
351 ! tracer advection, in m3 or kg.
352 ! (out) eta_av - The free surface height or column mass time-averaged
353 ! over a time step, in m or kg m-2.
354 ! (in) G - The ocean's grid structure.
355 ! (in) GV - The ocean's vertical grid structure.
356 ! (in) CS - The control structure set up by initialize_dyn_legacy_split.
357 ! (in) calc_dtbt - If true, recalculate the barotropic time step.
358 ! (in) VarMix - A pointer to a structure with fields that specify the
359 ! spatially variable viscosities.
360 ! (inout) MEKE - A pointer to a structure containing fields related to
361 ! the Mesoscale Eddy Kinetic Energy.
362 
363  real :: dt_pred ! The time step for the predictor part of the baroclinic
364  ! time stepping.
365 
366  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: &
367  up ! Predicted zonal velocitiy in m s-1.
368  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: &
369  vp ! Predicted meridional velocitiy in m s-1.
370  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
371  hp ! Predicted thickness in m or kg m-2 (H).
372 
373  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_bc_accel
374  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_bc_accel
375  ! u_bc_accel and v_bc_accel are the summed baroclinic accelerations of each
376  ! layer calculated by the non-barotropic part of the model, both in m s-2.
377  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target :: uh_in
378  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target :: vh_in
379  ! uh_in and vh_in are the zonal or meridional mass transports that would be
380  ! obtained using the initial velocities, both in m3 s-1 or kg s-1.
381  real, dimension(SZIB_(G),SZJ_(G)) :: uhbt_out
382  real, dimension(SZI_(G),SZJB_(G)) :: vhbt_out
383  ! uhbt_out and vhbt_out are the vertically summed transports from the
384  ! barotropic solver based on its final velocities, both in m3 s-1 or kg s-1.
385  real, dimension(SZI_(G),SZJ_(G)) :: eta_pred
386  ! eta_pred is the predictor value of the free surface height or column mass,
387  ! in m or kg m-2.
388  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target :: u_adj
389  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target :: v_adj
390  ! u_adj and v_adj are the zonal or meridional velocities after u and v
391  ! have been barotropically adjusted so the resulting transports match
392  ! uhbt_out and vhbt_out, both in m s-1.
393  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_tmp
394  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_tmp
395  ! u_tmp and v_tmp are temporary velocities used in diagnostic calculations.
396 
397  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_old_rad_OBC
398  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_old_rad_OBC
399  ! u_old_rad_OBC and v_old_rad_OBC are the starting velocities, which are
400  ! saved for use in the Flather open boundary condition code, both in m s-1.
401 
402  real :: Pa_to_eta ! A factor that converts pressures to the units of eta.
403  real, pointer, dimension(:,:) :: &
404  p_surf => null(), eta_pf_start => null(), &
405  taux_bot => null(), tauy_bot => null(), &
406  uhbt_in, vhbt_in, eta
407  real, pointer, dimension(:,:,:) :: &
408  uh_ptr => null(), u_ptr => null(), vh_ptr => null(), v_ptr => null(), &
409  u_init => null(), v_init => null(), & ! Pointers to u and v or u_adj and v_adj.
410  u_av, & ! The zonal velocity time-averaged over a time step, in m s-1.
411  v_av, & ! The meridional velocity time-averaged over a time step, in m s-1.
412  h_av ! The layer thickness time-averaged over a time step, in m or
413  ! kg m-2.
414  real :: Idt
415  logical :: dyn_p_surf
416  logical :: BT_cont_BT_thick ! If true, use the BT_cont_type to estimate the
417  ! relative weightings of the layers in calculating
418  ! the barotropic accelerations.
419  integer :: pid_bbl_h, pid_eta_PF, pid_eta, pid_visc
420  integer :: pid_h, pid_u, pid_u_av, pid_uh, pid_uhbt_in
421  integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
422  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
423  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
424  u_av => cs%u_av ; v_av => cs%v_av ; h_av => cs%h_av
425  eta => cs%eta ; uhbt_in => cs%uhbt_in ; vhbt_in => cs%vhbt_in
426  idt = 1.0 / dt
427 
428  up(:,:,:) = 0.0 ; vp(:,:,:) = 0.0 ; hp(:,:,:) = h(:,:,:)
429 
430  if (cs%debug) then
431  call mom_state_chksum("Start predictor ", u, v, h, uh, vh, g, gv)
432  call check_redundant("Start predictor u ", u, v, g)
433  call check_redundant("Start predictor uh ", uh, vh, g)
434  endif
435 
436  dyn_p_surf = associated(p_surf_begin) .and. associated(p_surf_end)
437  if (dyn_p_surf) then
438  p_surf => p_surf_end
439  call safe_alloc_ptr(eta_pf_start,g%isd,g%ied,g%jsd,g%jed)
440  eta_pf_start(:,:) = 0.0
441  else
442  p_surf => fluxes%p_surf
443  endif
444 
445  if (associated(cs%OBC)) then
446  do k=1,nz ; do j=js,je ; do i=is-2,ie+1
447  u_old_rad_obc(i,j,k) = u(i,j,k)
448  enddo ; enddo ; enddo
449  do k=1,nz ; do j=js-2,je+1 ; do i=is,ie
450  v_old_rad_obc(i,j,k) = v(i,j,k)
451  enddo ; enddo ; enddo
452  endif
453 
454  if (ASSOCIATED(cs%ADp%du_other)) cs%ADp%du_other(:,:,:) = 0.0
455  if (ASSOCIATED(cs%ADp%dv_other)) cs%ADp%dv_other(:,:,:) = 0.0
456 
457  bt_cont_bt_thick = .false.
458  if (associated(cs%BT_cont)) bt_cont_bt_thick = &
459  (associated(cs%BT_cont%h_u) .and. associated(cs%BT_cont%h_v))
460 
461  if (cs%split_bottom_stress) then
462  taux_bot => cs%taux_bot ; tauy_bot => cs%tauy_bot
463  endif
464 
465 ! PFu = d/dx M(h,T,S)
466 ! pbce = dM/deta
467  if (cs%begw == 0.0) call enable_averaging(dt, time_local, cs%diag)
468  call cpu_clock_begin(id_clock_pres)
469  call pressureforce(h, tv, cs%PFu, cs%PFv, g, gv, cs%PressureForce_CSp, &
470  cs%ALE_CSp, p_surf, cs%pbce, cs%eta_PF)
471  if (dyn_p_surf) then
472  if (gv%Boussinesq) then
473  pa_to_eta = 1.0 / (gv%Rho0*gv%g_Earth)
474  else
475  pa_to_eta = 1.0 / gv%H_to_Pa
476  endif
477  do j=jsq,jeq+1 ; do i=isq,ieq+1
478  eta_pf_start(i,j) = cs%eta_PF(i,j) - pa_to_eta * &
479  (p_surf_begin(i,j) - p_surf_end(i,j))
480  enddo ; enddo
481  endif
482  call cpu_clock_end(id_clock_pres)
483  call disable_averaging(cs%diag)
484 
485  if (g%nonblocking_updates) then
486  call cpu_clock_begin(id_clock_pass)
487  pid_eta_pf = pass_var_start(cs%eta_PF, g%Domain)
488  pid_eta = pass_var_start(eta, g%Domain)
489  if (cs%readjust_velocity) &
490  pid_uhbt_in = pass_vector_start(uhbt_in, vhbt_in, g%Domain)
491  call cpu_clock_end(id_clock_pass)
492  endif
493 
494  if (associated(cs%OBC)) then; if (cs%OBC%update_OBC) then
495  call update_obc_data(cs%OBC, g, gv, tv, h, cs%update_OBC_CSp, time_local)
496  endif; endif
497 
498 ! CAu = -(f+zeta_av)/h_av vh + d/dx KE_av
499  call cpu_clock_begin(id_clock_cor)
500  call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, g, gv, &
501  cs%CoriolisAdv_CSp)
502  call cpu_clock_end(id_clock_cor)
503 
504 ! u_bc_accel = CAu + PFu + diffu(u[n-1])
505  call cpu_clock_begin(id_clock_btforce)
506  do k=1,nz ; do j=js,je ; do i=isq,ieq
507  u_bc_accel(i,j,k) = (cs%Cau(i,j,k) + cs%PFu(i,j,k)) + cs%diffu(i,j,k)
508  enddo ; enddo ; enddo
509  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
510  v_bc_accel(i,j,k) = (cs%Cav(i,j,k) + cs%PFv(i,j,k)) + cs%diffv(i,j,k)
511  enddo ; enddo ; enddo
512  if (associated(cs%OBC)) then
513  call open_boundary_zero_normal_flow(cs%OBC, g, u_bc_accel, v_bc_accel)
514  endif
515  call cpu_clock_end(id_clock_btforce)
516 
517  if (cs%debug) then
518  call check_redundant("pre-btstep CS%Ca ", cs%Cau, cs%Cav, g)
519  call check_redundant("pre-btstep CS%PF ", cs%PFu, cs%PFv, g)
520  call check_redundant("pre-btstep CS%diff ", cs%diffu, cs%diffv, g)
521  call check_redundant("pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
522  endif
523 
524  if (g%nonblocking_updates) then
525  call cpu_clock_begin(id_clock_pass)
526  call pass_var_complete(pid_eta_pf, cs%eta_PF, g%Domain)
527  call pass_var_complete(pid_eta, eta, g%Domain)
528  if (cs%readjust_velocity) &
529  call pass_vector_complete(pid_uhbt_in, uhbt_in, vhbt_in, g%Domain)
530  call cpu_clock_end(id_clock_pass)
531  endif
532 
533  call cpu_clock_begin(id_clock_vertvisc)
534  do k=1,nz ; do j=js,je ; do i=isq,ieq
535  up(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt * u_bc_accel(i,j,k))
536  enddo ; enddo ; enddo
537  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
538  vp(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt * v_bc_accel(i,j,k))
539  enddo ; enddo ; enddo
540  call enable_averaging(dt, time_local, cs%diag)
541  call set_viscous_ml(u, v, h, tv, fluxes, visc, dt, g, gv, &
542  cs%set_visc_CSp)
543  call disable_averaging(cs%diag)
544 
545  call vertvisc_coef(up, vp, h, fluxes, visc, dt, g, gv, cs%vertvisc_CSp, cs%OBC)
546  call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, cs%vertvisc_CSp)
547  call cpu_clock_end(id_clock_vertvisc)
548 
549  call cpu_clock_begin(id_clock_pass)
550  if (g%nonblocking_updates) then
551  pid_visc = pass_vector_start(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
552  to_all+scalar_pair, cgrid_ne)
553  else
554  call pass_var(cs%eta_PF, g%Domain, complete=.false.)
555  call pass_var(eta, g%Domain)
556  if (cs%readjust_velocity) call pass_vector(uhbt_in, vhbt_in, g%Domain)
557  call pass_vector(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
558  to_all+scalar_pair, cgrid_ne)
559  endif
560  call cpu_clock_end(id_clock_pass)
561 
562  call cpu_clock_begin(id_clock_btcalc)
563  ! Calculate the relative layer weights for determining barotropic quantities.
564  if (.not.bt_cont_bt_thick) &
565  call legacy_btcalc(h, g, gv, cs%barotropic_CSp)
566  call legacy_bt_mass_source(h, eta, fluxes, .true., dt_therm, dt_since_flux, &
567  g, gv, cs%barotropic_CSp)
568  call cpu_clock_end(id_clock_btcalc)
569 
570  if (g%nonblocking_updates) then
571  call cpu_clock_begin(id_clock_pass)
572  call pass_vector_complete(pid_visc, cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
573  to_all+scalar_pair, cgrid_ne)
574  call cpu_clock_end(id_clock_pass)
575  endif
576 
577 ! u_accel_bt = layer accelerations due to barotropic solver
578  if (cs%flux_BT_coupling) then
579  call cpu_clock_begin(id_clock_continuity)
580  if (cs%readjust_velocity) then
581  ! Adjust the input velocites so that their transports match uhbt_out & vhbt_out.
582  call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, &
583  cs%continuity_CSp, uhbt_in, vhbt_in, cs%OBC, &
584  cs%visc_rem_u, cs%visc_rem_v, u_adj, v_adj, &
585  bt_cont=cs%BT_cont)
586  u_init => u_adj ; v_init => v_adj
587  if (ASSOCIATED(cs%ADp%du_other)) then ; do k=1,nz ; do j=js,je ; do i=isq,ieq
588  cs%ADp%du_other(i,j,k) = u_adj(i,j,k) - u(i,j,k)
589  enddo ; enddo ; enddo ; endif
590  if (ASSOCIATED(cs%ADp%dv_other)) then ; do k=1,nz ; do j=jsq,jeq ; do i=is,ie
591  cs%ADp%dv_other(i,j,k) = v_adj(i,j,k) - v(i,j,k)
592  enddo ; enddo ; enddo ; endif
593  cs%readjust_velocity = .false.
594  else
595  call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, &
596  cs%continuity_CSp, obc=cs%OBC, bt_cont=cs%BT_cont)
597 !### call continuity(u, v, h, hp, uh_in, vh_in, dt, G, GV, &
598 !### CS%continuity_CSp, OBC=CS%OBC, visc_rem_u=CS%visc_rem_u, &
599 !### visc_rem_v=CS%visc_rem_v, BT_cont=CS%BT_cont)
600  u_init => u ; v_init => v
601  endif
602  call cpu_clock_end(id_clock_continuity)
603 
604  if (bt_cont_bt_thick) then
605  call cpu_clock_begin(id_clock_pass)
606  call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
607  to_all+scalar_pair, cgrid_ne)
608  call cpu_clock_end(id_clock_pass)
609  call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
610  endif
611  call cpu_clock_begin(id_clock_btstep)
612  if (calc_dtbt) call legacy_set_dtbt(g, gv, cs%barotropic_CSp, eta, cs%pbce, cs%BT_cont)
613  call legacy_btstep(.true., uh_in, vh_in, eta, dt, u_bc_accel, v_bc_accel, &
614  fluxes, cs%pbce, cs%eta_PF, uh, vh, cs%u_accel_bt, &
615  cs%v_accel_bt, eta_pred, cs%uhbt, cs%vhbt, g, gv, &
616  cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, &
617  uhbt_out = uhbt_out, vhbt_out = vhbt_out, obc = cs%OBC, &
618  bt_cont = cs%BT_cont, eta_pf_start = eta_pf_start, &
619  taux_bot=taux_bot, tauy_bot=tauy_bot)
620  call cpu_clock_end(id_clock_btstep)
621  else
622 
623  if (associated(cs%BT_cont) .or. cs%BT_use_layer_fluxes) then
624  call cpu_clock_begin(id_clock_continuity)
625  call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, &
626  cs%continuity_CSp, obc=cs%OBC, &
627  visc_rem_u=cs%visc_rem_u, visc_rem_v=cs%visc_rem_v, &
628  bt_cont=cs%BT_cont)
629  call cpu_clock_end(id_clock_continuity)
630  if (bt_cont_bt_thick) then
631  call cpu_clock_begin(id_clock_pass)
632  call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
633  to_all+scalar_pair, cgrid_ne)
634  call cpu_clock_end(id_clock_pass)
635  call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
636  endif
637  endif
638 
639  if (cs%BT_use_layer_fluxes) then
640  uh_ptr => uh_in; vh_ptr => vh_in; u_ptr => u; v_ptr => v
641  endif
642 
643  u_init => u ; v_init => v
644  call cpu_clock_begin(id_clock_btstep)
645  if (calc_dtbt) call legacy_set_dtbt(g, gv, cs%barotropic_CSp, eta, cs%pbce)
646  call legacy_btstep(.false., u, v, eta, dt, u_bc_accel, v_bc_accel, &
647  fluxes, cs%pbce, cs%eta_PF, u_av, v_av, cs%u_accel_bt, &
648  cs%v_accel_bt, eta_pred, cs%uhbt, cs%vhbt, g, gv, cs%barotropic_CSp,&
649  cs%visc_rem_u, cs%visc_rem_v, obc=cs%OBC, &
650  bt_cont = cs%BT_cont, eta_pf_start=eta_pf_start, &
651  taux_bot=taux_bot, tauy_bot=tauy_bot, &
652  uh0=uh_ptr, vh0=vh_ptr, u_uh0=u_ptr, v_vh0=v_ptr)
653  call cpu_clock_end(id_clock_btstep)
654  endif
655 
656 ! up = u + dt_pred*( u_bc_accel + u_accel_bt )
657  dt_pred = dt * cs%be
658  call cpu_clock_begin(id_clock_mom_update)
659  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
660  vp(i,j,k) = g%mask2dCv(i,j) * (v_init(i,j,k) + dt_pred * &
661  (v_bc_accel(i,j,k) + cs%v_accel_bt(i,j,k)))
662  enddo ; enddo ; enddo
663 
664  do k=1,nz ; do j=js,je ; do i=isq,ieq
665  up(i,j,k) = g%mask2dCu(i,j) * (u_init(i,j,k) + dt_pred * &
666  (u_bc_accel(i,j,k) + cs%u_accel_bt(i,j,k)))
667  enddo ; enddo ; enddo
668  call cpu_clock_end(id_clock_mom_update)
669 
670  if (cs%debug) then
671  call uvchksum("Predictor 1 [uv]", up, vp, g%HI,haloshift=0)
672  call hchksum(h, "Predictor 1 h", g%HI, haloshift=1, scale=gv%H_to_m)
673  call uvchksum("Predictor 1 [uv]h", uh, vh, &
674  g%HI, haloshift=2, scale=gv%H_to_m)
675 ! call MOM_state_chksum("Predictor 1", up, vp, h, uh, vh, G, GV, haloshift=1)
676  call mom_accel_chksum("Predictor accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
677  cs%diffu, cs%diffv, g, gv, cs%pbce, cs%u_accel_bt, cs%v_accel_bt)
678  call mom_state_chksum("Predictor 1 init", u_init, v_init, h, uh, vh, g, gv, haloshift=2)
679  call check_redundant("Predictor 1 up", up, vp, g)
680  call check_redundant("Predictor 1 uh", uh, vh, g)
681  endif
682 
683 ! up <- up + dt_pred d/dz visc d/dz up
684 ! u_av <- u_av + dt_pred d/dz visc d/dz u_av
685  call cpu_clock_begin(id_clock_vertvisc)
686  call vertvisc_coef(up, vp, h, fluxes, visc, dt_pred, g, gv, cs%vertvisc_CSp, &
687  cs%OBC)
688  call vertvisc(up, vp, h, fluxes, visc, dt_pred, cs%OBC, cs%ADp, cs%CDp, g, &
689  gv, cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot)
690  if (g%nonblocking_updates) then
691  call cpu_clock_end(id_clock_vertvisc) ; call cpu_clock_begin(id_clock_pass)
692  pid_u = pass_vector_start(up, vp, g%Domain)
693  call cpu_clock_end(id_clock_pass) ; call cpu_clock_begin(id_clock_vertvisc)
694  endif
695  call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt_pred, g, gv, cs%vertvisc_CSp)
696  call cpu_clock_end(id_clock_vertvisc)
697 
698  call cpu_clock_begin(id_clock_pass)
699  call pass_vector(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
700  to_all+scalar_pair, cgrid_ne)
701  if (g%nonblocking_updates) then
702  call pass_vector_complete(pid_u, up, vp, g%Domain)
703  else
704  call pass_vector(up, vp, g%Domain)
705  endif
706  call cpu_clock_end(id_clock_pass)
707 
708 ! uh = u_av * h
709 ! hp = h + dt * div . uh
710  call cpu_clock_begin(id_clock_continuity)
711  call continuity(up, vp, h, hp, uh, vh, dt, g, gv, cs%continuity_CSp, &
712  cs%uhbt, cs%vhbt, cs%OBC, cs%visc_rem_u, &
713  cs%visc_rem_v, u_av, v_av, bt_cont=cs%BT_cont)
714  call cpu_clock_end(id_clock_continuity)
715 
716  call cpu_clock_begin(id_clock_pass)
717  call pass_var(hp, g%Domain)
718  if (g%nonblocking_updates) then
719  pid_u_av = pass_vector_start(u_av, v_av, g%Domain)
720  pid_uh = pass_vector_start(uh(:,:,:), vh(:,:,:), g%Domain)
721  else
722  call pass_vector(u_av, v_av, g%Domain, complete=.false.)
723  call pass_vector(uh(:,:,:), vh(:,:,:), g%Domain)
724  endif
725  call cpu_clock_end(id_clock_pass)
726 
727  if (associated(cs%OBC)) then
728  call radiation_open_bdry_conds(cs%OBC, u_av, u_old_rad_obc, v_av, v_old_rad_obc, g, dt)
729  endif
730 
731 ! h_av = (h + hp)/2
732  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
733  h_av(i,j,k) = 0.5*(h(i,j,k) + hp(i,j,k))
734  enddo ; enddo ; enddo
735 
736 ! The correction phase of the time step starts here.
737  call enable_averaging(dt, time_local, cs%diag)
738 
739 ! Calculate a revised estimate of the free-surface height correction to be
740 ! used in the next call to btstep. This call is at this point so that
741 ! hp can be changed if CS%begw /= 0.
742 ! eta_cor = ... (hidden inside CS%barotropic_CSp)
743  call cpu_clock_begin(id_clock_btcalc)
744  call legacy_bt_mass_source(hp, eta_pred, fluxes, .false., dt_therm, &
745  dt_since_flux+dt, g, gv, cs%barotropic_CSp)
746  call cpu_clock_end(id_clock_btcalc)
747 
748  if (cs%begw /= 0.0) then
749  ! hp <- (1-begw)*h_in + begw*hp
750  ! Back up hp to the value it would have had after a time-step of
751  ! begw*dt. hp is not used again until recalculated by continuity.
752  do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1
753  hp(i,j,k) = (1.0-cs%begw)*h(i,j,k) + cs%begw*hp(i,j,k)
754  enddo ; enddo ; enddo
755 
756 ! PFu = d/dx M(hp,T,S)
757 ! pbce = dM/deta
758  call cpu_clock_begin(id_clock_pres)
759  call pressureforce(hp, tv, cs%PFu, cs%PFv, g, gv, &
760  cs%PressureForce_CSp, cs%ALE_CSp, &
761  p_surf, cs%pbce, cs%eta_PF)
762  call cpu_clock_end(id_clock_pres)
763  call cpu_clock_begin(id_clock_pass)
764  call pass_var(cs%eta_PF, g%Domain)
765  call cpu_clock_end(id_clock_pass)
766  endif
767 
768  if (g%nonblocking_updates) then
769  call cpu_clock_begin(id_clock_pass)
770  call pass_vector_complete(pid_u_av, u_av, v_av, g%Domain)
771  call pass_vector_complete(pid_uh, uh(:,:,:), vh(:,:,:), g%Domain)
772  call cpu_clock_end(id_clock_pass)
773  endif
774 
775  if (associated(cs%OBC)) then; if (cs%OBC%update_OBC) then
776  call update_obc_data(cs%OBC, g, gv, tv, h, cs%update_OBC_CSp, time_local)
777  endif; endif
778 
779  if (bt_cont_bt_thick) then
780  call cpu_clock_begin(id_clock_pass)
781  call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
782  to_all+scalar_pair, cgrid_ne)
783  call cpu_clock_end(id_clock_pass)
784  call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
785  endif
786 
787  if (cs%debug) then
788  call mom_state_chksum("Predictor ", up, vp, hp, uh, vh, g, gv)
789  call uvchksum("Predictor avg [uv]", u_av, v_av, g%HI, haloshift=1)
790  call hchksum(h_av,"Predictor avg h",g%HI,haloshift=0, scale=gv%H_to_m)
791  ! call MOM_state_chksum("Predictor avg ", u_av, v_av, h_av,uh, vh, G, GV)
792  call check_redundant("Predictor up ", up, vp, g)
793  call check_redundant("Predictor uh ", uh, vh, g)
794  endif
795 
796 ! diffu = horizontal viscosity terms (u_av)
797  call cpu_clock_begin(id_clock_horvisc)
798  call horizontal_viscosity(u_av, v_av, h_av, cs%diffu, cs%diffv, &
799  meke, varmix, g, gv, cs%hor_visc_CSp, obc=cs%OBC)
800  call cpu_clock_end(id_clock_horvisc)
801 
802 ! CAu = -(f+zeta_av)/h_av vh + d/dx KE_av
803  call cpu_clock_begin(id_clock_cor)
804  call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, g, gv, &
805  cs%CoriolisAdv_CSp)
806  call cpu_clock_end(id_clock_cor)
807 
808 ! Calculate the momentum forcing terms for the barotropic equations.
809 
810 ! u_bc_accel = CAu + PFu + diffu(u[n-1])
811  call cpu_clock_begin(id_clock_btforce)
812  do k=1,nz ; do j=js,je ; do i=isq,ieq
813  u_bc_accel(i,j,k) = (cs%Cau(i,j,k) + cs%PFu(i,j,k)) + cs%diffu(i,j,k)
814  enddo ; enddo ; enddo
815  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
816  v_bc_accel(i,j,k) = (cs%Cav(i,j,k) + cs%PFv(i,j,k)) + cs%diffv(i,j,k)
817  enddo ; enddo ; enddo
818  if (associated(cs%OBC)) then
819  call open_boundary_zero_normal_flow(cs%OBC, g, u_bc_accel, v_bc_accel)
820  endif
821  call cpu_clock_end(id_clock_btforce)
822 
823  if (cs%debug) then
824  call check_redundant("corr pre-btstep CS%Ca ", cs%Cau, cs%Cav, g)
825  call check_redundant("corr pre-btstep CS%PF ", cs%PFu, cs%PFv, g)
826  call check_redundant("corr pre-btstep CS%diff ", cs%diffu, cs%diffv, g)
827  call check_redundant("corr pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
828  endif
829 
830 ! u_accel_bt = layer accelerations due to barotropic solver
831 ! pbce = dM/deta
832  call cpu_clock_begin(id_clock_btstep)
833  if (cs%flux_BT_coupling) then
834  call legacy_btstep(.true., uh_in, vh_in, eta, dt, u_bc_accel, v_bc_accel, &
835  fluxes, cs%pbce, cs%eta_PF, uh, vh, cs%u_accel_bt, &
836  cs%v_accel_bt, eta, cs%uhbt, cs%vhbt, g, gv, &
837  cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, etaav=eta_av, &
838  uhbt_out = uhbt_out, vhbt_out = vhbt_out, obc=cs%OBC, &
839  bt_cont = cs%BT_cont, eta_pf_start = eta_pf_start, &
840  taux_bot=taux_bot, tauy_bot=tauy_bot)
841  else
842  if (cs%BT_use_layer_fluxes) then
843  uh_ptr => uh ; vh_ptr => vh ; u_ptr => u_av ; v_ptr => v_av
844  endif
845 
846  call legacy_btstep(.false., u, v, eta, dt, u_bc_accel, v_bc_accel, &
847  fluxes, cs%pbce, cs%eta_PF, u_av, v_av, cs%u_accel_bt, &
848  cs%v_accel_bt, eta, cs%uhbt, cs%vhbt, g, gv, &
849  cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, &
850  etaav=eta_av, obc=cs%OBC, &
851  bt_cont = cs%BT_cont, eta_pf_start=eta_pf_start, &
852  taux_bot=taux_bot, tauy_bot=tauy_bot, &
853  uh0=uh_ptr, vh0=vh_ptr, u_uh0=u_ptr, v_vh0=v_ptr)
854  endif
855  call cpu_clock_end(id_clock_btstep)
856 
857  if (cs%debug) then
858  call check_redundant("u_accel_bt ", cs%u_accel_bt, cs%v_accel_bt, g)
859  endif
860 
861 ! u = u + dt*( u_bc_accel + u_accel_bt )
862  call cpu_clock_begin(id_clock_mom_update)
863  do k=1,nz ; do j=js,je ; do i=isq,ieq
864  u(i,j,k) = g%mask2dCu(i,j) * (u_init(i,j,k) + dt * &
865  (u_bc_accel(i,j,k) + cs%u_accel_bt(i,j,k)))
866  enddo ; enddo ; enddo
867 
868  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
869  v(i,j,k) = g%mask2dCv(i,j) * (v_init(i,j,k) + dt * &
870  (v_bc_accel(i,j,k) + cs%v_accel_bt(i,j,k)))
871  enddo ; enddo ; enddo
872  call cpu_clock_end(id_clock_mom_update)
873 
874  if (cs%debug) then
875  call uvchksum("Corrector 1 [uv]", u, v, g%HI, haloshift=0)
876  call hchksum(h,"Corrector 1 h",g%HI,haloshift=2, scale=gv%H_to_m)
877  call uvchksum("Corrector 1 [uv]h", &
878  uh, vh, g%HI, haloshift=2, scale=gv%H_to_m)
879  ! call MOM_state_chksum("Corrector 1", u, v, h, uh, vh, G, GV, haloshift=1)
880  call mom_accel_chksum("Corrector accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
881  cs%diffu, cs%diffv, g, gv, cs%pbce, cs%u_accel_bt, cs%v_accel_bt)
882  endif
883 
884 ! u <- u + dt d/dz visc d/dz u
885 ! u_av <- u_av + dt d/dz visc d/dz u_av
886  call cpu_clock_begin(id_clock_vertvisc)
887  call vertvisc_coef(u, v, h, fluxes, visc, dt, g, gv, cs%vertvisc_CSp, cs%OBC)
888  call vertvisc(u, v, h, fluxes, visc, dt, cs%OBC, cs%ADp, cs%CDp, g, gv, &
889  cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot)
890  if (g%nonblocking_updates) then
891  call cpu_clock_end(id_clock_vertvisc) ; call cpu_clock_begin(id_clock_pass)
892  pid_u = pass_vector_start(u, v, g%Domain)
893  call cpu_clock_end(id_clock_pass) ; call cpu_clock_begin(id_clock_vertvisc)
894  endif
895  call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, cs%vertvisc_CSp)
896  call cpu_clock_end(id_clock_vertvisc)
897 
898 ! Later, h_av = (h_in + h_out)/2, but for now use h_av to store h_in.
899  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
900  h_av(i,j,k) = h(i,j,k)
901  enddo ; enddo ; enddo
902 
903  call cpu_clock_begin(id_clock_pass)
904  call pass_vector(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
905  to_all+scalar_pair, cgrid_ne)
906  if (g%nonblocking_updates) then
907  call pass_vector_complete(pid_u, u, v, g%Domain)
908  else
909  call pass_vector(u, v, g%Domain)
910  endif
911  call cpu_clock_end(id_clock_pass)
912 
913 ! uh = u_av * h
914 ! h = h + dt * div . uh
915  if (cs%flux_BT_coupling) then
916  ! u_av and v_av adjusted so their mass transports match uhbt and vhbt.
917  ! Also, determine the values of u and v so that their transports
918  ! that agree with uhbt_out and vhbt_out.
919  if (ASSOCIATED(cs%ADp%du_other)) then ; do k=1,nz ; do j=js,je ; do i=isq,ieq
920  u_tmp(i,j,k) = u(i,j,k)
921  enddo ; enddo ; enddo ; endif
922  if (ASSOCIATED(cs%ADp%dv_other)) then ; do k=1,nz ; do j=jsq,jeq ; do i=is,ie
923  v_tmp(i,j,k) = v(i,j,k)
924  enddo ; enddo ; enddo ; endif
925  call cpu_clock_begin(id_clock_continuity)
926  call continuity(u, v, h, h, uh, vh, dt, g, gv, &
927  cs%continuity_CSp, cs%uhbt, cs%vhbt, cs%OBC, &
928  cs%visc_rem_u, cs%visc_rem_v, u_av, v_av, &
929  uhbt_out, vhbt_out, u, v)
930  call cpu_clock_end(id_clock_continuity)
931  ! Whenever thickness changes let the diag manager know, target grids
932  ! for vertical remapping may need to be regenerated.
933  call diag_update_remap_grids(cs%diag)
934  if (g%nonblocking_updates) then
935  call cpu_clock_begin(id_clock_pass)
936  pid_h = pass_var_start(h, g%Domain)
937  call cpu_clock_end(id_clock_pass)
938  endif
939  if (ASSOCIATED(cs%ADp%du_other)) then ; do k=1,nz ; do j=js,je ; do i=isq,ieq
940  cs%ADp%du_other(i,j,k) = cs%ADp%du_other(i,j,k) + (u(i,j,k) - u_tmp(i,j,k))
941  enddo ; enddo ; enddo ; endif
942  if (ASSOCIATED(cs%ADp%dv_other)) then ; do k=1,nz ; do j=jsq,jeq ; do i=is,ie
943  cs%ADp%dv_other(i,j,k) = cs%ADp%dv_other(i,j,k) + (v(i,j,k) - v_tmp(i,j,k))
944  enddo ; enddo ; enddo ; endif
945 
946  call cpu_clock_begin(id_clock_vertvisc)
947  call vertvisc_limit_vel(u, v, h_av, cs%ADp, cs%CDp, fluxes, visc, dt, g, gv, cs%vertvisc_CSp)
948  if (g%nonblocking_updates) then
949  call cpu_clock_end(id_clock_vertvisc) ; call cpu_clock_begin(id_clock_pass)
950  pid_u = pass_vector_start(u, v, g%Domain)
951  call cpu_clock_end(id_clock_pass) ; call cpu_clock_begin(id_clock_vertvisc)
952  endif
953  call vertvisc_limit_vel(u_av, v_av, h_av, cs%ADp, cs%CDp, fluxes, visc, dt, g, gv, cs%vertvisc_CSp)
954  call cpu_clock_end(id_clock_vertvisc)
955 
956  call cpu_clock_begin(id_clock_pass)
957  if (g%nonblocking_updates) then
958  call pass_var_complete(pid_h, h, g%Domain)
959  call pass_vector_complete(pid_u, u, v, g%Domain)
960  else
961  call pass_var(h, g%Domain)
962  call pass_vector(u, v, g%Domain, complete=.false.)
963  endif
964  call cpu_clock_end(id_clock_pass)
965  else
966  ! u_av and v_av adjusted so their mass transports match uhbt and vhbt.
967  call cpu_clock_begin(id_clock_continuity)
968  call continuity(u, v, h, h, uh, vh, dt, g, gv, &
969  cs%continuity_CSp, cs%uhbt, cs%vhbt, cs%OBC, &
970  cs%visc_rem_u, cs%visc_rem_v, u_av, v_av)
971  call cpu_clock_end(id_clock_continuity)
972  ! Whenever thickness changes let the diag manager know, target grids
973  ! for vertical remapping may need to be regenerated.
974  call diag_update_remap_grids(cs%diag)
975  call cpu_clock_begin(id_clock_pass)
976  call pass_var(h, g%Domain)
977  call cpu_clock_end(id_clock_pass)
978  endif
979 
980  call cpu_clock_begin(id_clock_pass)
981  if (g%nonblocking_updates) then
982  pid_uh = pass_vector_start(uh(:,:,:), vh(:,:,:), g%Domain)
983  pid_u_av = pass_vector_start(u_av, v_av, g%Domain)
984  else
985  call pass_vector(u_av, v_av, g%Domain, complete=.false.)
986  call pass_vector(uh(:,:,:), vh(:,:,:), g%Domain)
987  endif
988  call cpu_clock_end(id_clock_pass)
989 
990  if (associated(cs%OBC)) then
991  call radiation_open_bdry_conds(cs%OBC, u, u_old_rad_obc, v, v_old_rad_obc, g, dt)
992  endif
993 
994 ! h_av = (h_in + h_out)/2 . Going in to this line, h_av = h_in.
995  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
996  h_av(i,j,k) = 0.5*(h_av(i,j,k) + h(i,j,k))
997  enddo ; enddo ; enddo
998 
999  if (g%nonblocking_updates) then
1000  call cpu_clock_begin(id_clock_pass)
1001  call pass_vector_complete(pid_uh, uh(:,:,:), vh(:,:,:), g%Domain)
1002  call pass_vector_complete(pid_u_av, u_av, v_av, g%Domain)
1003  call cpu_clock_end(id_clock_pass)
1004  endif
1005 
1006  do k=1,nz ; do j=js-2,je+2 ; do i=isq-2,ieq+2
1007  uhtr(i,j,k) = uhtr(i,j,k) + uh(i,j,k)*dt
1008  enddo ; enddo ; enddo
1009  do k=1,nz ; do j=jsq-2,jeq+2 ; do i=is-2,ie+2
1010  vhtr(i,j,k) = vhtr(i,j,k) + vh(i,j,k)*dt
1011  enddo ; enddo ; enddo
1012 
1013 ! The time-averaged free surface height has already been set by the last
1014 ! call to btstep.
1015 
1016 ! Here various terms used in to update the momentum equations are
1017 ! offered for averaging.
1018  if (cs%id_PFu > 0) call post_data(cs%id_PFu, cs%PFu, cs%diag)
1019  if (cs%id_PFv > 0) call post_data(cs%id_PFv, cs%PFv, cs%diag)
1020  if (cs%id_CAu > 0) call post_data(cs%id_CAu, cs%CAu, cs%diag)
1021  if (cs%id_CAv > 0) call post_data(cs%id_CAv, cs%CAv, cs%diag)
1022 
1023 ! Here the thickness fluxes are offered for averaging.
1024  if (cs%id_uh > 0) call post_data(cs%id_uh, uh, cs%diag)
1025  if (cs%id_vh > 0) call post_data(cs%id_vh, vh, cs%diag)
1026  if (cs%id_uav > 0) call post_data(cs%id_uav, u_av, cs%diag)
1027  if (cs%id_vav > 0) call post_data(cs%id_vav, v_av, cs%diag)
1028  if (cs%id_u_BT_accel > 0) call post_data(cs%id_u_BT_accel, cs%u_accel_bt, cs%diag)
1029  if (cs%id_v_BT_accel > 0) call post_data(cs%id_v_BT_accel, cs%v_accel_bt, cs%diag)
1030  if (cs%id_du_adj > 0) call post_data(cs%id_du_adj, cs%ADp%du_other, cs%diag)
1031  if (cs%id_dv_adj > 0) call post_data(cs%id_dv_adj, cs%ADp%dv_other, cs%diag)
1032  if (cs%debug) then
1033  call mom_state_chksum("Corrector ", u, v, h, uh, vh, g, gv)
1034  call uvchksum("Corrector avg [uv]", u_av, v_av, g%HI, haloshift=1)
1035  call hchksum(h_av,"Corrector avg h",g%HI,haloshift=1, scale=gv%H_to_m)
1036  ! call MOM_state_chksum("Corrector avg ", u_av, v_av, h_av, uh, vh, G, GV)
1037  endif
1038 
1039 end subroutine step_mom_dyn_legacy_split
1040 
1041 ! =============================================================================
1042 
1043 subroutine adjustments_dyn_legacy_split(u, v, h, dt, G, GV, CS)
1044  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
1045  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
1046  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1047  intent(inout) :: u !< The zonal velocity, in m s-1.
1048  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1049  intent(inout) :: v !< The meridional velocity, in m s-1.
1050  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
1051  intent(inout) :: h !< Layer thicknesses, in H
1052  !! (usually m or kg m-2).
1053  real, intent(in) :: dt !< The baroclinic dynamics time step, in s.
1054  type(mom_dyn_legacy_split_cs), pointer :: CS !< The control structure set up by
1055  !! initialize_dyn_legacy_split.
1056 
1057 ! Arguments: u - The zonal velocity, in m s-1.
1058 ! (in) v - The meridional velocity, in m s-1.
1059 ! (in) h - The layer thicknesses, in m or kg m-2, depending on
1060 ! whether the Boussinesq approximation is made.
1061 ! (in) dt - The time step in s.
1062 ! (in) G - The ocean's grid structure.
1063 ! (in) GV - The ocean's vertical grid structure.
1064 ! (in) CS - The control structure set up by initialize_dyn_legacy_split.
1065 
1066  ! Temporary arrays to contain layer thickness fluxes in m3 s-1 or kg s-1.
1067  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: uh_temp
1068  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vh_temp
1069  ! A temporary array to contain layer projected thicknesses in m or kg m-2.
1070  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_temp
1071  integer :: i, j, k, is, ie, js, je, nz
1072  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1073 
1074  if (cs%readjust_BT_trans) then
1075  call cpu_clock_begin(id_clock_continuity)
1076  call continuity(u, v, h, h_temp, uh_temp, vh_temp, dt, g, gv, &
1077  cs%continuity_CSp, obc=cs%OBC)
1078  call cpu_clock_end(id_clock_continuity)
1079 !$OMP parallel default(none) shared(is,ie,js,je,nz,CS,uh_temp,vh_temp)
1080 !$OMP do
1081  do j=js,je
1082  do i=is-1,ie ; cs%uhbt_in(i,j) = uh_temp(i,j,1) ; enddo
1083  do k=2,nz ; do i=is-1,ie
1084  cs%uhbt_in(i,j) = cs%uhbt_in(i,j) + uh_temp(i,j,k)
1085  enddo ; enddo
1086  enddo
1087 !$OMP do
1088  do j=js-1,je
1089  do i=is,ie ; cs%vhbt_in(i,j) = vh_temp(i,j,1) ; enddo
1090  do k=2,nz ; do i=is,ie
1091  cs%vhbt_in(i,j) = cs%vhbt_in(i,j) + vh_temp(i,j,k)
1092  enddo ; enddo
1093  enddo
1094 !$OMP end parallel
1095  cs%readjust_velocity = .true.
1096  endif
1097 
1098 end subroutine adjustments_dyn_legacy_split
1099 
1100 ! =============================================================================
1101 
1102 subroutine register_restarts_dyn_legacy_split(HI, GV, param_file, CS, restart_CS, uh, vh)
1103  type(hor_index_type), intent(in) :: HI !< A horizontal index type structure.
1104  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
1105  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
1106  !! parameters.
1107  type(mom_dyn_legacy_split_cs), pointer :: CS !< The control structure set up by
1108  !! initialize_dyn_legacy_split.
1109  type(mom_restart_cs), pointer :: restart_CS !< A pointer to the restart
1110  !! control structure.
1111  real, dimension(SZIB_(HI),SZJ_(HI),SZK_(GV)), &
1112  target, intent(inout) :: uh !< The zonal volume or mass transport,
1113  !! in m3 s-1 or kg s-1.
1114  real, dimension(SZI_(HI),SZJB_(HI),SZK_(GV)), &
1115  target, intent(inout) :: vh !< The meridional volume or mass
1116  !! transport, in m3 s-1 or kg s-1.
1117 ! This subroutine sets up any auxiliary restart variables that are specific
1118 ! to the unsplit time stepping scheme. All variables registered here should
1119 ! have the ability to be recreated if they are not present in a restart file.
1120 
1121 ! Arguments: HI - A horizontal index type structure.
1122 ! (in) GV - The ocean's vertical grid structure.
1123 ! (in) param_file - A structure indicating the open file to parse for
1124 ! model parameter values.
1125 ! (inout) CS - The control structure set up by initialize_dyn_legacy_split.
1126 ! (in) restart_CS - A pointer to the restart control structure.
1127 ! (inout) uh - The zonal volume or mass transport, in m3 s-1 or kg s-1.
1128 ! (inout) vh - The meridional volume or mass transport, in m3 s-1 or kg s-1.
1129 
1130  type(vardesc) :: vd
1131  character(len=40) :: mdl = "MOM_dynamics_legacy_split" ! This module's name.
1132  character(len=48) :: thickness_units, flux_units
1133  logical :: adiabatic, flux_BT_coupling, readjust_BT_trans
1134  integer :: isd, ied, jsd, jed, nz, IsdB, IedB, JsdB, JedB
1135  isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
1136  isdb = hi%IsdB ; iedb = hi%IedB ; jsdb = hi%JsdB ; jedb = hi%JedB
1137 
1138 ! This is where a control structure that is specific to this module would be allocated.
1139  if (associated(cs)) then
1140  call mom_error(warning, "register_restarts_dyn_legacy_split called with an associated "// &
1141  "control structure.")
1142  return
1143  endif
1144  allocate(cs)
1145 
1146  call get_param(param_file, "MOM_legacy_split", "FLUX_BT_COUPLING", flux_bt_coupling, &
1147  default=.false., do_not_log=.true.)
1148  call get_param(param_file, "MOM_legacy_split", "READJUST_BT_TRANS", readjust_bt_trans, &
1149  default=.false., do_not_log=.true.)
1150  call get_param(param_file, "MOM_legacy_split", "ADIABATIC", adiabatic, &
1151  default=.false., do_not_log=.true.)
1152  if (.not.flux_bt_coupling .or. adiabatic) readjust_bt_trans = .false.
1153 
1154  alloc_(cs%diffu(isdb:iedb,jsd:jed,nz)) ; cs%diffu(:,:,:) = 0.0
1155  alloc_(cs%diffv(isd:ied,jsdb:jedb,nz)) ; cs%diffv(:,:,:) = 0.0
1156  alloc_(cs%CAu(isdb:iedb,jsd:jed,nz)) ; cs%CAu(:,:,:) = 0.0
1157  alloc_(cs%CAv(isd:ied,jsdb:jedb,nz)) ; cs%CAv(:,:,:) = 0.0
1158  alloc_(cs%PFu(isdb:iedb,jsd:jed,nz)) ; cs%PFu(:,:,:) = 0.0
1159  alloc_(cs%PFv(isd:ied,jsdb:jedb,nz)) ; cs%PFv(:,:,:) = 0.0
1160 
1161  alloc_(cs%eta(isd:ied,jsd:jed)) ; cs%eta(:,:) = 0.0
1162  alloc_(cs%u_av(isdb:iedb,jsd:jed,nz)) ; cs%u_av(:,:,:) = 0.0
1163  alloc_(cs%v_av(isd:ied,jsdb:jedb,nz)) ; cs%v_av(:,:,:) = 0.0
1164  alloc_(cs%h_av(isd:ied,jsd:jed,nz)) ; cs%h_av(:,:,:) = gv%Angstrom
1165  alloc_(cs%uhbt_in(isdb:iedb,jsd:jed)) ; cs%uhbt_in(:,:) = 0.0
1166  alloc_(cs%vhbt_in(isd:ied,jsdb:jedb)) ; cs%vhbt_in(:,:) = 0.0
1167 
1168  thickness_units = get_thickness_units(gv)
1169  flux_units = get_flux_units(gv)
1170 
1171  vd = var_desc("sfc",thickness_units,"Free surface Height",'h','1')
1172  call register_restart_field(cs%eta, vd, .false., restart_cs)
1173 
1174  vd = var_desc("u2","meter second-1","Auxiliary Zonal velocity",'u','L')
1175  call register_restart_field(cs%u_av, vd, .false., restart_cs)
1176 
1177  vd = var_desc("v2","meter second-1","Auxiliary Meridional velocity",'v','L')
1178  call register_restart_field(cs%v_av, vd, .false., restart_cs)
1179 
1180  vd = var_desc("h2",thickness_units,"Auxiliary Layer Thickness",'h','L')
1181  call register_restart_field(cs%h_av, vd, .false., restart_cs)
1182 
1183  vd = var_desc("uh",flux_units,"Zonal thickness flux",'u','L')
1184  call register_restart_field(uh, vd, .false., restart_cs)
1185 
1186  vd = var_desc("vh",flux_units,"Meridional thickness flux",'v','L')
1187  call register_restart_field(vh, vd, .false., restart_cs)
1188 
1189  vd = var_desc("diffu","meter second-2","Zonal horizontal viscous acceleration",'u','L')
1190  call register_restart_field(cs%diffu, vd, .false., restart_cs)
1191 
1192  vd = var_desc("diffv","meter second-2","Meridional horizontal viscous acceleration",'v','L')
1193  call register_restart_field(cs%diffv, vd, .false., restart_cs)
1194 
1195  call register_legacy_barotropic_restarts(hi, gv, param_file, &
1196  cs%barotropic_CSp, restart_cs)
1197 
1198  if (readjust_bt_trans) then
1199  vd = var_desc("uhbt_in",flux_units,"Final instantaneous barotropic zonal thickness flux",&
1200  'u','1')
1201  call register_restart_field(cs%uhbt_in, vd, .false., restart_cs)
1202 
1203  vd = var_desc("vhbt_in",flux_units,"Final instantaneous barotropic meridional thickness flux",&
1204  'v','1')
1205  call register_restart_field(cs%vhbt_in, vd, .false., restart_cs)
1206  endif
1207 
1209 
1210 subroutine initialize_dyn_legacy_split(u, v, h, uh, vh, eta, Time, G, GV, param_file, &
1211  diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, &
1212  VarMix, MEKE, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, &
1213  dirs, ntrunc)
1214  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
1215  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
1216  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1217  intent(inout) :: u !< The zonal velocity, in m s-1.
1218  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1219  intent(inout) :: v !< The meridional velocity, in m s-1.
1220  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , &
1221  intent(inout) :: h !< Layer thicknesses, in H
1222  !! (usually m or kg m-2).
1223  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1224  target, intent(inout) :: uh !< The zonal volume or mass transport,
1225  !! in m3 s-1 or kg s-1.
1226  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1227  target, intent(inout) :: vh !< The meridional volume or mass transport,
1228  !! in m3 s-1 or kg s-1.
1229  real, dimension(SZI_(G),SZJ_(G)), &
1230  intent(inout) :: eta !< The free surface height or column mass,
1231  !! in m or kg m-2.
1232  type(time_type), target, intent(in) :: Time !< The current model time.
1233  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
1234  !! parameters.
1235  type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to
1236  !! regulate diagnostic output.
1237  type(mom_dyn_legacy_split_cs), pointer :: CS !< The control structure set up by
1238  !! initialize_dyn_legacy_split.
1239  type(mom_restart_cs), pointer :: restart_CS !< A pointer to the restart control
1240  !! structure.
1241  real, intent(in) :: dt !< The baroclinic dynamics time step,
1242  !! in s.
1243  type(accel_diag_ptrs), target, intent(inout) :: Accel_diag !<A set of pointers to the various
1244  !! accelerations in the momentum equations, which can be
1245  !! used for later derived diagnostics, like energy budgets.
1246  type(cont_diag_ptrs), target, intent(inout) :: Cont_diag !< A structure with pointers to various
1247  !! terms in the continuity equations.
1248  type(ocean_internal_state), intent(inout) :: MIS !< The "MOM6 Internal State"
1249  !! structure, used to pass around pointers to
1250  !! various arrays for diagnostic purposes.
1251  type(varmix_cs), pointer :: VarMix !< A pointer to a structure with
1252  !! fields that specify the spatially variable viscosities.
1253  type(meke_type), pointer :: MEKE !< A pointer to a structure containing
1254  !! fields related to the Mesoscale Eddy Kinetic Energy.
1255  type(ocean_obc_type), pointer :: OBC !< If open boundary conditions are
1256  !! used, this points to the ocean_OBC_type
1257  !! that was set up in MOM_initialization.
1258  type(update_obc_cs), pointer :: update_OBC_CSp !< If open boundary condition
1259  !! updates are used, this points to
1260  !! the appropriate control structure.
1261  type(ale_cs), pointer :: ALE_CSp !< This points to the ALE control
1262  !! structure.
1263  type(set_visc_cs), pointer :: setVisc_CSp !< This points to the set_visc control
1264  !! structure.
1265  type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical
1266  !! viscosities, bottom drag viscosities, and related fields.
1267  type(directories), intent(in) :: dirs !< A structure containing several
1268  !! relevant directory paths.
1269  integer, target, intent(inout) :: ntrunc !< A target for the variable that
1270  !! records the number of times the velocity is truncated (this should be 0).
1271 
1272 ! Arguments: u - The zonal velocity, in m s-1.
1273 ! (inout) v - The meridional velocity, in m s-1.
1274 ! (inout) h - The layer thicknesses, in m or kg m-2, depending on whether
1275 ! the Boussinesq approximation is made.
1276 ! (inout) uh - The zonal volume or mass transport, in m3 s-1 or kg s-1.
1277 ! (inout) vh - The meridional volume or mass transport, in m3 s-1 or kg s-1.
1278 ! (out) eta - The free surface height or column mass, in m or kg m-2.
1279 ! (in) Time - The current model time.
1280 ! (in) G - The ocean's grid structure.
1281 ! (in) param_file - A structure indicating the open file to parse for
1282 ! model parameter values.
1283 ! (in) diag - A structure that is used to regulate diagnostic output.
1284 ! (inout) CS - The control structure set up by initialize_dyn_legacy_split.
1285 ! (in) restart_CS - A pointer to the restart control structure.
1286 ! (inout) Accel_diag - A set of pointers to the various accelerations in
1287 ! the momentum equations, which can be used for later derived
1288 ! diagnostics, like energy budgets.
1289 ! (inout) Cont_diag - A structure with pointers to various terms in the
1290 ! continuity equations.
1291 ! (inout) MIS - The "MOM6 Internal State" structure, used to pass around
1292 ! pointers to various arrays for diagnostic purposes.
1293 ! (in) VarMix - A pointer to a structure with fields that specify the
1294 ! spatially variable viscosities.
1295 ! (inout) MEKE - A pointer to a structure containing fields related to
1296 ! the Mesoscale Eddy Kinetic Energy.
1297 ! (in) OBC - If open boundary conditions are used, this points to the
1298 ! ocean_OBC_type that was set up in MOM_initialization.
1299 ! (in) update_OBC_CSp - If open boundary condition updates are used,
1300 ! this points to the appropriate control structure.
1301 ! (in) ALE_CS - This points to the ALE control structure.
1302 ! (in) setVisc_CSp - This points to the set_visc control structure.
1303 ! (inout) visc - A structure containing vertical viscosities, bottom drag
1304 ! viscosities, and related fields.
1305 ! (in) dirs - A structure containing several relevant directory paths.
1306 ! (in) ntrunc - A target for the variable that records the number of times
1307 ! the velocity is truncated (this should be 0).
1308 
1309  ! This subroutine initializes all of the variables that are used by this
1310  ! dynamic core, including diagnostics and the cpu clocks.
1311 
1312  ! This subroutine initializes any variables that are specific to this time
1313  ! stepping scheme, including the cpu clocks.
1314  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_tmp
1315  character(len=40) :: mdl = "MOM_dynamics_legacy_split" ! This module's name.
1316  character(len=48) :: thickness_units, flux_units
1317  logical :: adiabatic, use_tides, debug_truncations
1318  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
1319  integer :: IsdB, IedB, JsdB, JedB
1320  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1321  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1322  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
1323 
1324  if (.not.associated(cs)) call mom_error(fatal, &
1325  "initialize_dyn_legacy_split called with an unassociated control structure.")
1326  if (cs%module_is_initialized) then
1327  call mom_error(warning, "initialize_dyn_legacy_split called with a control "// &
1328  "structure that has already been initialized.")
1329  return
1330  endif
1331  cs%module_is_initialized = .true.
1332 
1333  cs%diag => diag
1334 
1335  call get_param(param_file, mdl, "TIDES", use_tides, &
1336  "If true, apply tidal momentum forcing.", default=.false.)
1337  call get_param(param_file, mdl, "BE", cs%be, &
1338  "If SPLIT is true, BE determines the relative weighting \n"//&
1339  "of a 2nd-order Runga-Kutta baroclinic time stepping \n"//&
1340  "scheme (0.5) and a backward Euler scheme (1) that is \n"//&
1341  "used for the Coriolis and inertial terms. BE may be \n"//&
1342  "from 0.5 to 1, but instability may occur near 0.5. \n"//&
1343  "BE is also applicable if SPLIT is false and USE_RK2 \n"//&
1344  "is true.", units="nondim", default=0.6)
1345  call get_param(param_file, mdl, "BEGW", cs%begw, &
1346  "If SPLIT is true, BEGW is a number from 0 to 1 that \n"//&
1347  "controls the extent to which the treatment of gravity \n"//&
1348  "waves is forward-backward (0) or simulated backward \n"//&
1349  "Euler (1). 0 is almost always used.\n"//&
1350  "If SPLIT is false and USE_RK2 is true, BEGW can be \n"//&
1351  "between 0 and 0.5 to damp gravity waves.", &
1352  units="nondim", default=0.0)
1353 
1354  call get_param(param_file, mdl, "FLUX_BT_COUPLING", cs%flux_BT_coupling, &
1355  "If true, use mass fluxes to ensure consistency between \n"//&
1356  "the baroclinic and barotropic modes. This is only used \n"//&
1357  "if SPLIT is true.", default=.false.)
1358  call get_param(param_file, mdl, "READJUST_BT_TRANS", cs%readjust_BT_trans, &
1359  "If true, make a barotropic adjustment to the layer \n"//&
1360  "velocities after the thermodynamic part of the step \n"//&
1361  "to ensure that the interaction between the thermodynamics \n"//&
1362  "and the continuity solver do not change the barotropic \n"//&
1363  "transport. This is only used if FLUX_BT_COUPLING and \n"//&
1364  "SPLIT are true.", default=.false.)
1365  call get_param(param_file, mdl, "SPLIT_BOTTOM_STRESS", cs%split_bottom_stress, &
1366  "If true, provide the bottom stress calculated by the \n"//&
1367  "vertical viscosity to the barotropic solver.", default=.false.)
1368  call get_param(param_file, mdl, "BT_USE_LAYER_FLUXES", cs%BT_use_layer_fluxes, &
1369  "If true, use the summed layered fluxes plus an \n"//&
1370  "adjustment due to the change in the barotropic velocity \n"//&
1371  "in the barotropic continuity equation.", default=.true.)
1372  call get_param(param_file, mdl, "DEBUG", cs%debug, &
1373  "If true, write out verbose debugging data.", default=.false.)
1374  call get_param(param_file, mdl, "ADIABATIC", adiabatic, default=.false., do_not_log=.true.)
1375  if (.not.cs%flux_BT_coupling .or. adiabatic) cs%readjust_BT_trans = .false.
1376  call get_param(param_file, mdl, "DEBUG_TRUNCATIONS", debug_truncations, &
1377  default=.false.)
1378 
1379  allocate(cs%taux_bot(isdb:iedb,jsd:jed)) ; cs%taux_bot(:,:) = 0.0
1380  allocate(cs%tauy_bot(isd:ied,jsdb:jedb)) ; cs%tauy_bot(:,:) = 0.0
1381 
1382  alloc_(cs%uhbt(isdb:iedb,jsd:jed)) ; cs%uhbt(:,:) = 0.0
1383  alloc_(cs%vhbt(isd:ied,jsdb:jedb)) ; cs%vhbt(:,:) = 0.0
1384  alloc_(cs%visc_rem_u(isdb:iedb,jsd:jed,nz)) ; cs%visc_rem_u(:,:,:) = 0.0
1385  alloc_(cs%visc_rem_v(isd:ied,jsdb:jedb,nz)) ; cs%visc_rem_v(:,:,:) = 0.0
1386  alloc_(cs%eta_PF(isd:ied,jsd:jed)) ; cs%eta_PF(:,:) = 0.0
1387  alloc_(cs%pbce(isd:ied,jsd:jed,nz)) ; cs%pbce(:,:,:) = 0.0
1388 
1389  alloc_(cs%u_accel_bt(isdb:iedb,jsd:jed,nz)) ; cs%u_accel_bt(:,:,:) = 0.0
1390  alloc_(cs%v_accel_bt(isd:ied,jsdb:jedb,nz)) ; cs%v_accel_bt(:,:,:) = 0.0
1391 
1392  mis%diffu => cs%diffu ; mis%diffv => cs%diffv
1393  mis%PFu => cs%PFu ; mis%PFv => cs%PFv
1394  mis%CAu => cs%CAu ; mis%CAv => cs%CAv
1395  mis%pbce => cs%pbce
1396  mis%u_accel_bt => cs%u_accel_bt ; mis%v_accel_bt => cs%v_accel_bt
1397  mis%u_av => cs%u_av ; mis%v_av => cs%v_av
1398 
1399  cs%ADp => accel_diag ; cs%CDp => cont_diag
1400  accel_diag%diffu => cs%diffu ; accel_diag%diffv => cs%diffv
1401  accel_diag%PFu => cs%PFu ; accel_diag%PFv => cs%PFv
1402  accel_diag%CAu => cs%CAu ; accel_diag%CAv => cs%CAv
1403 ! Accel_diag%pbce => CS%pbce
1404 ! Accel_diag%u_accel_bt => CS%u_accel_bt ; Accel_diag%v_accel_bt => CS%v_accel_bt
1405 ! Accel_diag%u_av => CS%u_av ; Accel_diag%v_av => CS%v_av
1406 
1407  call continuity_init(time, g, gv, param_file, diag, cs%continuity_CSp)
1408  call coriolisadv_init(time, g, param_file, diag, cs%ADp, cs%CoriolisAdv_CSp)
1409  if (use_tides) call tidal_forcing_init(time, g, param_file, cs%tides_CSp)
1410  call pressureforce_init(time, g, gv, param_file, diag, cs%PressureForce_CSp, &
1411  cs%tides_CSp)
1412  call hor_visc_init(time, g, param_file, diag, cs%hor_visc_CSp)
1413  call vertvisc_init(mis, time, g, gv, param_file, diag, cs%ADp, dirs, &
1414  ntrunc, cs%vertvisc_CSp)
1415  if (.not.associated(setvisc_csp)) call mom_error(fatal, &
1416  "initialize_dyn_legacy_split called with setVisc_CSp unassociated.")
1417  cs%set_visc_CSp => setvisc_csp
1418 
1419  if (associated(ale_csp)) cs%ALE_CSp => ale_csp
1420  if (associated(obc)) cs%OBC => obc
1421  if (associated(update_obc_csp)) cs%update_OBC_CSp => update_obc_csp
1422 
1423  if (.not. query_initialized(cs%eta,"sfc",restart_cs)) then
1424  ! Estimate eta based on the layer thicknesses - h. With the Boussinesq
1425  ! approximation, eta is the free surface height anomaly, while without it
1426  ! eta is the mass of ocean per unit area. eta always has the same
1427  ! dimensions as h, either m or kg m-3.
1428  ! CS%eta(:,:) = 0.0 already from initialization.
1429  if (gv%Boussinesq) then
1430  do j=js,je ; do i=is,ie ; cs%eta(i,j) = -g%bathyT(i,j) ; enddo ; enddo
1431  endif
1432  do k=1,nz ; do j=js,je ; do i=is,ie
1433  cs%eta(i,j) = cs%eta(i,j) + h(i,j,k)
1434  enddo ; enddo ; enddo
1435  endif
1436  ! Copy eta into an output array.
1437  do j=js,je ; do i=is,ie ; eta(i,j) = cs%eta(i,j) ; enddo ; enddo
1438 
1439  call legacy_barotropic_init(u, v, h, cs%eta, time, g, gv, param_file, diag, &
1440  cs%barotropic_CSp, restart_cs, cs%BT_cont, cs%tides_CSp)
1441 
1442  if (.not. query_initialized(cs%diffu,"diffu",restart_cs) .or. &
1443  .not. query_initialized(cs%diffv,"diffv",restart_cs)) &
1444  call horizontal_viscosity(u, v, h, cs%diffu, cs%diffv, meke, varmix, &
1445  g, gv, cs%hor_visc_CSp)
1446  if (.not. query_initialized(cs%u_av,"u2", restart_cs) .or. &
1447  .not. query_initialized(cs%u_av,"v2", restart_cs)) then
1448  cs%u_av(:,:,:) = u(:,:,:)
1449  cs%v_av(:,:,:) = v(:,:,:)
1450  endif
1451 ! This call is just here to initialize uh and vh.
1452  if (.not. query_initialized(uh,"uh",restart_cs) .or. &
1453  .not. query_initialized(vh,"vh",restart_cs)) then
1454  h_tmp(:,:,:) = h(:,:,:)
1455  call continuity(u, v, h, h_tmp, uh, vh, dt, g, gv, cs%continuity_CSp, obc=cs%OBC)
1456  call cpu_clock_begin(id_clock_pass_init)
1457  call pass_var(h_tmp, g%Domain)
1458  call cpu_clock_end(id_clock_pass_init)
1459  cs%h_av(:,:,:) = 0.5*(h(:,:,:) + h_tmp(:,:,:))
1460  else
1461  if (.not. query_initialized(cs%h_av,"h2",restart_cs)) &
1462  cs%h_av(:,:,:) = h(:,:,:)
1463  endif
1464 
1465  ! Determine whether there is a barotropic transport that is to be used
1466  ! to adjust the layers' velocities.
1467  cs%readjust_velocity = .false.
1468  if (cs%readjust_BT_trans) then
1469  if (query_initialized(cs%uhbt_in,"uhbt_in",restart_cs) .and. &
1470  query_initialized(cs%vhbt_in,"vhbt_in",restart_cs)) then
1471  cs%readjust_velocity = .true.
1472  call cpu_clock_begin(id_clock_pass_init)
1473  call pass_vector(cs%uhbt_in, cs%vhbt_in, g%Domain)
1474  call cpu_clock_end(id_clock_pass_init)
1475  endif
1476  endif
1477 
1478  call cpu_clock_begin(id_clock_pass_init)
1479  call pass_vector(cs%u_av,cs%v_av, g%Domain)
1480  call pass_var(cs%h_av, g%Domain)
1481  call pass_vector(uh, vh, g%Domain)
1482  call cpu_clock_end(id_clock_pass_init)
1483 
1484  flux_units = get_flux_units(gv)
1485  cs%id_uh = register_diag_field('ocean_model', 'uh', diag%axesCuL, time, &
1486  'Zonal Thickness Flux', flux_units)
1487  cs%id_vh = register_diag_field('ocean_model', 'vh', diag%axesCvL, time, &
1488  'Meridional Thickness Flux', flux_units)
1489  cs%id_CAu = register_diag_field('ocean_model', 'CAu', diag%axesCuL, time, &
1490  'Zonal Coriolis and Advective Acceleration', 'meter second-2')
1491  cs%id_CAv = register_diag_field('ocean_model', 'CAv', diag%axesCvL, time, &
1492  'Meridional Coriolis and Advective Acceleration', 'meter second-2')
1493  cs%id_PFu = register_diag_field('ocean_model', 'PFu', diag%axesCuL, time, &
1494  'Zonal Pressure Force Acceleration', 'meter second-2')
1495  cs%id_PFv = register_diag_field('ocean_model', 'PFv', diag%axesCvL, time, &
1496  'Meridional Pressure Force Acceleration', 'meter second-2')
1497 
1498  cs%id_uav = register_diag_field('ocean_model', 'uav', diag%axesCuL, time, &
1499  'Barotropic-step Averaged Zonal Velocity', 'meter second-1')
1500  cs%id_vav = register_diag_field('ocean_model', 'vav', diag%axesCvL, time, &
1501  'Barotropic-step Averaged Meridional Velocity', 'meter second-1')
1502 
1503 
1504  if (cs%flux_BT_coupling) then
1505  cs%id_du_adj = register_diag_field('ocean_model', 'du_adj', diag%axesCuL, time, &
1506  'Zonal velocity adjustments due to nonstandard terms', 'meter second-1')
1507  cs%id_dv_adj = register_diag_field('ocean_model', 'dv_adj', diag%axesCvL, time, &
1508  'Meridional velocity adjustments due to nonstandard terms', 'meter second-1')
1509  if (cs%id_du_adj > 0) call safe_alloc_ptr(cs%ADp%du_other,isdb,iedb,jsd,jed,nz)
1510  if (cs%id_dv_adj > 0) call safe_alloc_ptr(cs%ADp%dv_other,isd,ied,jsdb,jedb,nz)
1511  endif
1512  cs%id_u_BT_accel = register_diag_field('ocean_model', 'u_BT_accel', diag%axesCuL, time, &
1513  'Barotropic Anomaly Zonal Acceleration', 'meter second-1')
1514  cs%id_v_BT_accel = register_diag_field('ocean_model', 'v_BT_accel', diag%axesCvL, time, &
1515  'Barotropic Anomaly Meridional Acceleration', 'meter second-1')
1516 
1517  if (debug_truncations) then
1518  if (cs%flux_BT_coupling) then
1519  call safe_alloc_ptr(cs%ADp%du_other,isdb,iedb,jsd,jed,nz)
1520  call safe_alloc_ptr(cs%ADp%dv_other,isd,ied,jsdb,jedb,nz)
1521  endif
1522  endif
1523 
1524  id_clock_cor = cpu_clock_id('(Ocean Coriolis & mom advection)', grain=clock_module)
1525  id_clock_continuity = cpu_clock_id('(Ocean continuity equation)', grain=clock_module)
1526  id_clock_pres = cpu_clock_id('(Ocean pressure force)', grain=clock_module)
1527  id_clock_vertvisc = cpu_clock_id('(Ocean vertical viscosity)', grain=clock_module)
1528  id_clock_horvisc = cpu_clock_id('(Ocean horizontal viscosity)', grain=clock_module)
1529  id_clock_mom_update = cpu_clock_id('(Ocean momentum increments)', grain=clock_module)
1530  id_clock_pass = cpu_clock_id('(Ocean message passing)', grain=clock_module)
1531  id_clock_pass_init = cpu_clock_id('(Ocean init message passing)', grain=clock_routine)
1532  id_clock_btcalc = cpu_clock_id('(Ocean barotropic mode calc)', grain=clock_module)
1533  id_clock_btstep = cpu_clock_id('(Ocean barotropic mode stepping)', grain=clock_module)
1534  id_clock_btforce = cpu_clock_id('(Ocean barotropic forcing calc)', grain=clock_module)
1535 
1536 
1537 end subroutine initialize_dyn_legacy_split
1538 
1539 subroutine end_dyn_legacy_split(CS)
1540  type(mom_dyn_legacy_split_cs), pointer :: CS
1541 ! (inout) CS - The control structure set up by initialize_dyn_legacy_split.
1542 
1543  dealloc_(cs%diffu) ; dealloc_(cs%diffv)
1544  dealloc_(cs%CAu) ; dealloc_(cs%CAv)
1545  dealloc_(cs%PFu) ; dealloc_(cs%PFv)
1546 
1547  if (associated(cs%taux_bot)) deallocate(cs%taux_bot)
1548  if (associated(cs%tauy_bot)) deallocate(cs%tauy_bot)
1549  dealloc_(cs%uhbt) ; dealloc_(cs%vhbt)
1550  dealloc_(cs%u_accel_bt) ; dealloc_(cs%v_accel_bt)
1551  dealloc_(cs%visc_rem_u) ; dealloc_(cs%visc_rem_v)
1552 
1553  dealloc_(cs%eta) ; dealloc_(cs%eta_PF) ; dealloc_(cs%pbce)
1554  dealloc_(cs%h_av) ; dealloc_(cs%u_av) ; dealloc_(cs%v_av)
1555  dealloc_(cs%uhbt_in) ; dealloc_(cs%vhbt_in)
1556 
1557  call dealloc_bt_cont_type(cs%BT_cont)
1558 
1559  deallocate(cs)
1560 end subroutine end_dyn_legacy_split
1561 
1562 end module mom_dynamics_legacy_split
subroutine, public mom_io_init(param_file)
Initialize the MOM_io module.
Definition: MOM_io.F90:840
subroutine, public set_diag_mediator_grid(G, diag_cs)
subroutine, public mom_thermo_chksum(mesg, tv, G, haloshift)
subroutine, public coradcalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS)
Calculates the Coriolis and momentum advection contributions to the acceleration. ...
type(vardesc) function, public var_desc(name, units, longname, hor_grid, z_grid, t_grid, cmor_field_name, cmor_units, conversion, caller)
Returns a vardesc type whose elements have been filled with the provided fields. The argument name is...
Definition: MOM_io.F90:585
subroutine, public legacy_bt_mass_source(h, eta, fluxes, set_cor, dt_therm, dt_since_therm, G, GV, CS)
This module contains the main regridding routines. Regridding comprises two steps: (1) Interpolation ...
Definition: MOM_ALE.F90:7
subroutine, public alloc_bt_cont_type(BT_cont, G, alloc_faces)
alloc_BT_cont_type allocates the arrays contained within a BT_cont_type and initializes them to 0...
character(len=48) function, public get_flux_units(GV)
Returns the model&#39;s thickness flux units, usually m^3/s or kg/s.
This module implements boundary forcing for MOM6.
subroutine, public step_mom_dyn_legacy_split(u, v, h, tv, visc, Time_local, dt, fluxes, p_surf_begin, p_surf_end, dt_since_flux, dt_therm, uh, vh, uhtr, vhtr, eta_av, G, GV, CS, calc_dtbt, VarMix, MEKE)
subroutine, public enable_averaging(time_int_in, time_end_in, diag_cs)
subroutine, public continuity_init(Time, G, GV, param_file, diag, CS)
Initializes continuity_cs.
integer, parameter, public to_all
subroutine, public hor_visc_init(Time, G, param_file, diag, CS)
This subroutine allocates space for and calculates static variables used by this module. The metrics may be 0, 1, or 2-D arrays, while fields like the background viscosities are 2-D arrays. ALLOC is a macro defined in MOM_memory.h to either allocate for dynamic memory, or do nothing when using static memory.
The module calculates interface heights, including free surface height.
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
The following data type a list of diagnostic fields an their variants, as well as variables that cont...
subroutine, public diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, G, GV, CS)
This subroutine imposes the diapycnal mass fluxes and the accompanying diapycnal advection of momentu...
Solve the layer continuity equation.
Controls where open boundary conditions are applied.
subroutine, public register_legacy_barotropic_restarts(HI, GV, param_file, CS, restart_CS)
This subroutine is used to register any fields from MOM_barotropic.F90 that should be written to or r...
subroutine, public vertvisc_remnant(visc, visc_rem_u, visc_rem_v, dt, G, GV, CS)
Calculate the fraction of momentum originally in a layer that remains after a time-step of viscosity...
Implements vertical viscosity (vertvisc)
Provides the ocean grid type.
Definition: MOM_grid.F90:2
The vertvisc_type structure contains vertical viscosities, drag coefficients, and related fields...
subroutine, public pressureforce_init(Time, G, GV, param_file, diag, CS, tides_CSp)
Initialize the pressure force control structure.
This routine drives the diabatic/dianeutral physics for MOM.
Accelerations due to the Coriolis force and momentum advection.
subroutine, public diag_mediator_init(G, nz, param_file, diag_cs, doc_file_dir)
diag_mediator_init initializes the MOM diag_mediator and opens the available diagnostics file...
A thin wrapper for Boussinesq/non-Boussinesq forms of the pressure force calculation.
subroutine, public register_restarts_dyn_legacy_split(HI, GV, param_file, CS, restart_CS, uh, vh)
This module contains I/O framework code.
Definition: MOM_io.F90:2
Defines the horizontal index type (hor_index_type) used for providing index ranges.
subroutine, public mom_accel_chksum(mesg, CAu, CAv, PFu, PFv, diffu, diffv, G, GV, pbce, u_accel_bt, v_accel_bt, symmetric)
The accel_diag_ptrs structure contains pointers to arrays with accelerations, which can later be used...
Variable mixing coefficients.
subroutine, public coriolisadv_init(Time, G, param_file, diag, AD, CS)
Initializes the control structure for coriolisadv_cs.
character(len=48) function, public get_tr_flux_units(GV, tr_units, tr_vol_conc_units, tr_mass_conc_units)
Returns the model&#39;s tracer flux units.
Container for horizontal index ranges for data, computational and global domains. ...
Control structure for mom_coriolisadv.
subroutine, public end_dyn_legacy_split(CS)
subroutine, public horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, CS, OBC)
This subroutine determines the acceleration due to the horizontal viscosity. A combination of biharmo...
The BT_cont_type structure contains information about the summed layer transports and how they will v...
subroutine, public dealloc_bt_cont_type(BT_cont)
dealloc_BT_cont_type deallocates the arrays contained within a BT_cont_type.
subroutine, public adjustments_dyn_legacy_split(u, v, h, dt, G, GV, CS)
Control structure for mom_continuity.
subroutine, public open_boundary_zero_normal_flow(OBC, G, u, v)
Applies zero values to 3d u,v fields on OBC segments.
subroutine, public radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
Apply radiation conditions to 3D u,v at open boundaries.
subroutine, public mom_domains_init(MOM_dom, param_file, symmetric, static_memory, NIHALO, NJHALO, NIGLOBAL, NJGLOBAL, NIPROC, NJPROC, min_halo, domain_name, include_name, param_suffix)
logical function, public is_root_pe()
The cont_diag_ptrs structure contains pointers to arrays with transports, which can later be used for...
subroutine, public pressureforce(h, tv, PFu, PFv, G, GV, CS, ALE_CSp, p_atm, pbce, eta)
A thin layer between the model and the Boussinesq and non-Boussinesq pressure force routines...
subroutine, public mom_set_verbosity(verb)
character(len=48) function, public get_thickness_units(GV)
Returns the model&#39;s thickness units, usually m or kg/m^2.
The ocean_internal_state structure contains pointers to all of the prognostic variables allocated in ...
subroutine, public vertvisc_coef(u, v, h, fluxes, visc, dt, G, GV, CS, OBC)
Calculate the coupling coefficients (CSa_u and CSa_v) and effective layer thicknesses (CSh_u and CSh_...
subroutine, public update_obc_data(OBC, G, GV, tv, h, CS, Time)
Calls appropriate routine to update the open boundary conditions.
subroutine, public legacy_barotropic_init(u, v, h, eta, Time, G, GV, param_file, diag, CS, restart_CS, BT_cont, tides_CSp)
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine, public vertvisc_init(MIS, Time, G, GV, param_file, diag, ADp, dirs, ntrunc, CS)
Initialise the vertical friction module.
subroutine, public set_viscous_ml(u, v, h, tv, fluxes, visc, dt, G, GV, CS)
The following subroutine calculates the thickness of the surface boundary layer for applying an eleva...
subroutine, public mom_mesg(message, verb, all_print)
Type for describing a variable, typically a tracer.
Definition: MOM_io.F90:51
Control structure for this module.
integer function, public register_static_field(module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, do_not_log, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, area)
Registers a static diagnostic, returning an integer handle.
subroutine, public legacy_set_dtbt(G, GV, CS, eta, pbce, BT_cont, gtot_est, SSH_add)
subroutine, public tidal_forcing_init(Time, G, param_file, CS)
This subroutine allocates space for the static variables used by this module. The metrics may be effe...
subroutine, public continuity(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, visc_rem_u, visc_rem_v, u_cor, v_cor, uhbt_aux, vhbt_aux, u_cor_aux, v_cor_aux, BT_cont)
Time steps the layer thicknesses, using a monotonically limited, directionally split PPM scheme...
subroutine, public save_restart(directory, time, G, CS, time_stamped, filename, GV)
subroutine, public vertvisc_limit_vel(u, v, h, ADp, CDp, fluxes, visc, dt, G, GV, CS)
Velocity components which exceed a threshold for physically reasonable values are truncated...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
subroutine, public disable_averaging(diag_cs)
subroutine, public legacy_btstep(use_fluxes, U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, fluxes, pbce, eta_PF_in, U_Cor, V_Cor, accel_layer_u, accel_layer_v, eta_out, uhbtav, vhbtav, G, GV, CS, visc_rem_u, visc_rem_v, etaav, uhbt_out, vhbt_out, OBC, BT_cont, eta_PF_start, taux_bot, tauy_bot, uh0, vh0, u_uh0, v_vh0)
Controls where open boundary conditions are applied.
ALE control structure.
Definition: MOM_ALE.F90:61
subroutine, public restart_init(param_file, CS, restart_root)
subroutine, public vertvisc(u, v, h, fluxes, visc, dt, OBC, ADp, CDp, G, GV, CS, taux_bot, tauy_bot)
Perform a fully implicit vertical diffusion of momentum. Stress top and bottom boundary conditions ar...
subroutine, public initialize_dyn_legacy_split(u, v, h, uh, vh, eta, Time, G, GV, param_file, diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, VarMix, MEKE, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, dirs, ntrunc)
integer function, public register_diag_field(module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, cell_methods, x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
Returns the "diag_mediator" handle for a group (native, CMOR, z-coord, ...) of diagnostics derived fr...
subroutine, public mom_error(level, message, all_print)
subroutine, public legacy_btcalc(h, G, GV, CS, h_u, h_v, may_use_default)
This subroutine calculates the barotropic velocities from the full velocity and thickness fields...
subroutine, public diag_update_remap_grids(diag_cs, alt_h)
Build/update vertical grids for diagnostic remapping.
subroutine, public diabatic_driver_init(Time, G, GV, param_file, useALEalgorithm, diag, ADp, CDp, CS, tracer_flow_CSp, sponge_CSp, ALE_sponge_CSp, diag_to_Z_CSp)
This routine initializes the diabatic driver module.