12 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
14 use mom_cpu_clock,
only : clock_module_driver, clock_module, clock_routine
21 use mom_domains,
only : to_north, to_east, omit_corners
34 use mom_time_manager,
only :
operator(-),
operator(>),
operator(*),
operator(/)
65 implicit none ;
private
67 #include <MOM_memory.h>
71 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: &
72 cau, & !< CAu = f*v - u.grad(u) [L T-2 ~> m s-2]
73 pfu, & !< PFu = -dM/dx [L T-2 ~> m s-2]
76 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: &
77 cav, & !< CAv = -f*u - u.grad(v) [L T-2 ~> m s-2]
78 pfv, & !< PFv = -dM/dy [L T-2 ~> m s-2]
81 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: visc_rem_u
87 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: u_accel_bt
91 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: visc_rem_v
97 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: v_accel_bt
103 real allocable_,
dimension(NIMEM_,NJMEM_) :: eta
106 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: u_av
109 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: v_av
112 real allocable_,
dimension(NIMEM_,NJMEM_,NKMEM_) :: h_av
114 real allocable_,
dimension(NIMEM_,NJMEM_) :: eta_pf
116 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_) :: uhbt
119 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_) :: vhbt
122 real allocable_,
dimension(NIMEM_,NJMEM_,NKMEM_) :: pbce
126 real,
pointer,
dimension(:,:) :: taux_bot => null()
128 real,
pointer,
dimension(:,:) :: tauy_bot => null()
136 logical :: bt_use_layer_fluxes
139 logical :: split_bottom_stress
154 logical :: module_is_initialized = .false.
157 integer :: id_uh = -1, id_vh = -1
158 integer :: id_umo = -1, id_vmo = -1
159 integer :: id_umo_2d = -1, id_vmo_2d = -1
160 integer :: id_pfu = -1, id_pfv = -1
161 integer :: id_cau = -1, id_cav = -1
164 integer :: id_uav = -1, id_vav = -1
165 integer :: id_u_bt_accel = -1, id_v_bt_accel = -1
199 type(
ale_cs),
pointer :: ale_csp => null()
208 type(group_pass_type) :: pass_eta
209 type(group_pass_type) :: pass_visc_rem
210 type(group_pass_type) :: pass_uvp
211 type(group_pass_type) :: pass_hp_uv
212 type(group_pass_type) :: pass_uv
213 type(group_pass_type) :: pass_h
214 type(group_pass_type) :: pass_av_uvh
236 Time_local, dt, forces, p_surf_begin, p_surf_end, &
237 uh, vh, uhtr, vhtr, eta_av, &
238 G, GV, US, CS, calc_dtbt, VarMix, MEKE, thickness_diffuse_CSp, Waves)
242 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
243 target,
intent(inout) :: u
244 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
245 target,
intent(inout) :: v
246 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
250 type(time_type),
intent(in) :: time_local
251 real,
intent(in) :: dt
253 real,
dimension(:,:),
pointer :: p_surf_begin
255 real,
dimension(:,:),
pointer :: p_surf_end
257 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
258 target,
intent(inout) :: uh
260 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
261 target,
intent(inout) :: vh
263 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
264 intent(inout) :: uhtr
266 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
267 intent(inout) :: vhtr
269 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: eta_av
272 logical,
intent(in) :: calc_dtbt
281 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: up
282 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vp
283 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: hp
285 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_bc_accel
286 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_bc_accel
290 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
target :: uh_in
291 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
target :: vh_in
295 real,
dimension(SZIB_(G),SZJ_(G)) :: uhbt_out
296 real,
dimension(SZI_(G),SZJB_(G)) :: vhbt_out
300 real,
dimension(SZI_(G),SZJ_(G)) :: eta_pred
304 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_old_rad_obc
305 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_old_rad_obc
310 real,
pointer,
dimension(:,:) :: &
311 p_surf => null(), eta_pf_start => null(), &
312 taux_bot => null(), tauy_bot => null(), &
315 real,
pointer,
dimension(:,:,:) :: &
316 uh_ptr => null(), u_ptr => null(), vh_ptr => null(), v_ptr => null(), &
322 logical :: dyn_p_surf
323 logical :: bt_cont_bt_thick
327 logical :: showcalltree, sym
329 integer :: i, j, k, is, ie, js, je, isq, ieq, jsq, jeq, nz
330 integer :: cont_stencil
331 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
332 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
333 u_av => cs%u_av ; v_av => cs%v_av ; h_av => cs%h_av ; eta => cs%eta
335 sym=.false.;
if (g%Domain%symmetric) sym=.true.
337 showcalltree = calltree_showquery()
338 if (showcalltree)
call calltree_enter(
"step_MOM_dyn_split_RK2(), MOM_dynamics_split_RK2.F90")
342 do j=g%jsd,g%jed ;
do i=g%isdB,g%iedB ; up(i,j,k) = 0.0 ;
enddo ;
enddo
343 do j=g%jsdB,g%jedB ;
do i=g%isd,g%ied ; vp(i,j,k) = 0.0 ;
enddo ;
enddo
344 do j=g%jsd,g%jed ;
do i=g%isd,g%ied ; hp(i,j,k) = h(i,j,k) ;
enddo ;
enddo
351 call mom_state_chksum(
"Start predictor ", u, v, h, uh, vh, g, gv, us, symmetric=sym)
356 dyn_p_surf =
associated(p_surf_begin) .and.
associated(p_surf_end)
359 call safe_alloc_ptr(eta_pf_start,g%isd,g%ied,g%jsd,g%jed)
360 eta_pf_start(:,:) = 0.0
362 p_surf => forces%p_surf
365 if (
associated(cs%OBC))
then
368 do k=1,nz ;
do j=g%jsd,g%jed ;
do i=g%IsdB,g%IedB
369 u_old_rad_obc(i,j,k) = u_av(i,j,k)
370 enddo ;
enddo ;
enddo
371 do k=1,nz ;
do j=g%JsdB,g%JedB ;
do i=g%isd,g%ied
372 v_old_rad_obc(i,j,k) = v_av(i,j,k)
373 enddo ;
enddo ;
enddo
376 bt_cont_bt_thick = .false.
377 if (
associated(cs%BT_cont)) bt_cont_bt_thick = &
378 (
allocated(cs%BT_cont%h_u) .and.
allocated(cs%BT_cont%h_v))
380 if (cs%split_bottom_stress)
then
381 taux_bot => cs%taux_bot ; tauy_bot => cs%tauy_bot
391 call create_group_pass(cs%pass_visc_rem, cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
392 to_all+scalar_pair, cgrid_ne, halo=max(1,cont_stencil))
408 if (cs%begw == 0.0)
call enable_averages(dt, time_local, cs%diag)
410 call pressureforce(h, tv, cs%PFu, cs%PFv, g, gv, us, cs%PressureForce_CSp, &
411 cs%ALE_CSp, p_surf, cs%pbce, cs%eta_PF)
413 pa_to_eta = 1.0 / gv%H_to_Pa
415 do j=jsq,jeq+1 ;
do i=isq,ieq+1
416 eta_pf_start(i,j) = cs%eta_PF(i,j) - pa_to_eta * &
417 (p_surf_begin(i,j) - p_surf_end(i,j))
421 call disable_averaging(cs%diag)
422 if (showcalltree)
call calltree_waypoint(
"done with PressureForce (step_MOM_dyn_split_RK2)")
424 if (
associated(cs%OBC)) then;
if (cs%OBC%update_OBC)
then
425 call update_obc_data(cs%OBC, g, gv, us, tv, h, cs%update_OBC_CSp, time_local)
427 if (
associated(cs%OBC) .and. cs%debug_OBC) &
428 call open_boundary_zero_normal_flow(cs%OBC, g, cs%PFu, cs%PFv)
430 if (g%nonblocking_updates) &
435 call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
436 g, gv, us, cs%CoriolisAdv_CSp)
438 if (showcalltree)
call calltree_waypoint(
"done with CorAdCalc (step_MOM_dyn_split_RK2)")
444 do j=js,je ;
do i=isq,ieq
445 u_bc_accel(i,j,k) = (cs%CAu(i,j,k) + cs%PFu(i,j,k)) + cs%diffu(i,j,k)
447 do j=jsq,jeq ;
do i=is,ie
448 v_bc_accel(i,j,k) = (cs%CAv(i,j,k) + cs%PFv(i,j,k)) + cs%diffv(i,j,k)
451 if (
associated(cs%OBC))
then
452 call open_boundary_zero_normal_flow(cs%OBC, g, u_bc_accel, v_bc_accel)
458 cs%diffu, cs%diffv, g, gv, us, cs%pbce, u_bc_accel, v_bc_accel, &
463 call check_redundant(
"pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
469 do j=js,je ;
do i=isq,ieq
470 up(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt * u_bc_accel(i,j,k))
472 do j=jsq,jeq ;
do i=is,ie
473 vp(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt * v_bc_accel(i,j,k))
477 call enable_averages(dt, time_local, cs%diag)
478 call set_viscous_ml(u, v, h, tv, forces, visc, dt, g, gv, us, &
480 call disable_averaging(cs%diag)
483 call uvchksum(
"before vertvisc: up", up, vp, g%HI, haloshift=0, symmetric=sym, scale=us%L_T_to_m_s)
485 call vertvisc_coef(up, vp, h, forces, visc, dt, g, gv, us, cs%vertvisc_CSp, cs%OBC)
486 call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, us, cs%vertvisc_CSp)
488 if (showcalltree)
call calltree_waypoint(
"done with vertvisc_coef (step_MOM_dyn_split_RK2)")
492 if (g%nonblocking_updates)
then
496 call do_group_pass(cs%pass_eta, g%Domain)
497 call do_group_pass(cs%pass_visc_rem, g%Domain)
503 if (.not.bt_cont_bt_thick) &
504 call btcalc(h, g, gv, cs%barotropic_CSp, obc=cs%OBC)
505 call bt_mass_source(h, eta, .true., g, gv, cs%barotropic_CSp)
508 if (g%nonblocking_updates) &
512 if (
associated(cs%BT_cont) .or. cs%BT_use_layer_fluxes)
then
514 call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, us, cs%continuity_CSp, &
515 obc=cs%OBC, visc_rem_u=cs%visc_rem_u, visc_rem_v=cs%visc_rem_v, bt_cont=cs%BT_cont)
517 if (bt_cont_bt_thick)
then
518 call btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v, &
521 if (showcalltree)
call calltree_waypoint(
"done with continuity[BT_cont] (step_MOM_dyn_split_RK2)")
524 if (cs%BT_use_layer_fluxes)
then
525 uh_ptr => uh_in ; vh_ptr => vh_in; u_ptr => u ; v_ptr => v
529 if (calc_dtbt)
call set_dtbt(g, gv, us, cs%barotropic_CSp, eta, cs%pbce)
530 if (showcalltree)
call calltree_enter(
"btstep(), MOM_barotropic.F90")
532 call btstep(u, v, eta, dt, u_bc_accel, v_bc_accel, forces, cs%pbce, cs%eta_PF, &
533 u_av, v_av, cs%u_accel_bt, cs%v_accel_bt, eta_pred, cs%uhbt, cs%vhbt, &
534 g, gv, us, cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, &
535 obc=cs%OBC, bt_cont=cs%BT_cont, eta_pf_start=eta_pf_start, &
536 taux_bot=taux_bot, tauy_bot=tauy_bot, &
537 uh0=uh_ptr, vh0=vh_ptr, u_uh0=u_ptr, v_vh0=v_ptr)
547 do j=jsq,jeq ;
do i=is,ie
548 vp(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt_pred * &
549 (v_bc_accel(i,j,k) + cs%v_accel_bt(i,j,k)))
551 do j=js,je ;
do i=isq,ieq
552 up(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt_pred * &
553 (u_bc_accel(i,j,k) + cs%u_accel_bt(i,j,k)))
559 call uvchksum(
"Predictor 1 [uv]", up, vp, g%HI, haloshift=0, symmetric=sym, scale=us%L_T_to_m_s)
560 call hchksum(h,
"Predictor 1 h", g%HI, haloshift=1, scale=gv%H_to_m)
561 call uvchksum(
"Predictor 1 [uv]h", uh, vh, g%HI,haloshift=2, &
562 symmetric=sym, scale=gv%H_to_m*us%L_to_m**2*us%s_to_T)
565 cs%diffu, cs%diffv, g, gv, us, cs%pbce, cs%u_accel_bt, cs%v_accel_bt, symmetric=sym)
566 call mom_state_chksum(
"Predictor 1 init", u, v, h, uh, vh, g, gv, us, haloshift=2, &
576 call uvchksum(
"0 before vertvisc: [uv]p", up, vp, g%HI,haloshift=0, symmetric=sym, scale=us%L_T_to_m_s)
578 call vertvisc_coef(up, vp, h, forces, visc, dt_pred, g, gv, us, cs%vertvisc_CSp, &
580 call vertvisc(up, vp, h, forces, visc, dt_pred, cs%OBC, cs%ADp, cs%CDp, g, &
581 gv, us, cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot, waves=waves)
582 if (showcalltree)
call calltree_waypoint(
"done with vertvisc (step_MOM_dyn_split_RK2)")
583 if (g%nonblocking_updates)
then
588 call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt_pred, g, gv, us, cs%vertvisc_CSp)
591 call do_group_pass(cs%pass_visc_rem, g%Domain, clock=
id_clock_pass)
592 if (g%nonblocking_updates)
then
595 call do_group_pass(cs%pass_uvp, g%Domain, clock=
id_clock_pass)
601 call continuity(up, vp, h, hp, uh, vh, dt, g, gv, us, cs%continuity_CSp, &
602 cs%uhbt, cs%vhbt, cs%OBC, cs%visc_rem_u, cs%visc_rem_v, &
603 u_av, v_av, bt_cont=cs%BT_cont)
605 if (showcalltree)
call calltree_waypoint(
"done with continuity (step_MOM_dyn_split_RK2)")
607 call do_group_pass(cs%pass_hp_uv, g%Domain, clock=
id_clock_pass)
609 if (
associated(cs%OBC))
then
612 call uvchksum(
"Pre OBC avg [uv]", u_av, v_av, g%HI, haloshift=1, symmetric=sym, scale=us%L_T_to_m_s)
614 call radiation_open_bdry_conds(cs%OBC, u_av, u_old_rad_obc, v_av, v_old_rad_obc, g, us, dt_pred)
617 call uvchksum(
"Post OBC avg [uv]", u_av, v_av, g%HI, haloshift=1, symmetric=sym, scale=us%L_T_to_m_s)
623 if (g%nonblocking_updates)
then
629 do k=1,nz ;
do j=js-2,je+2 ;
do i=is-2,ie+2
630 h_av(i,j,k) = 0.5*(h(i,j,k) + hp(i,j,k))
631 enddo ;
enddo ;
enddo
634 call enable_averages(dt, time_local, cs%diag)
641 call bt_mass_source(hp, eta_pred, .false., g, gv, cs%barotropic_CSp)
644 if (cs%begw /= 0.0)
then
649 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie+1
650 hp(i,j,k) = (1.0-cs%begw)*h(i,j,k) + cs%begw*hp(i,j,k)
651 enddo ;
enddo ;
enddo
656 call pressureforce(hp, tv, cs%PFu, cs%PFv, g, gv, us, cs%PressureForce_CSp, &
657 cs%ALE_CSp, p_surf, cs%pbce, cs%eta_PF)
659 if (showcalltree)
call calltree_waypoint(
"done with PressureForce[hp=(1-b).h+b.h] (step_MOM_dyn_split_RK2)")
662 if (g%nonblocking_updates) &
665 if (bt_cont_bt_thick)
then
666 call btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v, &
668 if (showcalltree)
call calltree_waypoint(
"done with btcalc[BT_cont_BT_thick] (step_MOM_dyn_split_RK2)")
672 call mom_state_chksum(
"Predictor ", up, vp, hp, uh, vh, g, gv, us, symmetric=sym)
673 call uvchksum(
"Predictor avg [uv]", u_av, v_av, g%HI, haloshift=1, symmetric=sym, scale=us%L_T_to_m_s)
674 call hchksum(h_av,
"Predictor avg h", g%HI, haloshift=0, scale=gv%H_to_m)
683 meke, varmix, g, gv, us, cs%hor_visc_CSp, &
684 obc=cs%OBC, bt=cs%barotropic_CSp)
686 if (showcalltree)
call calltree_waypoint(
"done with horizontal_viscosity (step_MOM_dyn_split_RK2)")
690 call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, &
691 g, gv, us, cs%CoriolisAdv_CSp)
693 if (showcalltree)
call calltree_waypoint(
"done with CorAdCalc (step_MOM_dyn_split_RK2)")
701 do j=js,je ;
do i=isq,ieq
702 u_bc_accel(i,j,k) = (cs%Cau(i,j,k) + cs%PFu(i,j,k)) + cs%diffu(i,j,k)
704 do j=jsq,jeq ;
do i=is,ie
705 v_bc_accel(i,j,k) = (cs%Cav(i,j,k) + cs%PFv(i,j,k)) + cs%diffv(i,j,k)
708 if (
associated(cs%OBC))
then
709 call open_boundary_zero_normal_flow(cs%OBC, g, u_bc_accel, v_bc_accel)
714 call mom_accel_chksum(
"corr pre-btstep accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
715 cs%diffu, cs%diffv, g, gv, us, cs%pbce, u_bc_accel, v_bc_accel, &
719 call check_redundant(
"corr pre-btstep CS%diff ", cs%diffu, cs%diffv, g)
720 call check_redundant(
"corr pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
726 if (cs%BT_use_layer_fluxes)
then
727 uh_ptr => uh ; vh_ptr => vh ; u_ptr => u_av ; v_ptr => v_av
730 if (showcalltree)
call calltree_enter(
"btstep(), MOM_barotropic.F90")
732 call btstep(u, v, eta, dt, u_bc_accel, v_bc_accel, forces, cs%pbce, &
733 cs%eta_PF, u_av, v_av, cs%u_accel_bt, cs%v_accel_bt, &
734 eta_pred, cs%uhbt, cs%vhbt, g, gv, us, cs%barotropic_CSp, &
735 cs%visc_rem_u, cs%visc_rem_v, etaav=eta_av, obc=cs%OBC, &
736 bt_cont = cs%BT_cont, eta_pf_start=eta_pf_start, &
737 taux_bot=taux_bot, tauy_bot=tauy_bot, &
738 uh0=uh_ptr, vh0=vh_ptr, u_uh0=u_ptr, v_vh0=v_ptr)
739 do j=js,je ;
do i=is,ie ; eta(i,j) = eta_pred(i,j) ;
enddo ;
enddo
752 do j=js,je ;
do i=isq,ieq
753 u(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt * &
754 (u_bc_accel(i,j,k) + cs%u_accel_bt(i,j,k)))
756 do j=jsq,jeq ;
do i=is,ie
757 v(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt * &
758 (v_bc_accel(i,j,k) + cs%v_accel_bt(i,j,k)))
764 call uvchksum(
"Corrector 1 [uv]", u, v, g%HI,haloshift=0, symmetric=sym, scale=us%L_T_to_m_s)
765 call hchksum(h,
"Corrector 1 h", g%HI, haloshift=2, scale=gv%H_to_m)
766 call uvchksum(
"Corrector 1 [uv]h", uh, vh, g%HI, haloshift=2, &
767 symmetric=sym, scale=gv%H_to_m*us%L_to_m**2*us%s_to_T)
770 cs%diffu, cs%diffv, g, gv, us, cs%pbce, cs%u_accel_bt, cs%v_accel_bt, &
777 call vertvisc_coef(u, v, h, forces, visc, dt, g, gv, us, cs%vertvisc_CSp, cs%OBC)
778 call vertvisc(u, v, h, forces, visc, dt, cs%OBC, cs%ADp, cs%CDp, g, gv, us, &
779 cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot,waves=waves)
780 if (g%nonblocking_updates)
then
785 call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, us, cs%vertvisc_CSp)
787 if (showcalltree)
call calltree_waypoint(
"done with vertvisc (step_MOM_dyn_split_RK2)")
791 do k=1,nz ;
do j=js-2,je+2 ;
do i=is-2,ie+2
792 h_av(i,j,k) = h(i,j,k)
793 enddo ;
enddo ;
enddo
795 call do_group_pass(cs%pass_visc_rem, g%Domain, clock=
id_clock_pass)
796 if (g%nonblocking_updates)
then
799 call do_group_pass(cs%pass_uv, g%Domain, clock=
id_clock_pass)
806 call continuity(u, v, h, h, uh, vh, dt, g, gv, us, cs%continuity_CSp, &
807 cs%uhbt, cs%vhbt, cs%OBC, cs%visc_rem_u, cs%visc_rem_v, u_av, v_av)
813 if (showcalltree)
call calltree_waypoint(
"done with continuity (step_MOM_dyn_split_RK2)")
815 if (g%nonblocking_updates)
then
818 call do_group_pass(cs%pass_av_uvh, g%domain, clock=
id_clock_pass)
821 if (
associated(cs%OBC))
then
822 call radiation_open_bdry_conds(cs%OBC, u, u_old_rad_obc, v, v_old_rad_obc, g, us, dt)
827 do k=1,nz ;
do j=js-2,je+2 ;
do i=is-2,ie+2
828 h_av(i,j,k) = 0.5*(h_av(i,j,k) + h(i,j,k))
829 enddo ;
enddo ;
enddo
831 if (g%nonblocking_updates) &
836 do j=js-2,je+2 ;
do i=isq-2,ieq+2
837 uhtr(i,j,k) = uhtr(i,j,k) + uh(i,j,k)*dt
839 do j=jsq-2,jeq+2 ;
do i=is-2,ie+2
840 vhtr(i,j,k) = vhtr(i,j,k) + vh(i,j,k)*dt
849 if (cs%id_PFu > 0)
call post_data(cs%id_PFu, cs%PFu, cs%diag)
850 if (cs%id_PFv > 0)
call post_data(cs%id_PFv, cs%PFv, cs%diag)
851 if (cs%id_CAu > 0)
call post_data(cs%id_CAu, cs%CAu, cs%diag)
852 if (cs%id_CAv > 0)
call post_data(cs%id_CAv, cs%CAv, cs%diag)
855 if (cs%id_uh > 0)
call post_data(cs%id_uh , uh, cs%diag)
856 if (cs%id_vh > 0)
call post_data(cs%id_vh , vh, cs%diag)
857 if (cs%id_uav > 0)
call post_data(cs%id_uav, u_av, cs%diag)
858 if (cs%id_vav > 0)
call post_data(cs%id_vav, v_av, cs%diag)
859 if (cs%id_u_BT_accel > 0)
call post_data(cs%id_u_BT_accel, cs%u_accel_bt, cs%diag)
860 if (cs%id_v_BT_accel > 0)
call post_data(cs%id_v_BT_accel, cs%v_accel_bt, cs%diag)
863 call mom_state_chksum(
"Corrector ", u, v, h, uh, vh, g, gv, us, symmetric=sym)
864 call uvchksum(
"Corrector avg [uv]", u_av, v_av, g%HI, haloshift=1, symmetric=sym, scale=us%L_T_to_m_s)
865 call hchksum(h_av,
"Corrector avg h", g%HI, haloshift=1, scale=gv%H_to_m)
882 real,
dimension(SZIB_(HI),SZJ_(HI),SZK_(GV)), &
883 target,
intent(inout) :: uh
884 real,
dimension(SZI_(HI),SZJB_(HI),SZK_(GV)), &
885 target,
intent(inout) :: vh
888 character(len=40) :: mdl =
"MOM_dynamics_split_RK2"
889 character(len=48) :: thickness_units, flux_units
891 integer :: isd, ied, jsd, jed, nz, isdb, iedb, jsdb, jedb
892 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
893 isdb = hi%IsdB ; iedb = hi%IedB ; jsdb = hi%JsdB ; jedb = hi%JedB
896 if (
associated(cs))
then
897 call mom_error(warning,
"register_restarts_dyn_split_RK2 called with an associated "// &
898 "control structure.")
903 alloc_(cs%diffu(isdb:iedb,jsd:jed,nz)) ; cs%diffu(:,:,:) = 0.0
904 alloc_(cs%diffv(isd:ied,jsdb:jedb,nz)) ; cs%diffv(:,:,:) = 0.0
905 alloc_(cs%CAu(isdb:iedb,jsd:jed,nz)) ; cs%CAu(:,:,:) = 0.0
906 alloc_(cs%CAv(isd:ied,jsdb:jedb,nz)) ; cs%CAv(:,:,:) = 0.0
907 alloc_(cs%PFu(isdb:iedb,jsd:jed,nz)) ; cs%PFu(:,:,:) = 0.0
908 alloc_(cs%PFv(isd:ied,jsdb:jedb,nz)) ; cs%PFv(:,:,:) = 0.0
910 alloc_(cs%eta(isd:ied,jsd:jed)) ; cs%eta(:,:) = 0.0
911 alloc_(cs%u_av(isdb:iedb,jsd:jed,nz)) ; cs%u_av(:,:,:) = 0.0
912 alloc_(cs%v_av(isd:ied,jsdb:jedb,nz)) ; cs%v_av(:,:,:) = 0.0
913 alloc_(cs%h_av(isd:ied,jsd:jed,nz)) ; cs%h_av(:,:,:) = gv%Angstrom_H
915 thickness_units = get_thickness_units(gv)
918 if (gv%Boussinesq)
then
919 vd =
var_desc(
"sfc",thickness_units,
"Free surface Height",
'h',
'1')
921 vd =
var_desc(
"p_bot",thickness_units,
"Bottom Pressure",
'h',
'1')
925 vd =
var_desc(
"u2",
"m s-1",
"Auxiliary Zonal velocity",
'u',
'L')
928 vd =
var_desc(
"v2",
"m s-1",
"Auxiliary Meridional velocity",
'v',
'L')
931 vd =
var_desc(
"h2",thickness_units,
"Auxiliary Layer Thickness",
'h',
'L')
934 vd =
var_desc(
"uh",flux_units,
"Zonal thickness flux",
'u',
'L')
937 vd =
var_desc(
"vh",flux_units,
"Meridional thickness flux",
'v',
'L')
940 vd =
var_desc(
"diffu",
"m s-2",
"Zonal horizontal viscous acceleration",
'u',
'L')
943 vd =
var_desc(
"diffv",
"m s-2",
"Meridional horizontal viscous acceleration",
'v',
'L')
953 subroutine initialize_dyn_split_rk2(u, v, h, uh, vh, eta, Time, G, GV, US, param_file, &
954 diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, &
955 VarMix, MEKE, thickness_diffuse_CSp, &
956 OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, &
957 visc, dirs, ntrunc, calc_dtbt)
961 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
963 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
965 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) ,
intent(inout) :: h
966 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
967 target,
intent(inout) :: uh
968 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
969 target,
intent(inout) :: vh
970 real,
dimension(SZI_(G),SZJ_(G)),
intent(inout) :: eta
971 type(time_type),
target,
intent(in) :: time
973 type(
diag_ctrl),
target,
intent(inout) :: diag
976 real,
intent(in) :: dt
990 type(
ale_cs),
pointer :: ale_csp
994 integer,
target,
intent(inout) :: ntrunc
997 logical,
intent(out) :: calc_dtbt
1000 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_tmp
1001 character(len=40) :: mdl =
"MOM_dynamics_split_RK2"
1002 character(len=48) :: thickness_units, flux_units, eta_rest_name
1009 real :: accel_rescale
1012 type(group_pass_type) :: pass_av_h_uvh
1013 logical :: use_tides, debug_truncations
1015 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
1016 integer :: isdb, iedb, jsdb, jedb
1017 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1018 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1019 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
1021 if (.not.
associated(cs))
call mom_error(fatal, &
1022 "initialize_dyn_split_RK2 called with an unassociated control structure.")
1023 if (cs%module_is_initialized)
then
1024 call mom_error(warning,
"initialize_dyn_split_RK2 called with a control "// &
1025 "structure that has already been initialized.")
1028 cs%module_is_initialized = .true.
1032 call get_param(param_file, mdl,
"TIDES", use_tides, &
1033 "If true, apply tidal momentum forcing.", default=.false.)
1034 call get_param(param_file, mdl,
"BE", cs%be, &
1035 "If SPLIT is true, BE determines the relative weighting "//&
1036 "of a 2nd-order Runga-Kutta baroclinic time stepping "//&
1037 "scheme (0.5) and a backward Euler scheme (1) that is "//&
1038 "used for the Coriolis and inertial terms. BE may be "//&
1039 "from 0.5 to 1, but instability may occur near 0.5. "//&
1040 "BE is also applicable if SPLIT is false and USE_RK2 "//&
1041 "is true.", units=
"nondim", default=0.6)
1042 call get_param(param_file, mdl,
"BEGW", cs%begw, &
1043 "If SPLIT is true, BEGW is a number from 0 to 1 that "//&
1044 "controls the extent to which the treatment of gravity "//&
1045 "waves is forward-backward (0) or simulated backward "//&
1046 "Euler (1). 0 is almost always used. "//&
1047 "If SPLIT is false and USE_RK2 is true, BEGW can be "//&
1048 "between 0 and 0.5 to damp gravity waves.", &
1049 units=
"nondim", default=0.0)
1051 call get_param(param_file, mdl,
"SPLIT_BOTTOM_STRESS", cs%split_bottom_stress, &
1052 "If true, provide the bottom stress calculated by the "//&
1053 "vertical viscosity to the barotropic solver.", default=.false.)
1054 call get_param(param_file, mdl,
"BT_USE_LAYER_FLUXES", cs%BT_use_layer_fluxes, &
1055 "If true, use the summed layered fluxes plus an "//&
1056 "adjustment due to the change in the barotropic velocity "//&
1057 "in the barotropic continuity equation.", default=.true.)
1058 call get_param(param_file, mdl,
"DEBUG", cs%debug, &
1059 "If true, write out verbose debugging data.", &
1060 default=.false., debuggingparam=.true.)
1061 call get_param(param_file, mdl,
"DEBUG_OBC", cs%debug_OBC, default=.false.)
1062 call get_param(param_file, mdl,
"DEBUG_TRUNCATIONS", debug_truncations, &
1065 allocate(cs%taux_bot(isdb:iedb,jsd:jed)) ; cs%taux_bot(:,:) = 0.0
1066 allocate(cs%tauy_bot(isd:ied,jsdb:jedb)) ; cs%tauy_bot(:,:) = 0.0
1068 alloc_(cs%uhbt(isdb:iedb,jsd:jed)) ; cs%uhbt(:,:) = 0.0
1069 alloc_(cs%vhbt(isd:ied,jsdb:jedb)) ; cs%vhbt(:,:) = 0.0
1070 alloc_(cs%visc_rem_u(isdb:iedb,jsd:jed,nz)) ; cs%visc_rem_u(:,:,:) = 0.0
1071 alloc_(cs%visc_rem_v(isd:ied,jsdb:jedb,nz)) ; cs%visc_rem_v(:,:,:) = 0.0
1072 alloc_(cs%eta_PF(isd:ied,jsd:jed)) ; cs%eta_PF(:,:) = 0.0
1073 alloc_(cs%pbce(isd:ied,jsd:jed,nz)) ; cs%pbce(:,:,:) = 0.0
1075 alloc_(cs%u_accel_bt(isdb:iedb,jsd:jed,nz)) ; cs%u_accel_bt(:,:,:) = 0.0
1076 alloc_(cs%v_accel_bt(isd:ied,jsdb:jedb,nz)) ; cs%v_accel_bt(:,:,:) = 0.0
1078 mis%diffu => cs%diffu
1079 mis%diffv => cs%diffv
1085 mis%u_accel_bt => cs%u_accel_bt
1086 mis%v_accel_bt => cs%v_accel_bt
1090 cs%ADp => accel_diag
1092 accel_diag%diffu => cs%diffu
1093 accel_diag%diffv => cs%diffv
1094 accel_diag%PFu => cs%PFu
1095 accel_diag%PFv => cs%PFv
1096 accel_diag%CAu => cs%CAu
1097 accel_diag%CAv => cs%CAv
1104 grain=clock_routine)
1106 call continuity_init(time, g, gv, us, param_file, diag, cs%continuity_CSp)
1107 call coriolisadv_init(time, g, gv, us, param_file, diag, cs%ADp, cs%CoriolisAdv_CSp)
1111 call hor_visc_init(time, g, us, param_file, diag, cs%hor_visc_CSp, meke)
1112 call vertvisc_init(mis, time, g, gv, us, param_file, diag, cs%ADp, dirs, &
1113 ntrunc, cs%vertvisc_CSp)
1114 if (.not.
associated(setvisc_csp))
call mom_error(fatal, &
1115 "initialize_dyn_split_RK2 called with setVisc_CSp unassociated.")
1116 cs%set_visc_CSp => setvisc_csp
1120 if (
associated(ale_csp)) cs%ALE_CSp => ale_csp
1121 if (
associated(obc)) cs%OBC => obc
1122 if (
associated(update_obc_csp)) cs%update_OBC_CSp => update_obc_csp
1124 eta_rest_name =
"sfc" ;
if (.not.gv%Boussinesq) eta_rest_name =
"p_bot"
1131 if (gv%Boussinesq)
then
1132 do j=js,je ;
do i=is,ie ; cs%eta(i,j) = -gv%Z_to_H * g%bathyT(i,j) ;
enddo ;
enddo
1134 do k=1,nz ;
do j=js,je ;
do i=is,ie
1135 cs%eta(i,j) = cs%eta(i,j) + h(i,j,k)
1136 enddo ;
enddo ;
enddo
1137 elseif ((gv%m_to_H_restart /= 0.0) .and. (gv%m_to_H_restart /= gv%m_to_H))
then
1138 h_rescale = gv%m_to_H / gv%m_to_H_restart
1139 do j=js,je ;
do i=is,ie ; cs%eta(i,j) = h_rescale * cs%eta(i,j) ;
enddo ;
enddo
1142 do j=js,je ;
do i=is,ie ; eta(i,j) = cs%eta(i,j) ;
enddo ;
enddo
1144 call barotropic_init(u, v, h, cs%eta, time, g, gv, us, param_file, diag, &
1145 cs%barotropic_CSp, restart_cs, calc_dtbt, cs%BT_cont, &
1151 g, gv, us, cs%hor_visc_CSp, &
1152 obc=cs%OBC, bt=cs%barotropic_CSp)
1154 if ( (us%s_to_T_restart * us%m_to_L_restart /= 0.0) .and. &
1155 (us%m_to_L * us%s_to_T_restart**2 /= us%m_to_L_restart * us%s_to_T**2) )
then
1156 accel_rescale = (us%m_to_L * us%s_to_T_restart**2) / (us%m_to_L_restart * us%s_to_T**2)
1157 do k=1,nz ;
do j=js,je ;
do i=g%IscB,g%IecB
1158 cs%diffu(i,j,k) = accel_rescale * cs%diffu(i,j,k)
1159 enddo ;
enddo ;
enddo
1160 do k=1,nz ;
do j=g%JscB,g%JecB ;
do i=is,ie
1161 cs%diffv(i,j,k) = accel_rescale * cs%diffv(i,j,k)
1162 enddo ;
enddo ;
enddo
1168 do k=1,nz ;
do j=jsd,jed ;
do i=isdb,iedb ; cs%u_av(i,j,k) = u(i,j,k) ;
enddo ;
enddo ;
enddo
1169 do k=1,nz ;
do j=jsdb,jedb ;
do i=isd,ied ; cs%v_av(i,j,k) = v(i,j,k) ;
enddo ;
enddo ;
enddo
1170 elseif ( (us%s_to_T_restart * us%m_to_L_restart /= 0.0) .and. &
1171 ((us%m_to_L * us%s_to_T_restart) /= (us%m_to_L_restart * us%s_to_T)) )
then
1172 vel_rescale = (us%m_to_L * us%s_to_T_restart) / (us%m_to_L_restart * us%s_to_T)
1173 do k=1,nz ;
do j=jsd,jed ;
do i=isdb,iedb ; cs%u_av(i,j,k) = vel_rescale * cs%u_av(i,j,k) ;
enddo ;
enddo ;
enddo
1174 do k=1,nz ;
do j=jsdb,jedb ;
do i=isd,ied ; cs%v_av(i,j,k) = vel_rescale * cs%v_av(i,j,k) ;
enddo ;
enddo ;
enddo
1180 do k=1,nz ;
do j=jsd,jed ;
do i=isd,ied ; h_tmp(i,j,k) = h(i,j,k) ;
enddo ;
enddo ;
enddo
1181 call continuity(u, v, h, h_tmp, uh, vh, dt, g, gv, us, cs%continuity_CSp, obc=cs%OBC)
1183 do k=1,nz ;
do j=jsd,jed ;
do i=isd,ied
1184 cs%h_av(i,j,k) = 0.5*(h(i,j,k) + h_tmp(i,j,k))
1185 enddo ;
enddo ;
enddo
1188 cs%h_av(:,:,:) = h(:,:,:)
1189 elseif ((gv%m_to_H_restart /= 0.0) .and. (gv%m_to_H_restart /= gv%m_to_H))
then
1190 h_rescale = gv%m_to_H / gv%m_to_H_restart
1191 do k=1,nz ;
do j=js,je ;
do i=is,ie ; cs%h_av(i,j,k) = h_rescale * cs%h_av(i,j,k) ;
enddo ;
enddo ;
enddo
1193 if ( (gv%m_to_H_restart * us%s_to_T_restart * us%m_to_L_restart /= 0.0) .and. &
1194 ((gv%m_to_H * us%m_to_L**2 * us%s_to_T_restart) /= &
1195 (gv%m_to_H_restart * us%m_to_L_restart**2 * us%s_to_T)) )
then
1196 uh_rescale = (gv%m_to_H * us%m_to_L**2 * us%s_to_T_restart) / &
1197 (gv%m_to_H_restart * us%m_to_L_restart**2 * us%s_to_T)
1198 do k=1,nz ;
do j=js,je ;
do i=g%IscB,g%IecB ; uh(i,j,k) = uh_rescale * uh(i,j,k) ;
enddo ;
enddo ;
enddo
1199 do k=1,nz ;
do j=g%JscB,g%JecB ;
do i=is,ie ; vh(i,j,k) = uh_rescale * vh(i,j,k) ;
enddo ;
enddo ;
enddo
1207 call do_group_pass(pass_av_h_uvh, g%Domain)
1211 h_convert = gv%H_to_m ;
if (.not.gv%Boussinesq) h_convert = gv%H_to_kg_m2
1212 cs%id_uh = register_diag_field(
'ocean_model',
'uh', diag%axesCuL, time, &
1213 'Zonal Thickness Flux', flux_units, y_cell_method=
'sum', v_extensive=.true., &
1214 conversion=h_convert*us%L_to_m**2*us%s_to_T)
1215 cs%id_vh = register_diag_field(
'ocean_model',
'vh', diag%axesCvL, time, &
1216 'Meridional Thickness Flux', flux_units, x_cell_method=
'sum', v_extensive=.true., &
1217 conversion=h_convert*us%L_to_m**2*us%s_to_T)
1219 cs%id_CAu = register_diag_field(
'ocean_model',
'CAu', diag%axesCuL, time, &
1220 'Zonal Coriolis and Advective Acceleration',
'm s-2', conversion=us%L_T2_to_m_s2)
1221 cs%id_CAv = register_diag_field(
'ocean_model',
'CAv', diag%axesCvL, time, &
1222 'Meridional Coriolis and Advective Acceleration',
'm s-2', conversion=us%L_T2_to_m_s2)
1223 cs%id_PFu = register_diag_field(
'ocean_model',
'PFu', diag%axesCuL, time, &
1224 'Zonal Pressure Force Acceleration',
'm s-2', conversion=us%L_T2_to_m_s2)
1225 cs%id_PFv = register_diag_field(
'ocean_model',
'PFv', diag%axesCvL, time, &
1226 'Meridional Pressure Force Acceleration',
'm s-2', conversion=us%L_T2_to_m_s2)
1228 cs%id_uav = register_diag_field(
'ocean_model',
'uav', diag%axesCuL, time, &
1229 'Barotropic-step Averaged Zonal Velocity',
'm s-1', conversion=us%L_T_to_m_s)
1230 cs%id_vav = register_diag_field(
'ocean_model',
'vav', diag%axesCvL, time, &
1231 'Barotropic-step Averaged Meridional Velocity',
'm s-1', conversion=us%L_T_to_m_s)
1233 cs%id_u_BT_accel = register_diag_field(
'ocean_model',
'u_BT_accel', diag%axesCuL, time, &
1234 'Barotropic Anomaly Zonal Acceleration',
'm s-2', conversion=us%L_T2_to_m_s2)
1235 cs%id_v_BT_accel = register_diag_field(
'ocean_model',
'v_BT_accel', diag%axesCvL, time, &
1236 'Barotropic Anomaly Meridional Acceleration',
'm s-2', conversion=us%L_T2_to_m_s2)
1238 id_clock_cor = cpu_clock_id(
'(Ocean Coriolis & mom advection)', grain=clock_module)
1240 id_clock_pres = cpu_clock_id(
'(Ocean pressure force)', grain=clock_module)
1241 id_clock_vertvisc = cpu_clock_id(
'(Ocean vertical viscosity)', grain=clock_module)
1242 id_clock_horvisc = cpu_clock_id(
'(Ocean horizontal viscosity)', grain=clock_module)
1244 id_clock_pass = cpu_clock_id(
'(Ocean message passing)', grain=clock_module)
1245 id_clock_btcalc = cpu_clock_id(
'(Ocean barotropic mode calc)', grain=clock_module)
1246 id_clock_btstep = cpu_clock_id(
'(Ocean barotropic mode stepping)', grain=clock_module)
1247 id_clock_btforce = cpu_clock_id(
'(Ocean barotropic forcing calc)', grain=clock_module)
1256 dealloc_(cs%diffu) ; dealloc_(cs%diffv)
1257 dealloc_(cs%CAu) ; dealloc_(cs%CAv)
1258 dealloc_(cs%PFu) ; dealloc_(cs%PFv)
1260 if (
associated(cs%taux_bot))
deallocate(cs%taux_bot)
1261 if (
associated(cs%tauy_bot))
deallocate(cs%tauy_bot)
1262 dealloc_(cs%uhbt) ; dealloc_(cs%vhbt)
1263 dealloc_(cs%u_accel_bt) ; dealloc_(cs%v_accel_bt)
1264 dealloc_(cs%visc_rem_u) ; dealloc_(cs%visc_rem_v)
1266 dealloc_(cs%eta) ; dealloc_(cs%eta_PF) ; dealloc_(cs%pbce)
1267 dealloc_(cs%h_av) ; dealloc_(cs%u_av) ; dealloc_(cs%v_av)
1269 call dealloc_bt_cont_type(cs%BT_cont)