MOM6
MOM_dynamics_unsplit_RK2.F90
1 !> Time steps the ocean dynamics with an unsplit quasi 2nd order Runge-Kutta scheme
3 
4 ! This file is part of MOM6. See LICENSE.md for the license.
5 
6 !********+*********+*********+*********+*********+*********+*********+**
7 !* *
8 !* By Alistair Adcroft and Robert Hallberg, 2010-2012 *
9 !* *
10 !* This file contains code that does the time-stepping of the *
11 !* adiabatic dynamic core, in this case with a pseudo-second order *
12 !* Runge-Kutta time stepping scheme for the momentum and a forward- *
13 !* backward coupling between the momentum and continuity equations, *
14 !* but without any splitting between the baroclinic and barotropic *
15 !* modes. Apart from the lack of splitting, this is closely analogous *
16 !* to the split time stepping scheme, and efforts have been taken to *
17 !* ensure that for certain configurations (e.g., very short *
18 !* baroclinic time steps, a single barotropic step per baroclinic *
19 !* step, and particular choices about how to coupled the baroclinic *
20 !* and barotropic solves, the two solutions reproduce each other. *
21 !* Although this time stepping scheme is not very efficient with a *
22 !* large number of layers, it is valuable for verifying the proper *
23 !* behavior of the more complicated split time stepping scheme, and *
24 !* is not too inefficient for use with only a few layers. *
25 !* *
26 !* The subroutine step_MOM_dyn_unsplit_RK2 actually does the time *
27 !* stepping, while register_restarts_dyn_unsplit_RK2 sets the fields *
28 !* that are found in a full restart file with this scheme, and *
29 !* initialize_dyn_unsplit_RK2 initializes the cpu clocks that are * *
30 !* used in this module. For largely historical reasons, this module *
31 !* does not have its own control structure, but shares the same *
32 !* control structure with MOM.F90 and the other MOM_dynamics_... *
33 !* modules. *
34 !* *
35 !* Macros written all in capital letters are defined in MOM_memory.h. *
36 !* *
37 !* A small fragment of the grid is shown below: *
38 !* *
39 !* j+1 x ^ x ^ x At x: q, CoriolisBu *
40 !* j+1 > o > o > At ^: v, PFv, CAv, vh, diffv, tauy, vbt, vhtr *
41 !* j x ^ x ^ x At >: u, PFu, CAu, uh, diffu, taux, ubt, uhtr *
42 !* j > o > o > At o: h, bathyT, eta, T, S, tr *
43 !* j-1 x ^ x ^ x *
44 !* i-1 i i+1 *
45 !* i i+1 *
46 !* *
47 !* The boundaries always run through q grid points (x). *
48 !* *
49 !********+*********+*********+*********+*********+*********+*********+**
50 
54 use mom_checksum_packages, only : mom_thermo_chksum, mom_state_chksum, mom_accel_chksum
55 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
56 use mom_cpu_clock, only : clock_component, clock_subcomponent
57 use mom_cpu_clock, only : clock_module_driver, clock_module, clock_routine
58 use mom_diag_mediator, only : diag_mediator_init, enable_averaging
59 use mom_diag_mediator, only : disable_averaging, post_data, safe_alloc_ptr
60 use mom_diag_mediator, only : register_diag_field, register_static_field
61 use mom_diag_mediator, only : set_diag_mediator_grid, diag_ctrl
62 use mom_domains, only : mom_domains_init, pass_var, pass_vector
65 use mom_domains, only : to_south, to_west, to_all, cgrid_ne, scalar_pair
66 use mom_error_handler, only : mom_error, mom_mesg, fatal, warning, is_root_pe
67 use mom_error_handler, only : mom_set_verbosity
69 use mom_get_input, only : directories
70 use mom_io, only : mom_io_init
71 use mom_restart, only : register_restart_field, query_initialized, save_restart
72 use mom_restart, only : restart_init, mom_restart_cs
73 use mom_time_manager, only : time_type, time_type_to_real, operator(+)
74 use mom_time_manager, only : operator(-), operator(>), operator(*), operator(/)
75 
76 use mom_ale, only : ale_cs
77 use mom_boundary_update, only : update_obc_data, update_obc_cs
78 use mom_barotropic, only : barotropic_cs
79 use mom_continuity, only : continuity, continuity_init, continuity_cs
80 use mom_coriolisadv, only : coradcalc, coriolisadv_init, coriolisadv_cs
82 use mom_grid, only : ocean_grid_type
83 use mom_hor_index, only : hor_index_type
84 use mom_hor_visc, only : horizontal_viscosity, hor_visc_init, hor_visc_cs
86 use mom_meke_types, only : meke_type
88 use mom_open_boundary, only : radiation_open_bdry_conds
89 use mom_open_boundary, only : open_boundary_zero_normal_flow
90 use mom_pressureforce, only : pressureforce, pressureforce_init, pressureforce_cs
91 use mom_set_visc, only : set_viscous_ml, set_visc_cs
93 use mom_tidal_forcing, only : tidal_forcing_init, tidal_forcing_cs
95 use mom_vert_friction, only : vertvisc, vertvisc_coef
96 use mom_vert_friction, only : vertvisc_limit_vel, vertvisc_init, vertvisc_cs
97 use mom_verticalgrid, only : verticalgrid_type, get_thickness_units
98 use mom_verticalgrid, only : get_flux_units, get_tr_flux_units
99 
100 implicit none ; private
101 
102 #include <MOM_memory.h>
103 
104 !> MOM_dynamics_unsplit_RK2 module control structure
105 type, public :: mom_dyn_unsplit_rk2_cs ; private
106  real allocable_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: &
107  cau, & !< CAu = f*v - u.grad(u) [m s-2].
108  pfu, & !< PFu = -dM/dx [m s-2].
109  diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor [m s-1 T-1 ~> m s-2].
110 
111  real allocable_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: &
112  cav, & !< CAv = -f*u - u.grad(v) [m s-2].
113  pfv, & !< PFv = -dM/dy [m s-2].
114  diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor [m s-1 T-1 ~> m s-2].
115 
116  real, pointer, dimension(:,:) :: taux_bot => null() !< frictional x-bottom stress from the ocean to the seafloor (Pa)
117  real, pointer, dimension(:,:) :: tauy_bot => null() !< frictional y-bottom stress from the ocean to the seafloor (Pa)
118 
119  real :: be !< A nondimensional number from 0.5 to 1 that controls
120  !! the backward weighting of the time stepping scheme.
121  real :: begw !< A nondimensional number from 0 to 1 that controls
122  !! the extent to which the treatment of gravity waves
123  !! is forward-backward (0) or simulated backward
124  !! Euler (1). 0 is almost always used.
125  logical :: debug !< If true, write verbose checksums for debugging purposes.
126 
127  logical :: module_is_initialized = .false. !< Record whether this mouled has been initialzed.
128 
129  !>@{ Diagnostic IDs
130  integer :: id_uh = -1, id_vh = -1
131  integer :: id_pfu = -1, id_pfv = -1, id_cau = -1, id_cav = -1
132  !!@}
133 
134  type(diag_ctrl), pointer :: diag => null() !< A structure that is used to
135  !! regulate the timing of diagnostic output.
136  type(accel_diag_ptrs), pointer :: adp => null() !< A structure pointing to the
137  !! accelerations in the momentum equations,
138  !! which can later be used to calculate
139  !! derived diagnostics like energy budgets.
140  type(cont_diag_ptrs), pointer :: cdp => null() !< A structure with pointers to
141  !! various terms in the continuity equations,
142  !! which can later be used to calculate
143  !! derived diagnostics like energy budgets.
144 
145  ! The remainder of the structure points to child subroutines' control structures.
146  !> A pointer to the horizontal viscosity control structure
147  type(hor_visc_cs), pointer :: hor_visc_csp => null()
148  !> A pointer to the continuity control structure
149  type(continuity_cs), pointer :: continuity_csp => null()
150  !> A pointer to the CoriolisAdv control structure
151  type(coriolisadv_cs), pointer :: coriolisadv_csp => null()
152  !> A pointer to the PressureForce control structure
153  type(pressureforce_cs), pointer :: pressureforce_csp => null()
154  !> A pointer to the vertvisc control structure
155  type(vertvisc_cs), pointer :: vertvisc_csp => null()
156  !> A pointer to the set_visc control structure
157  type(set_visc_cs), pointer :: set_visc_csp => null()
158  !> A pointer to the tidal forcing control structure
159  type(tidal_forcing_cs), pointer :: tides_csp => null()
160  !> A pointer to the ALE control structure.
161  type(ale_cs), pointer :: ale_csp => null()
162 
163  type(ocean_obc_type), pointer :: obc => null() !< A pointer to an open boundary
164  !! condition type that specifies whether, where, and what open boundary
165  !! conditions are used. If no open BCs are used, this pointer stays
166  !! nullified. Flather OBCs use open boundary_CS as well.
167  !> A pointer to the update_OBC control structure
168  type(update_obc_cs), pointer :: update_obc_csp => null()
169 
170 end type mom_dyn_unsplit_rk2_cs
171 
172 
173 public step_mom_dyn_unsplit_rk2, register_restarts_dyn_unsplit_rk2
174 public initialize_dyn_unsplit_rk2, end_dyn_unsplit_rk2
175 
176 !>@{ CPU time clock IDs
177 integer :: id_clock_cor, id_clock_pres, id_clock_vertvisc
178 integer :: id_clock_horvisc, id_clock_continuity, id_clock_mom_update
179 integer :: id_clock_pass, id_clock_pass_init
180 !!@}
181 
182 contains
183 
184 ! =============================================================================
185 
186 !> Step the MOM6 dynamics using an unsplit quasi-2nd order Runge-Kutta scheme
187 subroutine step_mom_dyn_unsplit_rk2(u_in, v_in, h_in, tv, visc, Time_local, dt, forces, &
188  p_surf_begin, p_surf_end, uh, vh, uhtr, vhtr, eta_av, G, GV, US, CS, &
189  VarMix, MEKE)
190  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure.
191  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
192  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
193  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u_in !< The input and output zonal
194  !! velocity [m s-1].
195  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v_in !< The input and output meridional
196  !! velocity [m s-1].
197  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h_in !< The input and output layer thicknesses,
198  !! [H ~> m or kg m-2], depending on whether
199  !! the Boussinesq approximation is made.
200  type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various
201  !! thermodynamic variables.
202  type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical
203  !! viscosities, bottom drag
204  !! viscosities, and related fields.
205  type(time_type), intent(in) :: time_local !< The model time at the end of
206  !! the time step.
207  real, intent(in) :: dt !< The baroclinic dynamics time step [s].
208  type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces
209  real, dimension(:,:), pointer :: p_surf_begin !< A pointer (perhaps NULL) to
210  !! the surface pressure at the beginning
211  !! of this dynamic step [Pa].
212  real, dimension(:,:), pointer :: p_surf_end !< A pointer (perhaps NULL) to
213  !! the surface pressure at the end of
214  !! this dynamic step [Pa].
215  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uh !< The zonal volume or mass transport
216  !! [H m2 s-1 ~> m3 or kg s-1].
217  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vh !< The meridional volume or mass
218  !! transport [H m2 s-1 ~> m3 or kg s-1].
219  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< The accumulated zonal volume or
220  !! mass transport since the last
221  !! tracer advection [H m2 ~> m3 or kg].
222  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< The accumulated meridional volume
223  !! or mass transport since the last
224  !! tracer advection [H m2 ~> m3 or kg].
225  real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta_av !< The time-mean free surface height
226  !! or column mass [H ~> m or kg m-2].
227  type(mom_dyn_unsplit_rk2_cs), pointer :: cs !< The control structure set up by
228  !! initialize_dyn_unsplit_RK2.
229  type(varmix_cs), pointer :: varmix !< A pointer to a structure with
230  !! fields that specify the spatially
231  !! variable viscosities.
232  type(meke_type), pointer :: meke !< A pointer to a structure containing
233  !! fields related to the Mesoscale
234  !! Eddy Kinetic Energy.
235  ! Local variables
236  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_av, hp
237  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: up
238  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vp
239  real, dimension(:,:), pointer :: p_surf => null()
240  real :: dt_pred ! The time step for the predictor part of the baroclinic
241  ! time stepping.
242  logical :: dyn_p_surf
243  integer :: i, j, k, is, ie, js, je, isq, ieq, jsq, jeq, nz
244  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
245  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
246  dt_pred = dt * cs%BE
247 
248  h_av(:,:,:) = 0; hp(:,:,:) = 0
249  up(:,:,:) = 0
250  vp(:,:,:) = 0
251 
252  dyn_p_surf = associated(p_surf_begin) .and. associated(p_surf_end)
253  if (dyn_p_surf) then
254  call safe_alloc_ptr(p_surf,g%isd,g%ied,g%jsd,g%jed) ; p_surf(:,:) = 0.0
255  else
256  p_surf => forces%p_surf
257  endif
258 
259 ! Runge-Kutta second order accurate two step scheme is used to step
260 ! all of the fields except h. h is stepped separately.
261 
262  if (cs%debug) then
263  call mom_state_chksum("Start Predictor ", u_in, v_in, h_in, uh, vh, g, gv)
264  endif
265 
266 ! diffu = horizontal viscosity terms (u,h)
267  call enable_averaging(dt,time_local, cs%diag)
268  call cpu_clock_begin(id_clock_horvisc)
269  call horizontal_viscosity(u_in, v_in, h_in, cs%diffu, cs%diffv, meke, varmix, &
270  g, gv, us, cs%hor_visc_CSp)
271  call cpu_clock_end(id_clock_horvisc)
272  call disable_averaging(cs%diag)
273  call pass_vector(cs%diffu, cs%diffv, g%Domain, clock=id_clock_pass)
274 
275 ! This continuity step is solely for the Coroilis terms, specifically in the
276 ! denominator of PV and in the mass transport or PV.
277 ! uh = u[n-1]*h[n-1/2]
278 ! hp = h[n-1/2] + dt/2 div . uh
279  call cpu_clock_begin(id_clock_continuity)
280  ! This is a duplicate calculation of the last continuity from the previous step
281  ! and could/should be optimized out. -AJA
282  call continuity(u_in, v_in, h_in, hp, uh, vh, dt_pred, g, gv, us, cs%continuity_CSp, &
283  obc=cs%OBC)
284  call cpu_clock_end(id_clock_continuity)
285  call pass_var(hp, g%Domain, clock=id_clock_pass)
286  call pass_vector(uh, vh, g%Domain, clock=id_clock_pass)
287 
288 ! h_av = (h + hp)/2 (used in PV denominator)
289  call cpu_clock_begin(id_clock_mom_update)
290  do k=1,nz
291  do j=js-2,je+2 ; do i=is-2,ie+2
292  h_av(i,j,k) = (h_in(i,j,k) + hp(i,j,k)) * 0.5
293  enddo ; enddo ; enddo
294  call cpu_clock_end(id_clock_mom_update)
295 
296 ! CAu = -(f+zeta)/h_av vh + d/dx KE (function of u[n-1] and uh[n-1])
297  call cpu_clock_begin(id_clock_cor)
298  call coradcalc(u_in, v_in, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
299  g, gv, us, cs%CoriolisAdv_CSp)
300  call cpu_clock_end(id_clock_cor)
301 
302 ! PFu = d/dx M(h_av,T,S) (function of h[n-1/2])
303  call cpu_clock_begin(id_clock_pres)
304  if (dyn_p_surf) then ; do j=js-2,je+2 ; do i=is-2,ie+2
305  p_surf(i,j) = 0.5*p_surf_begin(i,j) + 0.5*p_surf_end(i,j)
306  enddo ; enddo ; endif
307  call pressureforce(h_in, tv, cs%PFu, cs%PFv, g, gv, us, &
308  cs%PressureForce_CSp, cs%ALE_CSp, p_surf)
309  call cpu_clock_end(id_clock_pres)
310  call pass_vector(cs%PFu, cs%PFv, g%Domain, clock=id_clock_pass)
311  call pass_vector(cs%CAu, cs%CAv, g%Domain, clock=id_clock_pass)
312 
313  if (associated(cs%OBC)) then; if (cs%OBC%update_OBC) then
314  call update_obc_data(cs%OBC, g, gv, us, tv, h_in, cs%update_OBC_CSp, time_local)
315  endif; endif
316  if (associated(cs%OBC)) then
317  call open_boundary_zero_normal_flow(cs%OBC, g, cs%PFu, cs%PFv)
318  call open_boundary_zero_normal_flow(cs%OBC, g, cs%CAu, cs%CAv)
319  call open_boundary_zero_normal_flow(cs%OBC, g, cs%diffu, cs%diffv)
320  endif
321 
322 ! up+[n-1/2] = u[n-1] + dt_pred * (PFu + CAu)
323  call cpu_clock_begin(id_clock_mom_update)
324  do k=1,nz ; do j=js,je ; do i=isq,ieq
325  up(i,j,k) = g%mask2dCu(i,j) * (u_in(i,j,k) + dt_pred * &
326  ((cs%PFu(i,j,k) + cs%CAu(i,j,k)) + us%s_to_T*cs%diffu(i,j,k)))
327  enddo ; enddo ; enddo
328  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
329  vp(i,j,k) = g%mask2dCv(i,j) * (v_in(i,j,k) + dt_pred * &
330  ((cs%PFv(i,j,k) + cs%CAv(i,j,k)) + us%s_to_T*cs%diffv(i,j,k)))
331  enddo ; enddo ; enddo
332  call cpu_clock_end(id_clock_mom_update)
333 
334  if (cs%debug) &
335  call mom_accel_chksum("Predictor 1 accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv,&
336  cs%diffu, cs%diffv, g, gv, us)
337 
338  ! up[n-1/2] <- up*[n-1/2] + dt/2 d/dz visc d/dz up[n-1/2]
339  call cpu_clock_begin(id_clock_vertvisc)
340  call enable_averaging(dt, time_local, cs%diag)
341  call set_viscous_ml(up, vp, h_av, tv, forces, visc, dt_pred, g, gv, us, &
342  cs%set_visc_CSp)
343  call disable_averaging(cs%diag)
344  call vertvisc_coef(up, vp, h_av, forces, visc, dt_pred, g, gv, us, &
345  cs%vertvisc_CSp, cs%OBC)
346  call vertvisc(up, vp, h_av, forces, visc, dt_pred, cs%OBC, cs%ADp, cs%CDp, &
347  g, gv, us, cs%vertvisc_CSp)
348  call cpu_clock_end(id_clock_vertvisc)
349  call pass_vector(up, vp, g%Domain, clock=id_clock_pass)
350 
351 ! uh = up[n-1/2] * h[n-1/2]
352 ! h_av = h + dt div . uh
353  call cpu_clock_begin(id_clock_continuity)
354  call continuity(up, vp, h_in, hp, uh, vh, &
355  dt, g, gv, us, cs%continuity_CSp, obc=cs%OBC)
356  call cpu_clock_end(id_clock_continuity)
357  call pass_var(hp, g%Domain, clock=id_clock_pass)
358  call pass_vector(uh, vh, g%Domain, clock=id_clock_pass)
359 
360 ! h_av <- (h + hp)/2 (centered at n-1/2)
361  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
362  h_av(i,j,k) = (h_in(i,j,k) + hp(i,j,k)) * 0.5
363  enddo ; enddo ; enddo
364 
365  if (cs%debug) &
366  call mom_state_chksum("Predictor 1", up, vp, h_av, uh, vh, g, gv)
367 
368 ! CAu = -(f+zeta(up))/h_av vh + d/dx KE(up) (function of up[n-1/2], h[n-1/2])
369  call cpu_clock_begin(id_clock_cor)
370  call coradcalc(up, vp, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
371  g, gv, us, cs%CoriolisAdv_CSp)
372  call cpu_clock_end(id_clock_cor)
373  if (associated(cs%OBC)) then
374  call open_boundary_zero_normal_flow(cs%OBC, g, cs%CAu, cs%CAv)
375  endif
376 
377 ! call enable_averaging(dt,Time_local, CS%diag) ?????????????????????/
378 
379 ! up* = u[n] + (1+gamma) * dt * ( PFu + CAu ) Extrapolated for damping
380 ! u*[n+1] = u[n] + dt * ( PFu + CAu )
381  do k=1,nz ; do j=js,je ; do i=isq,ieq
382  up(i,j,k) = g%mask2dCu(i,j) * (u_in(i,j,k) + dt * (1.+cs%begw) * &
383  ((cs%PFu(i,j,k) + cs%CAu(i,j,k)) + us%s_to_T*cs%diffu(i,j,k)))
384  u_in(i,j,k) = g%mask2dCu(i,j) * (u_in(i,j,k) + dt * &
385  ((cs%PFu(i,j,k) + cs%CAu(i,j,k)) + us%s_to_T*cs%diffu(i,j,k)))
386  enddo ; enddo ; enddo
387  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
388  vp(i,j,k) = g%mask2dCv(i,j) * (v_in(i,j,k) + dt * (1.+cs%begw) * &
389  ((cs%PFv(i,j,k) + cs%CAv(i,j,k)) + us%s_to_T*cs%diffv(i,j,k)))
390  v_in(i,j,k) = g%mask2dCv(i,j) * (v_in(i,j,k) + dt * &
391  ((cs%PFv(i,j,k) + cs%CAv(i,j,k)) + us%s_to_T*cs%diffv(i,j,k)))
392  enddo ; enddo ; enddo
393 
394 ! up[n] <- up* + dt d/dz visc d/dz up
395 ! u[n] <- u*[n] + dt d/dz visc d/dz u[n]
396  call cpu_clock_begin(id_clock_vertvisc)
397  call vertvisc_coef(up, vp, h_av, forces, visc, dt, g, gv, us, &
398  cs%vertvisc_CSp, cs%OBC)
399  call vertvisc(up, vp, h_av, forces, visc, dt, cs%OBC, cs%ADp, cs%CDp, &
400  g, gv, us, cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot)
401  call vertvisc_coef(u_in, v_in, h_av, forces, visc, dt, g, gv, us, &
402  cs%vertvisc_CSp, cs%OBC)
403  call vertvisc(u_in, v_in, h_av, forces, visc, dt, cs%OBC, cs%ADp, cs%CDp,&
404  g, gv, us, cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot)
405  call cpu_clock_end(id_clock_vertvisc)
406  call pass_vector(up, vp, g%Domain, clock=id_clock_pass)
407  call pass_vector(u_in, v_in, g%Domain, clock=id_clock_pass)
408 
409 ! uh = up[n] * h[n] (up[n] might be extrapolated to damp GWs)
410 ! h[n+1] = h[n] + dt div . uh
411  call cpu_clock_begin(id_clock_continuity)
412  call continuity(up, vp, h_in, h_in, uh, vh, &
413  dt, g, gv, us, cs%continuity_CSp, obc=cs%OBC)
414  call cpu_clock_end(id_clock_continuity)
415  call pass_var(h_in, g%Domain, clock=id_clock_pass)
416  call pass_vector(uh, vh, g%Domain, clock=id_clock_pass)
417 
418 ! Accumulate mass flux for tracer transport
419  do k=1,nz
420  do j=js-2,je+2 ; do i=isq-2,ieq+2
421  uhtr(i,j,k) = uhtr(i,j,k) + dt*uh(i,j,k)
422  enddo ; enddo
423  do j=jsq-2,jeq+2 ; do i=is-2,ie+2
424  vhtr(i,j,k) = vhtr(i,j,k) + dt*vh(i,j,k)
425  enddo ; enddo
426  enddo
427 
428  if (cs%debug) then
429  call mom_state_chksum("Corrector", u_in, v_in, h_in, uh, vh, g, gv)
430  call mom_accel_chksum("Corrector accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
431  cs%diffu, cs%diffv, g, gv, us)
432  endif
433 
434  if (gv%Boussinesq) then
435  do j=js,je ; do i=is,ie ; eta_av(i,j) = -gv%Z_to_H*g%bathyT(i,j) ; enddo ; enddo
436  else
437  do j=js,je ; do i=is,ie ; eta_av(i,j) = 0.0 ; enddo ; enddo
438  endif
439  do k=1,nz ; do j=js,je ; do i=is,ie
440  eta_av(i,j) = eta_av(i,j) + h_av(i,j,k)
441  enddo ; enddo ; enddo
442 
443  if (dyn_p_surf) deallocate(p_surf)
444 
445 ! Here various terms used in to update the momentum equations are
446 ! offered for averaging.
447  if (cs%id_PFu > 0) call post_data(cs%id_PFu, cs%PFu, cs%diag)
448  if (cs%id_PFv > 0) call post_data(cs%id_PFv, cs%PFv, cs%diag)
449  if (cs%id_CAu > 0) call post_data(cs%id_CAu, cs%CAu, cs%diag)
450  if (cs%id_CAv > 0) call post_data(cs%id_CAv, cs%CAv, cs%diag)
451 
452 ! Here the thickness fluxes are offered for averaging.
453  if (cs%id_uh > 0) call post_data(cs%id_uh, uh, cs%diag)
454  if (cs%id_vh > 0) call post_data(cs%id_vh, vh, cs%diag)
455 
456 end subroutine step_mom_dyn_unsplit_rk2
457 
458 ! =============================================================================
459 
460 !> Allocate the control structure for this module, allocates memory in it, and registers
461 !! any auxiliary restart variables that are specific to the unsplit RK2 time stepping scheme.
462 !!
463 !! All variables registered here should have the ability to be recreated if they are not present
464 !! in a restart file.
465 subroutine register_restarts_dyn_unsplit_rk2(HI, GV, param_file, CS, restart_CS)
466  type(hor_index_type), intent(in) :: hi !< A horizontal index type structure.
467  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
468  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
469  !! parameters.
470  type(mom_dyn_unsplit_rk2_cs), pointer :: cs !< The control structure set up by
471  !! initialize_dyn_unsplit_RK2.
472  type(mom_restart_cs), pointer :: restart_cs !< A pointer to the restart control
473  !! structure.
474 ! This subroutine sets up any auxiliary restart variables that are specific
475 ! to the unsplit time stepping scheme. All variables registered here should
476 ! have the ability to be recreated if they are not present in a restart file.
477 
478  ! Local variables
479  character(len=48) :: thickness_units, flux_units
480  integer :: isd, ied, jsd, jed, nz, isdb, iedb, jsdb, jedb
481  isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
482  isdb = hi%IsdB ; iedb = hi%IedB ; jsdb = hi%JsdB ; jedb = hi%JedB
483 
484 ! This is where a control structure that is specific to this module would be allocated.
485  if (associated(cs)) then
486  call mom_error(warning, "register_restarts_dyn_unsplit_RK2 called with an associated "// &
487  "control structure.")
488  return
489  endif
490  allocate(cs)
491 
492  alloc_(cs%diffu(isdb:iedb,jsd:jed,nz)) ; cs%diffu(:,:,:) = 0.0
493  alloc_(cs%diffv(isd:ied,jsdb:jedb,nz)) ; cs%diffv(:,:,:) = 0.0
494  alloc_(cs%CAu(isdb:iedb,jsd:jed,nz)) ; cs%CAu(:,:,:) = 0.0
495  alloc_(cs%CAv(isd:ied,jsdb:jedb,nz)) ; cs%CAv(:,:,:) = 0.0
496  alloc_(cs%PFu(isdb:iedb,jsd:jed,nz)) ; cs%PFu(:,:,:) = 0.0
497  alloc_(cs%PFv(isd:ied,jsdb:jedb,nz)) ; cs%PFv(:,:,:) = 0.0
498 
499  thickness_units = get_thickness_units(gv)
500  flux_units = get_flux_units(gv)
501 
502 ! No extra restart fields are needed with this time stepping scheme.
503 
504 end subroutine register_restarts_dyn_unsplit_rk2
505 
506 !> Initialize parameters and allocate memory associated with the unsplit RK2 dynamics module.
507 subroutine initialize_dyn_unsplit_rk2(u, v, h, Time, G, GV, US, param_file, diag, CS, &
508  restart_CS, Accel_diag, Cont_diag, MIS, MEKE, &
509  OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, &
510  visc, dirs, ntrunc)
511  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure.
512  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
513  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
514  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< The zonal velocity [m s-1].
515  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< The meridional velocity [m s-1].
516  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2]
517  type(time_type), target, intent(in) :: time !< The current model time.
518  type(param_file_type), intent(in) :: param_file !< A structure to parse
519  !! for run-time parameters.
520  type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to
521  !! regulate diagnostic output.
522  type(mom_dyn_unsplit_rk2_cs), pointer :: cs !< The control structure set up
523  !! by initialize_dyn_unsplit_RK2.
524  type(mom_restart_cs), pointer :: restart_cs !< A pointer to the restart
525  !! control structure.
526  type(accel_diag_ptrs), target, intent(inout) :: accel_diag !< A set of pointers to the
527  !! various accelerations in the momentum equations, which can
528  !! be used for later derived diagnostics, like energy budgets.
529  type(cont_diag_ptrs), target, intent(inout) :: cont_diag !< A structure with pointers
530  !! to various terms in the
531  !! continuity equations.
532  type(ocean_internal_state), intent(inout) :: mis !< The "MOM6 Internal State"
533  !! structure, used to pass around pointers
534  !! to various arrays for diagnostic purposes.
535  type(meke_type), pointer :: meke !< MEKE data
536  type(ocean_obc_type), pointer :: obc !< If open boundary conditions
537  !! are used, this points to the ocean_OBC_type
538  !! that was set up in MOM_initialization.
539  type(update_obc_cs), pointer :: update_obc_csp !< If open boundary
540  !! condition updates are used, this points
541  !! to the appropriate control structure.
542  type(ale_cs), pointer :: ale_csp !< This points to the ALE
543  !! control structure.
544  type(set_visc_cs), pointer :: setvisc_csp !< This points to the
545  !! set_visc control
546  !! structure.
547  type(vertvisc_type), intent(inout) :: visc !< A structure containing
548  !! vertical viscosities, bottom drag
549  !! viscosities, and related fields.
550  type(directories), intent(in) :: dirs !< A structure containing several
551  !! relevant directory paths.
552  integer, target, intent(inout) :: ntrunc !< A target for the variable
553  !! that records the number of times the
554  !! velocity is truncated (this should be 0).
555 
556  ! This subroutine initializes all of the variables that are used by this
557  ! dynamic core, including diagnostics and the cpu clocks.
558 
559  ! Local varaibles
560  character(len=40) :: mdl = "MOM_dynamics_unsplit_RK2" ! This module's name.
561  character(len=48) :: thickness_units, flux_units
562  real :: h_convert
563  logical :: use_tides
564  integer :: isd, ied, jsd, jed, nz, isdb, iedb, jsdb, jedb
565  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
566  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
567 
568  if (.not.associated(cs)) call mom_error(fatal, &
569  "initialize_dyn_unsplit_RK2 called with an unassociated control structure.")
570  if (cs%module_is_initialized) then
571  call mom_error(warning, "initialize_dyn_unsplit_RK2 called with a control "// &
572  "structure that has already been initialized.")
573  return
574  endif
575  cs%module_is_initialized = .true.
576 
577  cs%diag => diag
578 
579  call get_param(param_file, mdl, "BE", cs%be, &
580  "If SPLIT is true, BE determines the relative weighting "//&
581  "of a 2nd-order Runga-Kutta baroclinic time stepping "//&
582  "scheme (0.5) and a backward Euler scheme (1) that is "//&
583  "used for the Coriolis and inertial terms. BE may be "//&
584  "from 0.5 to 1, but instability may occur near 0.5. "//&
585  "BE is also applicable if SPLIT is false and USE_RK2 "//&
586  "is true.", units="nondim", default=0.6)
587  call get_param(param_file, mdl, "BEGW", cs%begw, &
588  "If SPLIT is true, BEGW is a number from 0 to 1 that "//&
589  "controls the extent to which the treatment of gravity "//&
590  "waves is forward-backward (0) or simulated backward "//&
591  "Euler (1). 0 is almost always used. "//&
592  "If SPLIT is false and USE_RK2 is true, BEGW can be "//&
593  "between 0 and 0.5 to damp gravity waves.", &
594  units="nondim", default=0.0)
595  call get_param(param_file, mdl, "DEBUG", cs%debug, &
596  "If true, write out verbose debugging data.", &
597  default=.false., debuggingparam=.true.)
598  call get_param(param_file, mdl, "TIDES", use_tides, &
599  "If true, apply tidal momentum forcing.", default=.false.)
600 
601  allocate(cs%taux_bot(isdb:iedb,jsd:jed)) ; cs%taux_bot(:,:) = 0.0
602  allocate(cs%tauy_bot(isd:ied,jsdb:jedb)) ; cs%tauy_bot(:,:) = 0.0
603 
604  mis%diffu => cs%diffu ; mis%diffv => cs%diffv
605  mis%PFu => cs%PFu ; mis%PFv => cs%PFv
606  mis%CAu => cs%CAu ; mis%CAv => cs%CAv
607 
608  cs%ADp => accel_diag ; cs%CDp => cont_diag
609  accel_diag%diffu => cs%diffu ; accel_diag%diffv => cs%diffv
610  accel_diag%PFu => cs%PFu ; accel_diag%PFv => cs%PFv
611  accel_diag%CAu => cs%CAu ; accel_diag%CAv => cs%CAv
612 
613  call continuity_init(time, g, gv, param_file, diag, cs%continuity_CSp)
614  call coriolisadv_init(time, g, param_file, diag, cs%ADp, cs%CoriolisAdv_CSp)
615  if (use_tides) call tidal_forcing_init(time, g, param_file, cs%tides_CSp)
616  call pressureforce_init(time, g, gv, us, param_file, diag, cs%PressureForce_CSp, &
617  cs%tides_CSp)
618  call hor_visc_init(time, g, us, param_file, diag, cs%hor_visc_CSp, meke)
619  call vertvisc_init(mis, time, g, gv, us, param_file, diag, cs%ADp, dirs, &
620  ntrunc, cs%vertvisc_CSp)
621  if (.not.associated(setvisc_csp)) call mom_error(fatal, &
622  "initialize_dyn_unsplit_RK2 called with setVisc_CSp unassociated.")
623  cs%set_visc_CSp => setvisc_csp
624 
625  if (associated(ale_csp)) cs%ALE_CSp => ale_csp
626  if (associated(obc)) cs%OBC => obc
627 
628  flux_units = get_flux_units(gv)
629  h_convert = gv%H_to_m ; if (.not.gv%Boussinesq) h_convert = gv%H_to_kg_m2
630  cs%id_uh = register_diag_field('ocean_model', 'uh', diag%axesCuL, time, &
631  'Zonal Thickness Flux', flux_units, y_cell_method='sum', v_extensive=.true., &
632  conversion=h_convert)
633  cs%id_vh = register_diag_field('ocean_model', 'vh', diag%axesCvL, time, &
634  'Meridional Thickness Flux', flux_units, x_cell_method='sum', v_extensive=.true., &
635  conversion=h_convert)
636  cs%id_CAu = register_diag_field('ocean_model', 'CAu', diag%axesCuL, time, &
637  'Zonal Coriolis and Advective Acceleration', 'meter second-2')
638  cs%id_CAv = register_diag_field('ocean_model', 'CAv', diag%axesCvL, time, &
639  'Meridional Coriolis and Advective Acceleration', 'meter second-2')
640  cs%id_PFu = register_diag_field('ocean_model', 'PFu', diag%axesCuL, time, &
641  'Zonal Pressure Force Acceleration', 'meter second-2')
642  cs%id_PFv = register_diag_field('ocean_model', 'PFv', diag%axesCvL, time, &
643  'Meridional Pressure Force Acceleration', 'meter second-2')
644 
645  id_clock_cor = cpu_clock_id('(Ocean Coriolis & mom advection)', grain=clock_module)
646  id_clock_continuity = cpu_clock_id('(Ocean continuity equation)', grain=clock_module)
647  id_clock_pres = cpu_clock_id('(Ocean pressure force)', grain=clock_module)
648  id_clock_vertvisc = cpu_clock_id('(Ocean vertical viscosity)', grain=clock_module)
649  id_clock_horvisc = cpu_clock_id('(Ocean horizontal viscosity)', grain=clock_module)
650  id_clock_mom_update = cpu_clock_id('(Ocean momentum increments)', grain=clock_module)
651  id_clock_pass = cpu_clock_id('(Ocean message passing)', grain=clock_module)
652  id_clock_pass_init = cpu_clock_id('(Ocean init message passing)', grain=clock_routine)
653 
654 end subroutine initialize_dyn_unsplit_rk2
655 
656 !> Clean up and deallocate memory associated with the dyn_unsplit_RK2 module.
657 subroutine end_dyn_unsplit_rk2(CS)
658  type(mom_dyn_unsplit_rk2_cs), pointer :: cs !< dyn_unsplit_RK2 control structure that
659  !! will be deallocated in this subroutine.
660 
661  dealloc_(cs%diffu) ; dealloc_(cs%diffv)
662  dealloc_(cs%CAu) ; dealloc_(cs%CAv)
663  dealloc_(cs%PFu) ; dealloc_(cs%PFv)
664 
665  deallocate(cs)
666 end subroutine end_dyn_unsplit_rk2
667 
668 end module mom_dynamics_unsplit_rk2
mom_domains::pass_var_complete
Complete a non-blocking halo update on an array.
Definition: MOM_domains.F90:64
mom_time_manager
Wraps the FMS time manager functions.
Definition: MOM_time_manager.F90:2
mom_forcing_type::mech_forcing
Structure that contains pointers to the mechanical forcing at the surface used to drive the liquid oc...
Definition: MOM_forcing_type.F90:185
mom_checksum_packages::mom_state_chksum
Write out checksums of the MOM6 state variables.
Definition: MOM_checksum_packages.F90:23
mom_verticalgrid
Provides a transparent vertical ocean grid type and supporting routines.
Definition: MOM_verticalGrid.F90:2
mom_continuity::continuity_cs
Control structure for mom_continuity.
Definition: MOM_continuity.F90:26
mom_hor_visc::hor_visc_cs
Control structure for horizontal viscosity.
Definition: MOM_hor_visc.F90:29
mom_coriolisadv::coriolisadv_cs
Control structure for mom_coriolisadv.
Definition: MOM_CoriolisAdv.F90:27
mom_file_parser::log_version
An overloaded interface to log version information about modules.
Definition: MOM_file_parser.F90:109
mom_boundary_update
Controls where open boundary conditions are applied.
Definition: MOM_boundary_update.F90:3
mom_domains::pass_vector_start
Initiate a halo update on a pair of arrays representing the two components of a vector.
Definition: MOM_domains.F90:69
mom_diag_mediator
The subroutines here provide convenient wrappers to the fms diag_manager interfaces with additional d...
Definition: MOM_diag_mediator.F90:3
mom_variables::thermo_var_ptrs
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Definition: MOM_variables.F90:82
mom_get_input::directories
Container for paths and parameter file names.
Definition: MOM_get_input.F90:20
mom_barotropic
Baropotric solver.
Definition: MOM_barotropic.F90:2
mom_domains::pass_var
Do a halo update on an array.
Definition: MOM_domains.F90:49
mom_file_parser::param_file_type
A structure that can be parsed to read and document run-time parameters.
Definition: MOM_file_parser.F90:54
mom_boundary_update::update_obc_cs
The control structure for the MOM_boundary_update module.
Definition: MOM_boundary_update.F90:37
mom_file_parser::get_param
An overloaded interface to read and log the values of various types of parameters.
Definition: MOM_file_parser.F90:102
mom_checksum_packages
Provides routines that do checksums of groups of MOM variables.
Definition: MOM_checksum_packages.F90:2
mom_hor_index
Defines the horizontal index type (hor_index_type) used for providing index ranges.
Definition: MOM_hor_index.F90:2
mom_io
This module contains I/O framework code.
Definition: MOM_io.F90:2
mom_vert_friction::vertvisc_cs
The control structure with parameters and memory for the MOM_vert_friction module.
Definition: MOM_vert_friction.F90:39
mom_restart::mom_restart_cs
A restart registry and the control structure for restarts.
Definition: MOM_restart.F90:72
mom_get_input
Reads the only Fortran name list needed to boot-strap the model.
Definition: MOM_get_input.F90:6
mom_unit_scaling::unit_scale_type
Describes various unit conversion factors.
Definition: MOM_unit_scaling.F90:14
mom_domains::pass_vector_complete
Complete a halo update on a pair of arrays representing the two components of a vector.
Definition: MOM_domains.F90:74
mom_diag_mediator::post_data
Make a diagnostic available for averaging or output.
Definition: MOM_diag_mediator.F90:70
mom_domains::pass_vector
Do a halo update on a pair of arrays representing the two components of a vector.
Definition: MOM_domains.F90:54
mom_tidal_forcing
Tidal contributions to geopotential.
Definition: MOM_tidal_forcing.F90:2
mom_thickness_diffuse::thickness_diffuse_cs
Control structure for thickness diffusion.
Definition: MOM_thickness_diffuse.F90:37
mom_forcing_type
This module implements boundary forcing for MOM6.
Definition: MOM_forcing_type.F90:2
mom_domains::pass_var_start
Initiate a non-blocking halo update on an array.
Definition: MOM_domains.F90:59
mom_hor_visc
Calculates horizontal viscosity and viscous stresses.
Definition: MOM_hor_visc.F90:2
mom_dynamics_unsplit_rk2
Time steps the ocean dynamics with an unsplit quasi 2nd order Runge-Kutta scheme.
Definition: MOM_dynamics_unsplit_RK2.F90:2
mom_tidal_forcing::tidal_forcing_cs
The control structure for the MOM_tidal_forcing module.
Definition: MOM_tidal_forcing.F90:26
mom_variables::vertvisc_type
Vertical viscosities, drag coefficients, and related fields.
Definition: MOM_variables.F90:200
mom_verticalgrid::verticalgrid_type
Describes the vertical ocean grid, including unit conversion factors.
Definition: MOM_verticalGrid.F90:24
mom_restart
The MOM6 facility for reading and writing restart files, and querying what has been read.
Definition: MOM_restart.F90:2
mom_meke_types::meke_type
This type is used to exchange information related to the MEKE calculations.
Definition: MOM_MEKE_types.F90:8
mom_domains
Describes the decomposed MOM domain and has routines for communications across PEs.
Definition: MOM_domains.F90:2
mom_ale
This module contains the main regridding routines.
Definition: MOM_ALE.F90:9
mom_lateral_mixing_coeffs::varmix_cs
Variable mixing coefficients.
Definition: MOM_lateral_mixing_coeffs.F90:26
mom_variables
Provides transparent structures with groups of MOM6 variables and supporting routines.
Definition: MOM_variables.F90:2
mom_open_boundary
Controls where open boundary conditions are applied.
Definition: MOM_open_boundary.F90:2
mom_cpu_clock
Wraps the MPP cpu clock functions.
Definition: MOM_cpu_clock.F90:2
mom_file_parser
The MOM6 facility to parse input files for runtime parameters.
Definition: MOM_file_parser.F90:2
mom_ale::ale_cs
ALE control structure.
Definition: MOM_ALE.F90:63
mom_dynamics_unsplit_rk2::mom_dyn_unsplit_rk2_cs
MOM_dynamics_unsplit_RK2 module control structure.
Definition: MOM_dynamics_unsplit_RK2.F90:105
mom_variables::cont_diag_ptrs
Pointers to arrays with transports, which can later be used for derived diagnostics,...
Definition: MOM_variables.F90:185
mom_variables::accel_diag_ptrs
Pointers to arrays with accelerations, which can later be used for derived diagnostics,...
Definition: MOM_variables.F90:155
mom_hor_index::hor_index_type
Container for horizontal index ranges for data, computational and global domains.
Definition: MOM_hor_index.F90:15
mom_grid
Provides the ocean grid type.
Definition: MOM_grid.F90:2
mom_open_boundary::ocean_obc_type
Open-boundary data.
Definition: MOM_open_boundary.F90:186
mom_debugging::check_redundant
Check for consistency between the duplicated points of a C-grid vector.
Definition: MOM_debugging.F90:33
mom_restart::register_restart_field
Register fields for restarts.
Definition: MOM_restart.F90:107
mom_unit_scaling
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Definition: MOM_unit_scaling.F90:2
mom_set_visc
Calculates various values related to the bottom boundary layer, such as the viscosity and thickness o...
Definition: MOM_set_viscosity.F90:3
mom_debugging
Provides checksumming functions for debugging.
Definition: MOM_debugging.F90:7
mom_continuity
Solve the layer continuity equation.
Definition: MOM_continuity.F90:2
mom_vert_friction
Implements vertical viscosity (vertvisc)
Definition: MOM_vert_friction.F90:2
mom_pressureforce::pressureforce_cs
Pressure force control structure.
Definition: MOM_PressureForce.F90:31
mom_coriolisadv
Accelerations due to the Coriolis force and momentum advection.
Definition: MOM_CoriolisAdv.F90:2
mom_thickness_diffuse
Thickness diffusion (or Gent McWilliams)
Definition: MOM_thickness_diffuse.F90:2
mom_lateral_mixing_coeffs
Variable mixing coefficients.
Definition: MOM_lateral_mixing_coeffs.F90:2
mom_restart::query_initialized
Indicate whether a field has been read from a restart file.
Definition: MOM_restart.F90:116
mom_variables::ocean_internal_state
Pointers to all of the prognostic variables allocated in MOM_variables.F90 and MOM....
Definition: MOM_variables.F90:126
mom_pressureforce
A thin wrapper for Boussinesq/non-Boussinesq forms of the pressure force calculation.
Definition: MOM_PressureForce.F90:2
mom_error_handler
Routines for error handling and I/O management.
Definition: MOM_error_handler.F90:2
mom_barotropic::barotropic_cs
The barotropic stepping control stucture.
Definition: MOM_barotropic.F90:100
mom_set_visc::set_visc_cs
Control structure for MOM_set_visc.
Definition: MOM_set_viscosity.F90:44
mom_grid::ocean_grid_type
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:25
mom_diag_mediator::diag_ctrl
The following data type a list of diagnostic fields an their variants, as well as variables that cont...
Definition: MOM_diag_mediator.F90:239