Step the MOM6 dynamics using an unsplit mixed 2nd order (for continuity) and 3rd order (for the inviscid momentum equations) order scheme.
192 type(ocean_grid_type),
intent(inout) :: G
193 type(verticalGrid_type),
intent(in) :: GV
194 type(unit_scale_type),
intent(in) :: US
195 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: u
196 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: v
197 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: h
198 type(thermo_var_ptrs),
intent(in) :: tv
200 type(vertvisc_type),
intent(inout) :: visc
202 type(time_type),
intent(in) :: Time_local
204 real,
intent(in) :: dt
205 type(mech_forcing),
intent(in) :: forces
206 real,
dimension(:,:),
pointer :: p_surf_begin
208 real,
dimension(:,:),
pointer :: p_surf_end
210 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: uh
212 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: vh
214 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(inout) :: uhtr
216 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(inout) :: vhtr
218 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: eta_av
220 type(MOM_dyn_unsplit_CS),
pointer :: CS
222 type(VarMix_CS),
pointer :: VarMix
224 type(MEKE_type),
pointer :: MEKE
226 type(wave_parameters_CS),
optional,
pointer :: Waves
230 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_av, hp
231 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: up, upp
232 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vp, vpp
233 real,
dimension(:,:),
pointer :: p_surf => null()
236 logical :: dyn_p_surf
237 integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
238 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
239 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
242 h_av(:,:,:) = 0; hp(:,:,:) = 0
243 up(:,:,:) = 0; upp(:,:,:) = 0
244 vp(:,:,:) = 0; vpp(:,:,:) = 0
246 dyn_p_surf =
associated(p_surf_begin) .and.
associated(p_surf_end)
248 call safe_alloc_ptr(p_surf,g%isd,g%ied,g%jsd,g%jed) ; p_surf(:,:) = 0.0
250 p_surf => forces%p_surf
257 call mom_state_chksum(
"Start First Predictor ", u, v, h, uh, vh, g, gv, us)
261 call enable_averages(dt, time_local, cs%diag)
262 call cpu_clock_begin(id_clock_horvisc)
263 call horizontal_viscosity(u, v, h, cs%diffu, cs%diffv, meke, varmix, g, gv, us, cs%hor_visc_CSp)
264 call cpu_clock_end(id_clock_horvisc)
265 call disable_averaging(cs%diag)
269 call cpu_clock_begin(id_clock_continuity)
270 call continuity(u, v, h, hp, uh, vh, dt*0.5, g, gv, us, cs%continuity_CSp, obc=cs%OBC)
271 call cpu_clock_end(id_clock_continuity)
272 call pass_var(hp, g%Domain, clock=id_clock_pass)
273 call pass_vector(uh, vh, g%Domain, clock=id_clock_pass)
275 call enable_averages(0.5*dt, time_local-real_to_time(0.5*us%T_to_s*dt), cs%diag)
277 if (cs%id_uh > 0)
call post_data(cs%id_uh, uh, cs%diag)
278 if (cs%id_vh > 0)
call post_data(cs%id_vh, vh, cs%diag)
279 call disable_averaging(cs%diag)
283 call cpu_clock_begin(id_clock_mom_update)
285 do j=js-2,je+2 ;
do i=is-2,ie+2
286 h_av(i,j,k) = (h(i,j,k) + hp(i,j,k)) * 0.5
288 do j=js,je ;
do i=isq,ieq
289 u(i,j,k) = u(i,j,k) + dt * cs%diffu(i,j,k) * g%mask2dCu(i,j)
291 do j=jsq,jeq ;
do i=is,ie
292 v(i,j,k) = v(i,j,k) + dt * cs%diffv(i,j,k) * g%mask2dCv(i,j)
294 do j=js-2,je+2 ;
do i=isq-2,ieq+2
295 uhtr(i,j,k) = uhtr(i,j,k) + 0.5*dt*uh(i,j,k)
297 do j=jsq-2,jeq+2 ;
do i=is-2,ie+2
298 vhtr(i,j,k) = vhtr(i,j,k) + 0.5*dt*vh(i,j,k)
301 call cpu_clock_end(id_clock_mom_update)
302 call pass_vector(u, v, g%Domain, clock=id_clock_pass)
305 call cpu_clock_begin(id_clock_cor)
306 call coradcalc(u, v, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
307 g, gv, us, cs%CoriolisAdv_CSp)
308 call cpu_clock_end(id_clock_cor)
311 call cpu_clock_begin(id_clock_pres)
312 if (dyn_p_surf)
then ;
do j=js-2,je+2 ;
do i=is-2,ie+2
313 p_surf(i,j) = 0.75*p_surf_begin(i,j) + 0.25*p_surf_end(i,j)
314 enddo ;
enddo ;
endif
315 call pressureforce(h_av, tv, cs%PFu, cs%PFv, g, gv, us, &
316 cs%PressureForce_CSp, cs%ALE_CSp, p_surf)
317 call cpu_clock_end(id_clock_pres)
319 if (
associated(cs%OBC)) then;
if (cs%OBC%update_OBC)
then
320 call update_obc_data(cs%OBC, g, gv, us, tv, h, cs%update_OBC_CSp, time_local)
322 if (
associated(cs%OBC))
then
323 call open_boundary_zero_normal_flow(cs%OBC, g, cs%PFu, cs%PFv)
324 call open_boundary_zero_normal_flow(cs%OBC, g, cs%CAu, cs%CAv)
328 call cpu_clock_begin(id_clock_mom_update)
329 do k=1,nz ;
do j=js,je ;
do i=isq,ieq
330 up(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt_pred * (cs%PFu(i,j,k) + cs%CAu(i,j,k)))
331 enddo ;
enddo ;
enddo
332 do k=1,nz ;
do j=jsq,jeq ;
do i=is,ie
333 vp(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt_pred * (cs%PFv(i,j,k) + cs%CAv(i,j,k)))
334 enddo ;
enddo ;
enddo
335 call cpu_clock_end(id_clock_mom_update)
338 call mom_state_chksum(
"Predictor 1", up, vp, h_av, uh, vh, g, gv, us)
339 call mom_accel_chksum(
"Predictor 1 accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
340 cs%diffu, cs%diffv, g, gv, us)
344 call cpu_clock_begin(id_clock_vertvisc)
345 call enable_averages(dt, time_local, cs%diag)
346 dt_visc = 0.5*dt ;
if (cs%use_correct_dt_visc) dt_visc = dt
347 call set_viscous_ml(u, v, h_av, tv, forces, visc, dt_visc, g, gv, us, cs%set_visc_CSp)
348 call disable_averaging(cs%diag)
350 dt_visc = 0.5*dt ;
if (cs%use_correct_dt_visc) dt_visc = dt_pred
351 call vertvisc_coef(up, vp, h_av, forces, visc, dt_visc, g, gv, us, cs%vertvisc_CSp, cs%OBC)
352 call vertvisc(up, vp, h_av, forces, visc, dt_visc, cs%OBC, cs%ADp, cs%CDp, &
353 g, gv, us, cs%vertvisc_CSp, waves=waves)
354 call cpu_clock_end(id_clock_vertvisc)
355 call pass_vector(up, vp, g%Domain, clock=id_clock_pass)
359 call cpu_clock_begin(id_clock_continuity)
360 call continuity(up, vp, hp, h_av, uh, vh, (0.5*dt), g, gv, us, cs%continuity_CSp, obc=cs%OBC)
361 call cpu_clock_end(id_clock_continuity)
362 call pass_var(h_av, g%Domain, clock=id_clock_pass)
363 call pass_vector(uh, vh, g%Domain, clock=id_clock_pass)
366 do k=1,nz ;
do j=js-2,je+2 ;
do i=is-2,ie+2
367 h_av(i,j,k) = (hp(i,j,k) + h_av(i,j,k)) * 0.5
368 enddo ;
enddo ;
enddo
371 call cpu_clock_begin(id_clock_cor)
372 call coradcalc(up, vp, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
373 g, gv, us, cs%CoriolisAdv_CSp)
374 call cpu_clock_end(id_clock_cor)
377 call cpu_clock_begin(id_clock_pres)
378 if (dyn_p_surf)
then ;
do j=js-2,je+2 ;
do i=is-2,ie+2
379 p_surf(i,j) = 0.25*p_surf_begin(i,j) + 0.75*p_surf_end(i,j)
380 enddo ;
enddo ;
endif
381 call pressureforce(h_av, tv, cs%PFu, cs%PFv, g, gv, us, &
382 cs%PressureForce_CSp, cs%ALE_CSp, p_surf)
383 call cpu_clock_end(id_clock_pres)
385 if (
associated(cs%OBC)) then;
if (cs%OBC%update_OBC)
then
386 call update_obc_data(cs%OBC, g, gv, us, tv, h, cs%update_OBC_CSp, time_local)
388 if (
associated(cs%OBC))
then
389 call open_boundary_zero_normal_flow(cs%OBC, g, cs%PFu, cs%PFv)
390 call open_boundary_zero_normal_flow(cs%OBC, g, cs%CAu, cs%CAv)
394 call cpu_clock_begin(id_clock_mom_update)
395 do k=1,nz ;
do j=js,je ;
do i=isq,ieq
396 upp(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt * 0.5 * (cs%PFu(i,j,k) + cs%CAu(i,j,k)))
397 enddo ;
enddo ;
enddo
398 do k=1,nz ;
do j=jsq,jeq ;
do i=is,ie
399 vpp(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt * 0.5 * (cs%PFv(i,j,k) + cs%CAv(i,j,k)))
400 enddo ;
enddo ;
enddo
401 call cpu_clock_end(id_clock_mom_update)
404 call mom_state_chksum(
"Predictor 2", upp, vpp, h_av, uh, vh, g, gv, us)
405 call mom_accel_chksum(
"Predictor 2 accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
406 cs%diffu, cs%diffv, g, gv, us)
410 call cpu_clock_begin(id_clock_vertvisc)
411 call vertvisc_coef(upp, vpp, hp, forces, visc, dt*0.5, g, gv, us, cs%vertvisc_CSp, cs%OBC)
412 call vertvisc(upp, vpp, hp, forces, visc, dt*0.5, cs%OBC, cs%ADp, cs%CDp, &
413 g, gv, us, cs%vertvisc_CSp, waves=waves)
414 call cpu_clock_end(id_clock_vertvisc)
415 call pass_vector(upp, vpp, g%Domain, clock=id_clock_pass)
419 call cpu_clock_begin(id_clock_continuity)
420 call continuity(upp, vpp, hp, h, uh, vh, (dt*0.5), g, gv, us, cs%continuity_CSp, obc=cs%OBC)
421 call cpu_clock_end(id_clock_continuity)
422 call pass_var(h, g%Domain, clock=id_clock_pass)
423 call pass_vector(uh, vh, g%Domain, clock=id_clock_pass)
426 call diag_update_remap_grids(cs%diag)
428 call enable_averages(0.5*dt, time_local, cs%diag)
430 if (cs%id_uh > 0)
call post_data(cs%id_uh, uh, cs%diag)
431 if (cs%id_vh > 0)
call post_data(cs%id_vh, vh, cs%diag)
432 call disable_averaging(cs%diag)
433 call enable_averages(dt, time_local, cs%diag)
437 do j=js-2,je+2 ;
do i=is-2,ie+2
438 h_av(i,j,k) = 0.5*(h(i,j,k) + hp(i,j,k))
440 do j=js-2,je+2 ;
do i=isq-2,ieq+2
441 uhtr(i,j,k) = uhtr(i,j,k) + 0.5*dt*uh(i,j,k)
443 do j=jsq-2,jeq+2 ;
do i=is-2,ie+2
444 vhtr(i,j,k) = vhtr(i,j,k) + 0.5*dt*vh(i,j,k)
449 call cpu_clock_begin(id_clock_cor)
450 call coradcalc(upp, vpp, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
451 g, gv, us, cs%CoriolisAdv_CSp)
452 call cpu_clock_end(id_clock_cor)
455 call cpu_clock_begin(id_clock_pres)
456 call pressureforce(h_av, tv, cs%PFu, cs%PFv, g, gv, us, &
457 cs%PressureForce_CSp, cs%ALE_CSp, p_surf)
458 call cpu_clock_end(id_clock_pres)
460 if (
associated(cs%OBC)) then;
if (cs%OBC%update_OBC)
then
461 call update_obc_data(cs%OBC, g, gv, us, tv, h, cs%update_OBC_CSp, time_local)
465 if (
associated(cs%OBC))
then
466 call open_boundary_zero_normal_flow(cs%OBC, g, cs%PFu, cs%PFv)
467 call open_boundary_zero_normal_flow(cs%OBC, g, cs%CAu, cs%CAv)
469 do k=1,nz ;
do j=js,je ;
do i=isq,ieq
470 u(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt * (cs%PFu(i,j,k) + cs%CAu(i,j,k)))
471 enddo ;
enddo ;
enddo
472 do k=1,nz ;
do j=jsq,jeq ;
do i=is,ie
473 v(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt * (cs%PFv(i,j,k) + cs%CAv(i,j,k)))
474 enddo ;
enddo ;
enddo
477 call cpu_clock_begin(id_clock_vertvisc)
478 call vertvisc_coef(u, v, h_av, forces, visc, dt, g, gv, us, cs%vertvisc_CSp, cs%OBC)
479 call vertvisc(u, v, h_av, forces, visc, dt, cs%OBC, cs%ADp, cs%CDp, &
480 g, gv, us, cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot, waves=waves)
481 call cpu_clock_end(id_clock_vertvisc)
482 call pass_vector(u, v, g%Domain, clock=id_clock_pass)
485 call mom_state_chksum(
"Corrector", u, v, h, uh, vh, g, gv, us)
486 call mom_accel_chksum(
"Corrector accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
487 cs%diffu, cs%diffv, g, gv, us)
490 if (gv%Boussinesq)
then
491 do j=js,je ;
do i=is,ie ; eta_av(i,j) = -gv%Z_to_H*g%bathyT(i,j) ;
enddo ;
enddo
493 do j=js,je ;
do i=is,ie ; eta_av(i,j) = 0.0 ;
enddo ;
enddo
495 do k=1,nz ;
do j=js,je ;
do i=is,ie
496 eta_av(i,j) = eta_av(i,j) + h_av(i,j,k)
497 enddo ;
enddo ;
enddo
499 if (dyn_p_surf)
deallocate(p_surf)
503 if (cs%id_PFu > 0)
call post_data(cs%id_PFu, cs%PFu, cs%diag)
504 if (cs%id_PFv > 0)
call post_data(cs%id_PFv, cs%PFv, cs%diag)
505 if (cs%id_CAu > 0)
call post_data(cs%id_CAu, cs%CAu, cs%diag)
506 if (cs%id_CAv > 0)
call post_data(cs%id_CAv, cs%CAv, cs%diag)