75 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
77 use mom_cpu_clock, only : clock_module_driver, clock_module, clock_routine
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(/)
124 implicit none ;
private 126 #include <MOM_memory.h> 129 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: &
142 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: &
157 real allocable_,
dimension(NIMEM_,NJMEM_) :: &
159 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: u_av
160 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: v_av
163 real allocable_,
dimension(NIMEM_,NJMEM_,NKMEM_) :: h_av
165 real allocable_,
dimension(NIMEM_,NJMEM_) :: &
167 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_) :: uhbt
168 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_) :: vhbt
172 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_) :: uhbt_in
173 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_) :: vhbt_in
177 real allocable_,
dimension(NIMEM_,NJMEM_,NKMEM_) :: pbce
181 real,
pointer,
dimension(:,:) :: taux_bot => null(), tauy_bot => null()
190 logical :: flux_bt_coupling
192 logical :: bt_use_layer_fluxes
195 logical :: split_bottom_stress
198 logical :: readjust_bt_trans
201 logical :: readjust_velocity
217 logical :: module_is_initialized = .false.
219 integer :: id_uh = -1, id_vh = -1
220 integer :: id_pfu = -1, id_pfv = -1, id_cau = -1, id_cav = -1
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
253 type(
ale_cs),
pointer :: ale_csp => null()
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)
277 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
278 target,
intent(inout) :: u
279 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
280 target,
intent(inout) :: v
281 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
287 type(time_type),
intent(in) :: Time_local
289 real,
intent(in) :: dt
290 type(
forcing),
intent(in) :: fluxes
293 real,
dimension(:,:),
pointer :: p_surf_begin
296 real,
dimension(:,:),
pointer :: p_surf_end
299 real,
intent(in) :: dt_since_flux
301 real,
intent(in) :: dt_therm
302 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
303 target,
intent(inout) :: uh
305 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
306 target,
intent(inout) :: vh
308 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
309 intent(inout) :: uhtr
312 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
313 intent(inout) :: vhtr
316 real,
dimension(SZI_(G),SZJ_(G)), &
317 intent(out) :: eta_av
323 logical,
intent(in) :: calc_dtbt
366 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: &
368 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: &
370 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
373 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_bc_accel
374 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_bc_accel
377 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
target :: uh_in
378 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
target :: vh_in
381 real,
dimension(SZIB_(G),SZJ_(G)) :: uhbt_out
382 real,
dimension(SZI_(G),SZJB_(G)) :: vhbt_out
385 real,
dimension(SZI_(G),SZJ_(G)) :: eta_pred
388 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
target :: u_adj
389 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
target :: v_adj
393 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_tmp
394 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_tmp
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
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(), &
415 logical :: dyn_p_surf
416 logical :: BT_cont_BT_thick
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
428 up(:,:,:) = 0.0 ; vp(:,:,:) = 0.0 ; hp(:,:,:) = h(:,:,:)
436 dyn_p_surf =
associated(p_surf_begin) .and.
associated(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
442 p_surf => fluxes%p_surf
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 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
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))
461 if (cs%split_bottom_stress)
then 462 taux_bot => cs%taux_bot ; tauy_bot => cs%tauy_bot
467 if (cs%begw == 0.0)
call enable_averaging(dt, time_local, cs%diag)
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)
472 if (gv%Boussinesq)
then 473 pa_to_eta = 1.0 / (gv%Rho0*gv%g_Earth)
475 pa_to_eta = 1.0 / gv%H_to_Pa
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))
483 call disable_averaging(cs%diag)
485 if (g%nonblocking_updates)
then 489 if (cs%readjust_velocity) &
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)
500 call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, g, gv, &
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 521 call check_redundant(
"pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
524 if (g%nonblocking_updates)
then 528 if (cs%readjust_velocity) &
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)
543 call disable_averaging(cs%diag)
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)
550 if (g%nonblocking_updates)
then 552 to_all+scalar_pair, cgrid_ne)
554 call pass_var(cs%eta_PF, g%Domain, complete=.false.)
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)
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)
570 if (g%nonblocking_updates)
then 573 to_all+scalar_pair, cgrid_ne)
578 if (cs%flux_BT_coupling)
then 580 if (cs%readjust_velocity)
then 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, &
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.
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)
600 u_init => u ; v_init => v
604 if (bt_cont_bt_thick)
then 606 call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
607 to_all+scalar_pair, cgrid_ne)
609 call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
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)
623 if (
associated(cs%BT_cont) .or. cs%BT_use_layer_fluxes)
then 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, &
630 if (bt_cont_bt_thick)
then 632 call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
633 to_all+scalar_pair, cgrid_ne)
635 call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
639 if (cs%BT_use_layer_fluxes)
then 640 uh_ptr => uh_in; vh_ptr => vh_in; u_ptr => u; v_ptr => v
643 u_init => u ; v_init => v
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)
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 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 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)
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)
686 call vertvisc_coef(up, vp, h, fluxes, visc, dt_pred, g, gv, cs%vertvisc_CSp, &
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 695 call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt_pred, g, gv, cs%vertvisc_CSp)
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 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)
718 if (g%nonblocking_updates)
then 722 call pass_vector(u_av, v_av, g%Domain, complete=.false.)
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)
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 737 call enable_averaging(dt, time_local, cs%diag)
744 call legacy_bt_mass_source(hp, eta_pred, fluxes, .false., dt_therm, &
745 dt_since_flux+dt, g, gv, cs%barotropic_CSp)
748 if (cs%begw /= 0.0)
then 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 760 cs%PressureForce_CSp, cs%ALE_CSp, &
761 p_surf, cs%pbce, cs%eta_PF)
768 if (g%nonblocking_updates)
then 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)
779 if (bt_cont_bt_thick)
then 781 call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
782 to_all+scalar_pair, cgrid_ne)
784 call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
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)
792 call check_redundant(
"Predictor up ", up, vp, g)
793 call check_redundant(
"Predictor uh ", uh, vh, g)
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)
804 call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, g, gv, &
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)
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)
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)
842 if (cs%BT_use_layer_fluxes)
then 843 uh_ptr => uh ; vh_ptr => vh ; u_ptr => u_av ; v_ptr => v_av
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)
858 call check_redundant(
"u_accel_bt ", cs%u_accel_bt, cs%v_accel_bt, g)
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 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 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)
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)
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 892 pid_u = pass_vector_start(u, v, g%Domain)
895 call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, cs%vertvisc_CSp)
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 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)
909 call pass_vector(u, v, g%Domain)
915 if (cs%flux_BT_coupling)
then 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 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)
933 call diag_update_remap_grids(cs%diag)
934 if (g%nonblocking_updates)
then 936 pid_h = pass_var_start(h, g%Domain)
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 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 950 pid_u = pass_vector_start(u, v, g%Domain)
953 call vertvisc_limit_vel(u_av, v_av, h_av, cs%ADp, cs%CDp, fluxes, visc, dt, g, gv, cs%vertvisc_CSp)
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)
961 call pass_var(h, g%Domain)
962 call pass_vector(u, v, g%Domain, complete=.false.)
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)
974 call diag_update_remap_grids(cs%diag)
976 call pass_var(h, g%Domain)
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)
985 call pass_vector(u_av, v_av, g%Domain, complete=.false.)
986 call pass_vector(uh(:,:,:), vh(:,:,:), g%Domain)
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)
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 999 if (g%nonblocking_updates)
then 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)
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 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)
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)
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)
1044 type(ocean_grid_type),
intent(inout) :: G
1045 type(verticalgrid_type),
intent(in) :: GV
1046 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1048 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1050 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
1053 real,
intent(in) :: dt
1067 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: uh_temp
1068 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vh_temp
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
1074 if (cs%readjust_BT_trans)
then 1076 call continuity(u, v, h, h_temp, uh_temp, vh_temp, dt, g, gv, &
1077 cs%continuity_CSp, obc=cs%OBC)
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)
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)
1095 cs%readjust_velocity = .true.
1103 type(hor_index_type),
intent(in) :: HI
1104 type(verticalgrid_type),
intent(in) :: GV
1105 type(param_file_type),
intent(in) :: param_file
1109 type(mom_restart_cs),
pointer :: restart_CS
1111 real,
dimension(SZIB_(HI),SZJ_(HI),SZK_(GV)), &
1112 target,
intent(inout) :: uh
1114 real,
dimension(SZI_(HI),SZJB_(HI),SZK_(GV)), &
1115 target,
intent(inout) :: vh
1131 character(len=40) :: mdl =
"MOM_dynamics_legacy_split" 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
1139 if (
associated(cs))
then 1140 call mom_error(warning,
"register_restarts_dyn_legacy_split called with an associated "// &
1141 "control structure.")
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.
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
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
1168 thickness_units = get_thickness_units(gv)
1169 flux_units = get_flux_units(gv)
1171 vd = var_desc(
"sfc",thickness_units,
"Free surface Height",
'h',
'1')
1172 call register_restart_field(cs%eta, vd, .false., restart_cs)
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)
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)
1180 vd = var_desc(
"h2",thickness_units,
"Auxiliary Layer Thickness",
'h',
'L')
1181 call register_restart_field(cs%h_av, vd, .false., restart_cs)
1183 vd = var_desc(
"uh",flux_units,
"Zonal thickness flux",
'u',
'L')
1184 call register_restart_field(uh, vd, .false., restart_cs)
1186 vd = var_desc(
"vh",flux_units,
"Meridional thickness flux",
'v',
'L')
1187 call register_restart_field(vh, vd, .false., restart_cs)
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)
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)
1195 call register_legacy_barotropic_restarts(hi, gv, param_file, &
1196 cs%barotropic_CSp, restart_cs)
1198 if (readjust_bt_trans)
then 1199 vd = var_desc(
"uhbt_in",flux_units,
"Final instantaneous barotropic zonal thickness flux",&
1201 call register_restart_field(cs%uhbt_in, vd, .false., restart_cs)
1203 vd = var_desc(
"vhbt_in",flux_units,
"Final instantaneous barotropic meridional thickness flux",&
1205 call register_restart_field(cs%vhbt_in, vd, .false., restart_cs)
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, &
1214 type(ocean_grid_type),
intent(inout) :: G
1215 type(verticalgrid_type),
intent(in) :: GV
1216 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1218 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1220 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) , &
1223 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1224 target,
intent(inout) :: uh
1226 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1227 target,
intent(inout) :: vh
1229 real,
dimension(SZI_(G),SZJ_(G)), &
1230 intent(inout) :: eta
1232 type(time_type),
target,
intent(in) :: Time
1233 type(param_file_type),
intent(in) :: param_file
1235 type(diag_ctrl),
target,
intent(inout) :: diag
1239 type(mom_restart_cs),
pointer :: restart_CS
1241 real,
intent(in) :: dt
1243 type(accel_diag_ptrs),
target,
intent(inout) :: Accel_diag
1246 type(cont_diag_ptrs),
target,
intent(inout) :: Cont_diag
1248 type(ocean_internal_state),
intent(inout) :: MIS
1251 type(varmix_cs),
pointer :: VarMix
1253 type(meke_type),
pointer :: MEKE
1255 type(ocean_obc_type),
pointer :: OBC
1258 type(update_obc_cs),
pointer :: update_OBC_CSp
1261 type(ale_cs),
pointer :: ALE_CSp
1263 type(set_visc_cs),
pointer :: setVisc_CSp
1265 type(vertvisc_type),
intent(inout) :: visc
1267 type(directories),
intent(in) :: dirs
1269 integer,
target,
intent(inout) :: ntrunc
1314 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_tmp
1315 character(len=40) :: mdl =
"MOM_dynamics_legacy_split" 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
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.")
1331 cs%module_is_initialized = .true.
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)
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, &
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
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
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
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
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
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
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, &
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
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
1423 if (.not. query_initialized(cs%eta,
"sfc",restart_cs))
then 1429 if (gv%Boussinesq)
then 1430 do j=js,je ;
do i=is,ie ; cs%eta(i,j) = -g%bathyT(i,j) ;
enddo ;
enddo 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 1437 do j=js,je ;
do i=is,ie ; eta(i,j) = cs%eta(i,j) ;
enddo ;
enddo 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)
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(:,:,:)
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)
1457 call pass_var(h_tmp, g%Domain)
1459 cs%h_av(:,:,:) = 0.5*(h(:,:,:) + h_tmp(:,:,:))
1461 if (.not. query_initialized(cs%h_av,
"h2",restart_cs)) &
1462 cs%h_av(:,:,:) = h(:,:,:)
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.
1473 call pass_vector(cs%uhbt_in, cs%vhbt_in, g%Domain)
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)
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')
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')
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)
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')
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)
1524 id_clock_cor = cpu_clock_id(
'(Ocean Coriolis & mom advection)', 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)
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)
1543 dealloc_(cs%diffu) ; dealloc_(cs%diffv)
1544 dealloc_(cs%CAu) ; dealloc_(cs%CAv)
1545 dealloc_(cs%PFu) ; dealloc_(cs%PFv)
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)
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)
1557 call dealloc_bt_cont_type(cs%BT_cont)
subroutine, public mom_io_init(param_file)
Initialize the MOM_io module.
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...
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 ...
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...
integer id_clock_pass_init
character(len=48) function, public get_flux_units(GV)
Returns the model'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 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.
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.
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.
integer id_clock_vertvisc
This routine drives the diabatic/dianeutral physics for MOM.
integer id_clock_continuity
Accelerations due to the Coriolis force and momentum advection.
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.
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's tracer flux units.
Container for horizontal index ranges for data, computational and global domains. ...
Control structure for mom_coriolisadv.
Variable mixing coefficients.
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'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.
Control structure for this module.
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...
integer id_clock_thick_diff
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 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.
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)
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...
integer id_clock_mom_update
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.