95 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
117 implicit none ;
private 119 #include <MOM_memory.h> 120 #ifdef STATIC_MEMORY_ 124 # define WHALOI_ MAX(BTHALO_-NIHALO_,0) 125 # define WHALOJ_ MAX(BTHALO_-NJHALO_,0) 126 # define NIMEMW_ 1-WHALOI_:NIMEM_+WHALOI_ 127 # define NJMEMW_ 1-WHALOJ_:NJMEM_+WHALOJ_ 128 # define NIMEMBW_ -WHALOI_:NIMEM_+WHALOI_ 129 # define NJMEMBW_ -WHALOJ_:NJMEM_+WHALOJ_ 130 # define SZIW_(G) NIMEMW_ 131 # define SZJW_(G) NJMEMW_ 132 # define SZIBW_(G) NIMEMBW_ 133 # define SZJBW_(G) NJMEMBW_ 139 # define SZIW_(G) G%isdw:G%iedw 140 # define SZJW_(G) G%jsdw:G%jedw 141 # define SZIBW_(G) G%isdw-1:G%iedw 142 # define SZJBW_(G) G%jsdw-1:G%jedw 149 real,
dimension(:,:),
pointer :: &
157 ubt_outer => null(), &
158 vbt_outer => null(), &
160 eta_outer_u => null(), &
161 eta_outer_v => null()
163 logical :: apply_u_obcs
164 logical :: apply_v_obcs
165 integer :: is_u_obc, ie_u_obc, js_u_obc, je_u_obc
166 integer :: is_v_obc, ie_v_obc, js_v_obc, je_v_obc
167 logical :: is_alloced = .false.
171 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: frhatu
172 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: frhatv
175 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_) :: &
185 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_) :: &
195 real allocable_,
dimension(NIMEM_,NJMEM_) :: &
206 real allocable_,
dimension(NIMEMW_,NJMEMW_) :: &
210 real allocable_,
dimension(NIMEMW_,NJMEMW_) :: &
213 real allocable_,
dimension(NIMEMBW_,NJMEMW_) :: &
217 real allocable_,
dimension(NIMEMW_,NJMEMBW_) :: &
221 real allocable_,
dimension(NIMEMBW_,NJMEMBW_) :: &
224 real,
pointer,
dimension(:,:,:) :: frhatu1 => null(), frhatv1 => null()
232 real :: dtbt_fraction
239 integer :: nstep_last = 0
247 real :: eta_source_limit
251 logical :: bound_bt_corr
256 logical :: gradual_bt_ics
267 logical :: nonlinear_continuity
269 integer :: nonlin_cont_update_period
273 logical :: bt_project_velocity
281 logical :: dynamic_psurf
283 real :: dmin_dyn_psurf
286 real :: ice_strength_length
289 real :: const_dyn_psurf
294 integer :: hvel_scheme
298 logical :: strong_drag
300 logical :: linearized_bt_pv
303 logical :: use_wide_halos
305 logical :: clip_velocity
316 real :: maxcfl_bt_cont
321 logical :: bt_cont_bounds
324 logical :: visc_rem_u_uh0
328 logical :: adjust_bt_cont
331 type(time_type),
pointer :: time
337 logical :: module_is_initialized = .false.
339 integer :: isdw, iedw, jsdw, jedw
342 type(group_pass_type) :: pass_q_dcor, pass_gtot
343 type(group_pass_type) :: pass_tmp_uv, pass_eta_bt_rem
344 type(group_pass_type) :: pass_force_hbt0_cor_ref, pass_dat_uv
345 type(group_pass_type) :: pass_eta_ubt, pass_etaav, pass_ubt_cor
346 type(group_pass_type) :: pass_ubta_uhbta, pass_e_anom
348 integer :: id_pfu_bt = -1, id_pfv_bt = -1, id_coru_bt = -1, id_corv_bt = -1
349 integer :: id_ubtforce = -1, id_vbtforce = -1, id_uaccel = -1, id_vaccel = -1
350 integer :: id_visc_rem_u = -1, id_visc_rem_v = -1, id_eta_cor = -1
351 integer :: id_ubt = -1, id_vbt = -1, id_eta_bt = -1, id_ubtav = -1, id_vbtav = -1
352 integer :: id_ubt_st = -1, id_vbt_st = -1, id_eta_st = -1
353 integer :: id_ubt_hifreq = -1, id_vbt_hifreq = -1, id_eta_hifreq = -1
354 integer :: id_uhbt_hifreq = -1, id_vhbt_hifreq = -1, id_eta_pred_hifreq = -1
355 integer :: id_gtotn = -1, id_gtots = -1, id_gtote = -1, id_gtotw = -1
356 integer :: id_uhbt = -1, id_frhatu = -1, id_vhbt = -1, id_frhatv = -1
357 integer :: id_frhatu1 = -1, id_frhatv1 = -1
359 integer :: id_btc_fa_u_ee = -1, id_btc_fa_u_e0 = -1, id_btc_fa_u_w0 = -1, id_btc_fa_u_ww = -1
360 integer :: id_btc_ubt_ee = -1, id_btc_ubt_ww = -1
361 integer :: id_btc_fa_v_nn = -1, id_btc_fa_v_n0 = -1, id_btc_fa_v_s0 = -1, id_btc_fa_v_ss = -1
362 integer :: id_btc_vbt_nn = -1, id_btc_vbt_ss = -1
363 integer :: id_uhbt0 = -1, id_vhbt0 = -1
368 real :: fa_u_ee, fa_u_e0, fa_u_w0, fa_u_ww
369 real :: ubt_ee, ubt_ww
370 real :: uh_crve, uh_crvw
374 real :: fa_v_nn, fa_v_n0, fa_v_s0, fa_v_ss
375 real :: vbt_nn, vbt_ss
376 real :: vh_crvn, vh_crvs
381 integer :: isdw, iedw, jsdw, jedw
407 subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, &
408 fluxes, pbce, eta_PF_in, U_Cor, V_Cor, &
409 accel_layer_u, accel_layer_v, eta_out, uhbtav, vhbtav, G, GV, CS, &
410 visc_rem_u, visc_rem_v, etaav, OBC, &
411 BT_cont, eta_PF_start, &
412 taux_bot, tauy_bot, uh0, vh0, u_uh0, v_vh0)
415 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: U_in
416 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: V_in
417 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: eta_in
419 real,
intent(in) :: dt
420 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: bc_accel_u
421 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: bc_accel_v
423 type(
forcing),
intent(in) :: fluxes
425 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: pbce
427 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: eta_PF_in
433 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: U_Cor
435 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: V_Cor
436 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(out) :: accel_layer_u
438 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(out) :: accel_layer_v
440 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: eta_out
442 real,
dimension(SZIB_(G),SZJ_(G)),
intent(out) :: uhbtav
445 real,
dimension(SZI_(G),SZJB_(G)),
intent(out) :: vhbtav
450 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in) :: visc_rem_u
456 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in) :: visc_rem_v
457 real,
dimension(SZI_(G),SZJ_(G)),
intent(out),
optional :: etaav
463 real,
dimension(:,:),
pointer,
optional :: eta_PF_start
466 real,
dimension(:,:),
pointer,
optional :: taux_bot
468 real,
dimension(:,:),
pointer,
optional :: tauy_bot
470 real,
dimension(:,:,:),
pointer,
optional :: uh0, u_uh0
471 real,
dimension(:,:,:),
pointer,
optional :: vh0, v_vh0
474 real :: ubt_Cor(szib_(g),szj_(g))
475 real :: vbt_Cor(szi_(g),szjb_(g))
477 real :: wt_u(szib_(g),szj_(g),szk_(g))
478 real :: wt_v(szi_(g),szjb_(g),szk_(g))
481 real,
dimension(SZIB_(G),SZJ_(G)) :: &
484 real,
dimension(SZI_(G),SZJB_(G)) :: &
487 real,
dimension(SZI_(G),SZJ_(G)) :: &
494 real :: q(szibw_(cs),szjbw_(cs))
495 real,
dimension(SZIBW_(CS),SZJW_(CS)) :: &
527 real,
dimension(SZIW_(CS),SZJBW_(CS)) :: &
557 real,
target,
dimension(SZIW_(CS),SZJW_(CS)) :: &
561 real,
pointer,
dimension(:,:) :: &
564 real,
dimension(SZIW_(CS),SZJW_(CS)) :: &
590 real,
dimension(SZIBW_(CS),SZJW_(CS)) :: &
591 ubt_prev, uhbt_prev, ubt_sum_prev, uhbt_sum_prev, ubt_wtd_prev
592 real,
dimension(SZIW_(CS),SZJBW_(CS)) :: &
593 vbt_prev, vhbt_prev, vbt_sum_prev, vhbt_sum_prev, vbt_wtd_prev
620 logical :: do_hifreq_output
621 logical :: use_BT_cont, do_ave, find_etaav, find_PF, find_Cor
622 logical :: ice_is_rigid, nonblock_setup, interp_eta_PF
623 logical :: project_velocity, add_uh0
626 real :: ice_strength = 0.0
634 real :: u_max_cor, v_max_cor
638 real,
allocatable,
dimension(:) :: wt_vel, wt_eta, wt_accel, wt_trans, wt_accel2
639 real :: sum_wt_vel, sum_wt_eta, sum_wt_accel, sum_wt_trans
640 real :: I_sum_wt_vel, I_sum_wt_eta, I_sum_wt_accel, I_sum_wt_trans
642 real :: trans_wt1, trans_wt2
645 logical :: apply_OBCs, apply_OBC_flather, apply_OBC_open
647 character(len=200) :: mesg
648 integer :: isv, iev, jsv, jev
650 integer :: isvf, ievf, jsvf, jevf, num_cycles
651 integer :: i, j, k, n
652 integer :: is, ie, js, je, nz, Isq, Ieq, Jsq, Jeq
653 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
654 integer :: ioff, joff
656 if (.not.
associated(cs))
call mom_error(fatal, &
657 "btstep: Module MOM_barotropic must be initialized before it is used.")
658 if (.not.cs%split)
return 659 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
660 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
661 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
662 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
663 ms%isdw = cs%isdw ; ms%iedw = cs%iedw ; ms%jsdw = cs%jsdw ; ms%jedw = cs%jedw
666 use_bt_cont = .false.
667 if (
present(bt_cont)) use_bt_cont = (
associated(bt_cont))
669 interp_eta_pf = .false.
670 if (
present(eta_pf_start)) interp_eta_pf = (
associated(eta_pf_start))
672 project_velocity = cs%BT_project_velocity
676 if ((.not.use_bt_cont) .and. cs%Nonlinear_continuity .and. &
677 (cs%Nonlin_cont_update_period > 0)) stencil = 2
680 if (cs%use_wide_halos) &
681 num_cycles = min((is-cs%isdw) / stencil, (js-cs%jsdw) / stencil)
682 isvf = is - (num_cycles-1)*stencil ; ievf = ie + (num_cycles-1)*stencil
683 jsvf = js - (num_cycles-1)*stencil ; jevf = je + (num_cycles-1)*stencil
685 do_ave = query_averaging_enabled(cs%diag)
686 find_etaav =
present(etaav)
687 find_pf = (do_ave .and. ((cs%id_PFu_bt > 0) .or. (cs%id_PFv_bt > 0)))
688 find_cor = (do_ave .and. ((cs%id_Coru_bt > 0) .or. (cs%id_Corv_bt > 0)))
691 if (
present(uh0)) add_uh0 =
associated(uh0)
692 if (add_uh0 .and. .not.(
present(vh0) .and.
present(u_uh0) .and. &
694 "btstep: vh0, u_uh0, and v_vh0 must be present if uh0 is used.")
695 if (add_uh0 .and. .not.(
associated(vh0) .and.
associated(u_uh0) .and. &
696 associated(v_vh0)))
call mom_error(fatal, &
697 "btstep: vh0, u_uh0, and v_vh0 must be associated if uh0 is used.")
700 nonblock_setup = g%nonblocking_updates
704 apply_obcs = .false. ; cs%BT_OBC%apply_u_OBCs = .false. ; cs%BT_OBC%apply_v_OBCs = .false.
705 apply_obc_open = .false.
706 apply_obc_flather = .false.
707 if (
present(obc))
then ;
if (
associated(obc))
then 708 cs%BT_OBC%apply_u_OBCs = obc%open_u_BCs_exist_globally .or. obc%specified_u_BCs_exist_globally
709 cs%BT_OBC%apply_v_OBCs = obc%open_v_BCs_exist_globally .or. obc%specified_v_BCs_exist_globally
710 apply_obc_flather = obc%Flather_u_BCs_exist_globally .or. obc%Flather_v_BCs_exist_globally
711 apply_obc_open = obc%open_u_BCs_exist_globally .or. obc%open_v_BCs_exist_globally
712 apply_obcs = obc%specified_u_BCs_exist_globally .or. obc%specified_v_BCs_exist_globally .or. &
713 apply_obc_flather .or. apply_obc_open
714 if (.not.apply_obc_flather .and. obc%oblique_BCs_exist_globally) stencil = 2
716 if (apply_obc_flather .and. .not.gv%Boussinesq)
call mom_error(fatal, &
717 "btstep: Flather open boundary conditions have not yet been "// &
718 "implemented for a non-Boussinesq model.")
721 nstep = ceiling(dt/cs%dtbt - 0.0001)
722 if (
is_root_pe() .and. (nstep /= cs%nstep_last))
then 723 write(mesg,
'("btstep is using a dynamic barotropic timestep of ", ES12.6, & 724 & " seconds, max ", ES12.6, ".")') (dt/nstep), cs%dtbt_max
727 cs%nstep_last = nstep
730 instep = 1.0 /
real(nstep)
737 if (project_velocity)
then 738 trans_wt1 = (1.0 + be_proj); trans_wt2 = -be_proj
740 trans_wt1 = bebt ; trans_wt2 = (1.0-bebt)
743 do_hifreq_output = .false.
744 if ((cs%id_ubt_hifreq > 0) .or. (cs%id_vbt_hifreq > 0) .or. &
745 (cs%id_eta_hifreq > 0) .or. (cs%id_eta_pred_hifreq > 0) .or. &
746 (cs%id_uhbt_hifreq > 0) .or. (cs%id_vhbt_hifreq > 0))
then 747 do_hifreq_output = query_averaging_enabled(cs%diag, time_int_in, time_end_in)
748 if (do_hifreq_output) &
749 time_bt_start = time_end_in - set_time(int(floor(dt+0.5)))
754 if (.not. cs%linearized_BT_PV)
then 759 if ((isq > is-1) .or. (jsq > js-1)) &
762 to_all+scalar_pair, agrid)
764 to_all+scalar_pair, agrid)
766 if (cs%dynamic_psurf) &
768 if (interp_eta_pf)
then 777 cs%BT_Domain, to_all+scalar_pair)
779 if (((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) .or. (isq <= is-1) .or. (jsq <= js-1)) &
780 call create_group_pass(cs%pass_force_hbt0_Cor_ref, bt_force_u, bt_force_v, cs%BT_Domain)
781 if (add_uh0)
call create_group_pass(cs%pass_force_hbt0_Cor_ref, uhbt0, vhbt0, cs%BT_Domain)
782 call create_group_pass(cs%pass_force_hbt0_Cor_ref, cor_ref_u, cor_ref_v, cs%BT_Domain)
783 if (.not. use_bt_cont)
then 784 call create_group_pass(cs%pass_Dat_uv, datu, datv, cs%BT_Domain, to_all+scalar_pair)
805 if (cs%linearized_BT_PV)
then 807 do j=jsvf-2,jevf+1 ;
do i=isvf-2,ievf+1
811 do j=jsvf-1,jevf+1 ;
do i=isvf-2,ievf+1
812 dcor_u(i,j) = cs%D_u_Cor(i,j)
815 do j=jsvf-2,jevf+1 ;
do i=isvf-1,ievf+1
816 dcor_v(i,j) = cs%D_v_Cor(i,j)
819 q(:,:) = 0.0 ; dcor_u(:,:) = 0.0 ; dcor_v(:,:) = 0.0
823 do j=js,je ;
do i=is-1,ie
824 dcor_u(i,j) = 0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j))
827 do j=js-1,je ;
do i=is,ie
828 dcor_v(i,j) = 0.5 * (g%bathyT(i,j+1) + g%bathyT(i,j))
831 do j=js-1,je ;
do i=is-1,ie
832 q(i,j) = 0.25 * g%CoriolisBu(i,j) * &
833 ((g%areaT(i,j) + g%areaT(i+1,j+1)) + (g%areaT(i+1,j) + g%areaT(i,j+1))) / &
834 ((g%areaT(i,j) * g%bathyT(i,j) + g%areaT(i+1,j+1) * g%bathyT(i+1,j+1)) + &
835 (g%areaT(i+1,j) * g%bathyT(i+1,j) + g%areaT(i,j+1) * g%bathyT(i,j+1)))
844 if (nonblock_setup)
then 847 call do_group_pass(cs%pass_q_DCor, cs%BT_Domain)
855 do j=cs%jsdw,cs%jedw ;
do i=cs%isdw,cs%iedw
856 gtot_e(i,j) = 0.0 ; gtot_w(i,j) = 0.0
857 gtot_n(i,j) = 0.0 ; gtot_s(i,j) = 0.0
860 if (interp_eta_pf)
then 861 eta_pf_1(i,j) = 0.0 ; d_eta_pf(i,j) = 0.0
863 p_surf_dyn(i,j) = 0.0
864 if (cs%dynamic_psurf) dyn_coef_eta(i,j) = 0.0
870 do j=cs%jsdw,cs%jedw ;
do i=cs%isdw-1,cs%iedw
871 cor_ref_u(i,j) = 0.0 ; bt_force_u(i,j) = 0.0 ; ubt(i,j) = 0.0
872 datu(i,j) = 0.0 ; bt_rem_u(i,j) = 0.0 ; uhbt0(i,j) = 0.0
875 do j=cs%jsdw-1,cs%jedw ;
do i=cs%isdw,cs%iedw
876 cor_ref_v(i,j) = 0.0 ; bt_force_v(i,j) = 0.0 ; vbt(i,j) = 0.0
877 datv(i,j) = 0.0 ; bt_rem_v(i,j) = 0.0 ; vhbt0(i,j) = 0.0
881 if (interp_eta_pf)
then 883 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
884 eta(i,j) = eta_in(i,j)
885 eta_pf_1(i,j) = eta_pf_start(i,j)
886 d_eta_pf(i,j) = eta_pf_in(i,j) - eta_pf_start(i,j)
890 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
891 eta(i,j) = eta_in(i,j)
892 eta_pf(i,j) = eta_pf_in(i,j)
897 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
900 if (visc_rem_u(i,j,k) <= 0.0)
then ; visc_rem = 0.0
901 elseif (visc_rem_u(i,j,k) >= 1.0)
then ; visc_rem = 1.0
902 elseif (visc_rem_u(i,j,k)**2 > visc_rem_u(i,j,k) - 0.5*instep)
then 903 visc_rem = visc_rem_u(i,j,k)
904 else ; visc_rem = 1.0 - 0.5*instep/visc_rem_u(i,j,k) ;
endif 905 wt_u(i,j,k) = cs%frhatu(i,j,k) * visc_rem
906 enddo ;
enddo ;
enddo 908 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
910 if (visc_rem_v(i,j,k) <= 0.0)
then ; visc_rem = 0.0
911 elseif (visc_rem_v(i,j,k) >= 1.0)
then ; visc_rem = 1.0
912 elseif (visc_rem_v(i,j,k)**2 > visc_rem_v(i,j,k) - 0.5*instep)
then 913 visc_rem = visc_rem_v(i,j,k)
914 else ; visc_rem = 1.0 - 0.5*instep/visc_rem_v(i,j,k) ;
endif 915 wt_v(i,j,k) = cs%frhatv(i,j,k) * visc_rem
916 enddo ;
enddo ;
enddo 921 do j=js-1,je+1 ;
do i=is-1,ie ; ubt_cor(i,j) = 0.0 ;
enddo ;
enddo 923 do j=js-1,je ;
do i=is-1,ie+1 ; vbt_cor(i,j) = 0.0 ;
enddo ;
enddo 925 do j=js,je ;
do k=1,nz ;
do i=is-1,ie
926 ubt_cor(i,j) = ubt_cor(i,j) + wt_u(i,j,k) * u_cor(i,j,k)
927 enddo ;
enddo ;
enddo 929 do j=js-1,je ;
do k=1,nz ;
do i=is,ie
930 vbt_cor(i,j) = vbt_cor(i,j) + wt_v(i,j,k) * v_cor(i,j,k)
931 enddo ;
enddo ;
enddo 939 do k=1,nz ;
do i=is-1,ie
940 gtot_e(i,j) = gtot_e(i,j) + pbce(i,j,k) * wt_u(i,j,k)
941 gtot_w(i+1,j) = gtot_w(i+1,j) + pbce(i+1,j,k) * wt_u(i,j,k)
946 do k=1,nz ;
do i=is,ie
947 gtot_n(i,j) = gtot_n(i,j) + pbce(i,j,k) * wt_v(i,j,k)
948 gtot_s(i,j+1) = gtot_s(i,j+1) + pbce(i,j+1,k) * wt_v(i,j,k)
954 dgeo_de = 1.0 + det_de + cs%G_extra
956 dgeo_de = 1.0 + cs%G_extra
959 if (nonblock_setup .and. .not.cs%linearized_BT_PV)
then 969 if (use_bt_cont)
then 972 if (cs%Nonlinear_continuity)
then 981 call set_up_bt_obc(obc, eta, cs%BT_OBC, g, gv, ms, ievf-ie, use_bt_cont, &
982 datu, datv, btcl_u, btcl_v)
992 do j=js,je ;
do i=is-1,ie
996 bt_force_u(i,j) = fluxes%taux(i,j) * i_rho0*cs%IDatu(i,j)*visc_rem_u(i,j,1)
999 do j=js-1,je ;
do i=is,ie
1003 bt_force_v(i,j) = fluxes%tauy(i,j) * i_rho0*cs%IDatv(i,j)*visc_rem_v(i,j,1)
1005 if (
present(taux_bot) .and.
present(tauy_bot))
then 1006 if (
associated(taux_bot) .and.
associated(tauy_bot))
then 1008 do j=js,je ;
do i=is-1,ie
1009 bt_force_u(i,j) = bt_force_u(i,j) - taux_bot(i,j) * i_rho0 * cs%IDatu(i,j)
1012 do j=js-1,je ;
do i=is,ie
1013 bt_force_v(i,j) = bt_force_v(i,j) - tauy_bot(i,j) * i_rho0 * cs%IDatv(i,j)
1021 do j=js,je ;
do k=1,nz ;
do i=isq,ieq
1022 bt_force_u(i,j) = bt_force_u(i,j) + wt_u(i,j,k) * bc_accel_u(i,j,k)
1023 enddo ;
enddo ;
enddo 1025 do j=jsq,jeq ;
do k=1,nz ;
do i=is,ie
1026 bt_force_v(i,j) = bt_force_v(i,j) + wt_v(i,j,k) * bc_accel_v(i,j,k)
1027 enddo ;
enddo ;
enddo 1033 do j=js,je ;
do i=is-1,ie ; uhbt(i,j) = 0.0 ; ubt(i,j) = 0.0 ;
enddo ;
enddo 1035 do j=js-1,je ;
do i=is,ie ; vhbt(i,j) = 0.0 ; vbt(i,j) = 0.0 ;
enddo ;
enddo 1036 if (cs%visc_rem_u_uh0)
then 1038 do j=js,je ;
do k=1,nz ;
do i=is-1,ie
1039 uhbt(i,j) = uhbt(i,j) + uh0(i,j,k)
1040 ubt(i,j) = ubt(i,j) + wt_u(i,j,k) * u_uh0(i,j,k)
1041 enddo ;
enddo ;
enddo 1043 do j=js-1,je ;
do k=1,nz ;
do i=is,ie
1044 vhbt(i,j) = vhbt(i,j) + vh0(i,j,k)
1045 vbt(i,j) = vbt(i,j) + wt_v(i,j,k) * v_vh0(i,j,k)
1046 enddo ;
enddo ;
enddo 1049 do j=js,je ;
do k=1,nz ;
do i=is-1,ie
1050 uhbt(i,j) = uhbt(i,j) + uh0(i,j,k)
1051 ubt(i,j) = ubt(i,j) + cs%frhatu(i,j,k) * u_uh0(i,j,k)
1052 enddo ;
enddo ;
enddo 1054 do j=js-1,je ;
do k=1,nz ;
do i=is,ie
1055 vhbt(i,j) = vhbt(i,j) + vh0(i,j,k)
1056 vbt(i,j) = vbt(i,j) + cs%frhatv(i,j,k) * v_vh0(i,j,k)
1057 enddo ;
enddo ;
enddo 1059 if (use_bt_cont)
then 1060 if (cs%adjust_BT_cont)
then 1067 call pass_vector(ubt, vbt, cs%BT_Domain, complete=.false., halo=1+ievf-ie)
1068 call pass_vector(uhbt, vhbt, cs%BT_Domain, complete=.true., halo=1+ievf-ie)
1076 do j=js,je ;
do i=is-1,ie
1077 uhbt0(i,j) = uhbt(i,j) -
find_uhbt(ubt(i,j),btcl_u(i,j))
1080 do j=js-1,je ;
do i=is,ie
1081 vhbt0(i,j) = vhbt(i,j) -
find_vhbt(vbt(i,j),btcl_v(i,j))
1085 do j=js,je ;
do i=is-1,ie
1086 uhbt0(i,j) = uhbt(i,j) - datu(i,j)*ubt(i,j)
1089 do j=js-1,je ;
do i=is,ie
1090 vhbt0(i,j) = vhbt(i,j) - datv(i,j)*vbt(i,j)
1097 do j=jsvf-1,jevf+1 ;
do i=isvf-2,ievf+1
1098 ubt(i,j) = 0.0 ; uhbt(i,j) = 0.0 ; u_accel_bt(i,j) = 0.0
1101 do j=jsvf-2,jevf+1 ;
do i=isvf-1,ievf+1
1102 vbt(i,j) = 0.0 ; vhbt(i,j) = 0.0 ; v_accel_bt(i,j) = 0.0
1105 do j=js,je ;
do k=1,nz ;
do i=is-1,ie
1106 ubt(i,j) = ubt(i,j) + wt_u(i,j,k) * u_in(i,j,k)
1107 enddo ;
enddo ;
enddo 1109 do j=js-1,je ;
do k=1,nz ;
do i=is,ie
1110 vbt(i,j) = vbt(i,j) + wt_v(i,j,k) * v_in(i,j,k)
1111 enddo ;
enddo ;
enddo 1113 if (apply_obcs)
then 1114 ubt_first(:,:) = ubt(:,:) ; vbt_first(:,:) = vbt(:,:)
1117 if (cs%gradual_BT_ICs)
then 1119 do j=js,je ;
do i=is-1,ie
1120 bt_force_u(i,j) = bt_force_u(i,j) + (ubt(i,j) - cs%ubt_IC(i,j)) * idt
1121 ubt(i,j) = cs%ubt_IC(i,j)
1124 do j=js-1,je ;
do i=is,ie
1125 bt_force_v(i,j) = bt_force_v(i,j) + (vbt(i,j) - cs%vbt_IC(i,j)) * idt
1126 vbt(i,j) = cs%vbt_IC(i,j)
1130 if ((isq > is-1) .or. (jsq > js-1))
then 1135 tmp_u(:,:) = 0.0 ; tmp_v(:,:) = 0.0
1136 do j=js,je ;
do i=isq,ieq ; tmp_u(i,j) = bt_force_u(i,j) ;
enddo ;
enddo 1137 do j=jsq,jeq ;
do i=is,ie ; tmp_v(i,j) = bt_force_v(i,j) ;
enddo ;
enddo 1138 if (nonblock_setup)
then 1141 call do_group_pass(cs%pass_tmp_uv, g%Domain)
1142 do j=jsd,jed ;
do i=isdb,iedb ; bt_force_u(i,j) = tmp_u(i,j) ;
enddo ;
enddo 1143 do j=jsdb,jedb ;
do i=isd,ied ; bt_force_v(i,j) = tmp_v(i,j) ;
enddo ;
enddo 1149 if (nonblock_setup)
then 1160 do j=jsvf-1,jevf ;
do i=isvf-1,ievf+1
1161 if (cs%Sadourny)
then 1162 amer(i-1,j) = dcor_u(i-1,j) * q(i-1,j)
1163 bmer(i,j) = dcor_u(i,j) * q(i,j)
1164 cmer(i,j+1) = dcor_u(i,j+1) * q(i,j)
1165 dmer(i-1,j+1) = dcor_u(i-1,j+1) * q(i-1,j)
1167 amer(i-1,j) = dcor_u(i-1,j) * &
1168 ((q(i,j) + q(i-1,j-1)) + q(i-1,j)) / 3.0
1169 bmer(i,j) = dcor_u(i,j) * &
1170 (q(i,j) + (q(i-1,j) + q(i,j-1))) / 3.0
1171 cmer(i,j+1) = dcor_u(i,j+1) * &
1172 (q(i,j) + (q(i-1,j) + q(i,j+1))) / 3.0
1173 dmer(i-1,j+1) = dcor_u(i-1,j+1) * &
1174 ((q(i,j) + q(i-1,j+1)) + q(i-1,j)) / 3.0
1179 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf
1180 if (cs%Sadourny)
then 1181 azon(i,j) = dcor_v(i+1,j) * q(i,j)
1182 bzon(i,j) = dcor_v(i,j) * q(i,j)
1183 czon(i,j) = dcor_v(i,j-1) * q(i,j-1)
1184 dzon(i,j) = dcor_v(i+1,j-1) * q(i,j-1)
1186 azon(i,j) = dcor_v(i+1,j) * &
1187 (q(i,j) + (q(i+1,j) + q(i,j-1))) / 3.0
1188 bzon(i,j) = dcor_v(i,j) * &
1189 (q(i,j) + (q(i-1,j) + q(i,j-1))) / 3.0
1190 czon(i,j) = dcor_v(i,j-1) * &
1191 ((q(i,j) + q(i-1,j-1)) + q(i,j-1)) / 3.0
1192 dzon(i,j) = dcor_v(i+1,j-1) * &
1193 ((q(i,j) + q(i+1,j-1)) + q(i,j-1)) / 3.0
1200 if (nonblock_setup)
then 1201 if ((isq > is-1) .or. (jsq > js-1))
then 1203 do j=jsd,jed ;
do i=isdb,iedb ; bt_force_u(i,j) = tmp_u(i,j) ;
enddo ;
enddo 1204 do j=jsdb,jedb ;
do i=isd,ied ; bt_force_v(i,j) = tmp_v(i,j) ;
enddo ;
enddo 1209 call do_group_pass(cs%pass_gtot, cs%BT_Domain)
1210 call do_group_pass(cs%pass_ubt_Cor, g%Domain)
1214 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf+1
1215 if (cs%ua_polarity(i,j) < 0.0)
call swap(gtot_e(i,j), gtot_w(i,j))
1216 if (cs%va_polarity(i,j) < 0.0)
call swap(gtot_n(i,j), gtot_s(i,j))
1220 do j=js,je ;
do i=is-1,ie
1222 ((azon(i,j) * vbt_cor(i+1,j) + czon(i,j) * vbt_cor(i ,j-1)) + &
1223 (bzon(i,j) * vbt_cor(i ,j) + dzon(i,j) * vbt_cor(i+1,j-1)))
1226 do j=js-1,je ;
do i=is,ie
1227 cor_ref_v(i,j) = -1.0 * &
1228 ((amer(i-1,j) * ubt_cor(i-1,j) + cmer(i ,j+1) * ubt_cor(i ,j+1)) + &
1229 (bmer(i ,j) * ubt_cor(i ,j) + dmer(i-1,j+1) * ubt_cor(i-1,j+1)))
1233 if (nonblock_setup)
then 1234 if (.not.use_bt_cont) &
1251 do j=js-1,je+1 ;
do i=is-1,ie ; av_rem_u(i,j) = 0.0 ;
enddo ;
enddo 1253 do j=js-1,je ;
do i=is-1,ie+1 ; av_rem_v(i,j) = 0.0 ;
enddo ;
enddo 1255 do j=js,je ;
do k=1,nz ;
do i=is-1,ie
1256 av_rem_u(i,j) = av_rem_u(i,j) + cs%frhatu(i,j,k) * visc_rem_u(i,j,k)
1257 enddo ;
enddo ;
enddo 1259 do j=js-1,je ;
do k=1,nz ;
do i=is,ie
1260 av_rem_v(i,j) = av_rem_v(i,j) + cs%frhatv(i,j,k) * visc_rem_v(i,j,k)
1261 enddo ;
enddo ;
enddo 1262 if (cs%strong_drag)
then 1264 do j=js,je ;
do i=is-1,ie
1265 bt_rem_u(i,j) = g%mask2dCu(i,j) * &
1266 ((nstep * av_rem_u(i,j)) / (1.0 + (nstep-1)*av_rem_u(i,j)))
1269 do j=js-1,je ;
do i=is,ie
1270 bt_rem_v(i,j) = g%mask2dCv(i,j) * &
1271 ((nstep * av_rem_v(i,j)) / (1.0 + (nstep-1)*av_rem_v(i,j)))
1275 do j=js,je ;
do i=is-1,ie
1277 if (g%mask2dCu(i,j) * av_rem_u(i,j) > 0.0) &
1278 bt_rem_u(i,j) = g%mask2dCu(i,j) * (av_rem_u(i,j)**instep)
1281 do j=js-1,je ;
do i=is,ie
1283 if (g%mask2dCv(i,j) * av_rem_v(i,j) > 0.0) &
1284 bt_rem_v(i,j) = g%mask2dCv(i,j) * (av_rem_v(i,j)**instep)
1288 if (find_etaav)
then 1290 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf+1
1291 eta_sum(i,j) = 0.0 ; eta_wtd(i,j) = 0.0
1295 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf+1
1300 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf
1301 ubt_sum(i,j) = 0.0 ; uhbt_sum(i,j) = 0.0
1302 pfu_bt_sum(i,j) = 0.0 ; coru_bt_sum(i,j) = 0.0
1303 ubt_wtd(i,j) = 0.0 ; ubt_trans(i,j) = 0.0
1306 do j=jsvf-1,jevf ;
do i=isvf-1,ievf+1
1307 vbt_sum(i,j) = 0.0 ; vhbt_sum(i,j) = 0.0
1308 pfv_bt_sum(i,j) = 0.0 ; corv_bt_sum(i,j) = 0.0
1309 vbt_wtd(i,j) = 0.0 ; vbt_trans(i,j) = 0.0
1314 do j=jsvf-1,jevf+1;
do i=isvf-1,ievf+1 ; eta_src(i,j) = 0.0 ;
enddo ;
enddo 1315 if (cs%bound_BT_corr)
then ;
if (use_bt_cont .and. cs%BT_cont_bounds)
then 1316 do j=js,je ;
do i=is,ie ;
if (g%mask2dT(i,j) > 0.0)
then 1317 if (cs%eta_cor(i,j) > 0.0)
then 1321 u_max_cor = g%dxT(i,j) * (cs%maxCFL_BT_cont*idt)
1322 v_max_cor = g%dyT(i,j) * (cs%maxCFL_BT_cont*idt)
1323 eta_cor_max = dt * (cs%IareaT(i,j) * &
1324 (((
find_uhbt(u_max_cor,btcl_u(i,j)) + uhbt0(i,j)) - &
1325 (
find_uhbt(-u_max_cor,btcl_u(i-1,j)) + uhbt0(i-1,j))) + &
1326 ((
find_vhbt(v_max_cor,btcl_v(i,j)) + vhbt0(i,j)) - &
1327 (
find_vhbt(-v_max_cor,btcl_v(i,j-1)) + vhbt0(i,j-1))) ) - &
1329 cs%eta_cor(i,j) = min(cs%eta_cor(i,j), max(0.0, eta_cor_max))
1334 if (gv%Boussinesq) htot = cs%bathyT(i,j)*gv%m_to_H + eta(i,j)
1336 cs%eta_cor(i,j) = max(cs%eta_cor(i,j), -max(0.0,htot + dt*cs%eta_source(i,j)))
1338 endif ;
enddo ;
enddo 1339 else ;
do j=js,je ;
do i=is,ie
1340 if (abs(cs%eta_cor(i,j)) > dt*cs%eta_cor_bound(i,j)) &
1341 cs%eta_cor(i,j) = sign(dt*cs%eta_cor_bound(i,j),cs%eta_cor(i,j))
1342 enddo ;
enddo ;
endif ;
endif 1344 do j=js,je ;
do i=is,ie
1345 eta_src(i,j) = g%mask2dT(i,j) * (instep * cs%eta_cor(i,j) + dtbt * cs%eta_source(i,j))
1349 if (cs%dynamic_psurf)
then 1350 ice_is_rigid = (
associated(fluxes%rigidity_ice_u) .and. &
1351 associated(fluxes%rigidity_ice_v))
1352 h_min_dyn = gv%m_to_H * cs%Dmin_dyn_psurf
1353 if (ice_is_rigid .and. use_bt_cont) &
1355 if (ice_is_rigid)
then 1360 do j=js,je ;
do i=is,ie
1366 idt_max2 = 0.5 * (dgeo_de * (1.0 + 2.0*bebt)) * (g%IareaT(i,j) * &
1367 ((gtot_e(i,j) * (datu(i,j)*g%IdxCu(i,j)) + &
1368 gtot_w(i,j) * (datu(i-1,j)*g%IdxCu(i-1,j))) + &
1369 (gtot_n(i,j) * (datv(i,j)*g%IdyCv(i,j)) + &
1370 gtot_s(i,j) * (datv(i,j-1)*g%IdyCv(i,j-1)))) + &
1371 ((g%CoriolisBu(i,j)**2 + g%CoriolisBu(i-1,j-1)**2) + &
1372 (g%CoriolisBu(i-1,j)**2 + g%CoriolisBu(i,j-1)**2)))
1373 h_eff_dx2 = max(h_min_dyn * (g%IdxT(i,j)**2 + g%IdyT(i,j)**2), &
1375 ((datu(i,j)*g%IdxCu(i,j) + datu(i-1,j)*g%IdxCu(i-1,j)) + &
1376 (datv(i,j)*g%IdyCv(i,j) + datv(i,j-1)*g%IdyCv(i,j-1)) ) )
1377 dyn_coef_max = cs%const_dyn_psurf * max(0.0, 1.0 - dtbt**2 * idt_max2) / &
1378 (dtbt**2 * h_eff_dx2)
1381 ice_strength = ((fluxes%rigidity_ice_u(i,j) + fluxes%rigidity_ice_u(i-1,j)) + &
1382 (fluxes%rigidity_ice_v(i,j) + fluxes%rigidity_ice_v(i,j-1))) / &
1383 (cs%ice_strength_length**2 * dtbt)
1386 dyn_coef_eta(i,j) = min(dyn_coef_max, ice_strength * gv%H_to_m)
1387 enddo ;
enddo ;
endif 1392 if (nonblock_setup)
then 1396 call do_group_pass(cs%pass_eta_bt_rem, cs%BT_Domain)
1397 if (.not.use_bt_cont) &
1398 call do_group_pass(cs%pass_Dat_uv, cs%BT_Domain)
1399 call do_group_pass(cs%pass_force_hbt0_Cor_ref, cs%BT_Domain)
1405 if (nonblock_setup)
then 1409 if (.not.use_bt_cont) &
1419 call uvchksum(
"BT [uv]hbt", uhbt, vhbt, cs%debug_BT_HI, haloshift=0, &
1421 call uvchksum(
"BT Initial [uv]bt", ubt, vbt, cs%debug_BT_HI, haloshift=0)
1422 call hchksum(eta,
"BT Initial eta", cs%debug_BT_HI, haloshift=0, scale=gv%H_to_m)
1423 call uvchksum(
"BT BT_force_[uv]", bt_force_u, bt_force_v, &
1424 cs%debug_BT_HI, haloshift=0)
1425 if (interp_eta_pf)
then 1426 call hchksum(eta_pf_1,
"BT eta_PF_1",cs%debug_BT_HI,haloshift=0, scale=gv%H_to_m)
1427 call hchksum(d_eta_pf,
"BT d_eta_PF",cs%debug_BT_HI,haloshift=0, scale=gv%H_to_m)
1429 call hchksum(eta_pf,
"BT eta_PF",cs%debug_BT_HI,haloshift=0, scale=gv%H_to_m)
1430 call hchksum(eta_pf_in,
"BT eta_PF_in",g%HI,haloshift=0, scale=gv%H_to_m)
1432 call uvchksum(
"BT Cor_ref_[uv]", cor_ref_u, cor_ref_v, cs%debug_BT_HI, haloshift=0)
1433 call uvchksum(
"BT [uv]hbt0", uhbt0, vhbt0, cs%debug_BT_HI, &
1434 haloshift=0, scale=gv%H_to_m)
1435 if (.not. use_bt_cont)
then 1436 call uvchksum(
"BT Dat[uv]", datu, datv, cs%debug_BT_HI, haloshift=1, &
1439 call uvchksum(
"BT wt_[uv]", wt_u, wt_v, g%HI, 0, .true., .true.)
1440 call uvchksum(
"BT frhat[uv]", cs%frhatu, cs%frhatv, g%HI, 0, .true., .true.)
1441 call uvchksum(
"BT bc_accel_[uv]", bc_accel_u, bc_accel_v, &
1443 call uvchksum(
"BT IDat[uv]", cs%IDatu, cs%IDatv, g%HI, haloshift=0)
1444 call uvchksum(
"BT visc_rem_[uv]", visc_rem_u, visc_rem_v, &
1448 if (query_averaging_enabled(cs%diag))
then 1449 if (cs%id_eta_st > 0)
call post_data(cs%id_eta_st, eta(isd:ied,jsd:jed), cs%diag)
1450 if (cs%id_ubt_st > 0)
call post_data(cs%id_ubt_st, ubt(isdb:iedb,jsd:jed), cs%diag)
1451 if (cs%id_vbt_st > 0)
call post_data(cs%id_vbt_st, vbt(isd:ied,jsdb:jedb), cs%diag)
1457 if (project_velocity)
then ; eta_pf_bt => eta ;
else ; eta_pf_bt => eta_pred ;
endif 1459 if (cs%dt_bt_filter >= 0.0)
then 1460 dt_filt = 0.5 * max(0.0, min(cs%dt_bt_filter, 2.0*dt))
1462 dt_filt = 0.5 * max(0.0, dt * min(-cs%dt_bt_filter, 2.0))
1464 nfilter = ceiling(dt_filt / dtbt)
1466 if (nstep+nfilter==0 )
call mom_error(fatal, &
1467 "btstep: number of barotropic step (nstep+nfilter) is 0")
1470 sum_wt_vel = 0.0 ; sum_wt_eta = 0.0 ; sum_wt_accel = 0.0 ; sum_wt_trans = 0.0
1471 allocate(wt_vel(nstep+nfilter)) ;
allocate(wt_eta(nstep+nfilter))
1472 allocate(wt_trans(nstep+nfilter+1)) ;
allocate(wt_accel(nstep+nfilter+1))
1473 allocate(wt_accel2(nstep+nfilter+1))
1474 do n=1,nstep+nfilter
1476 if ( (n==nstep) .or. (dt_filt - abs(n-nstep)*dtbt >= 0.0))
then 1477 wt_vel(n) = 1.0 ; wt_eta(n) = 1.0
1478 elseif (dtbt + dt_filt - abs(n-nstep)*dtbt > 0.0)
then 1479 wt_vel(n) = 1.0 + (dt_filt / dtbt) - abs(n-nstep) ; wt_eta(n) = wt_vel(n)
1481 wt_vel(n) = 0.0 ; wt_eta(n) = 0.0
1487 sum_wt_vel = sum_wt_vel + wt_vel(n) ; sum_wt_eta = sum_wt_eta + wt_eta(n)
1489 wt_trans(nstep+nfilter+1) = 0.0 ; wt_accel(nstep+nfilter+1) = 0.0
1490 do n=nstep+nfilter,1,-1
1491 wt_trans(n) = wt_trans(n+1) + wt_eta(n)
1492 wt_accel(n) = wt_accel(n+1) + wt_vel(n)
1493 sum_wt_accel = sum_wt_accel + wt_accel(n) ; sum_wt_trans = sum_wt_trans + wt_trans(n)
1496 i_sum_wt_vel = 1.0 / sum_wt_vel ; i_sum_wt_accel = 1.0 / sum_wt_accel
1497 i_sum_wt_eta = 1.0 / sum_wt_eta ; i_sum_wt_trans = 1.0 / sum_wt_trans
1498 do n=1,nstep+nfilter
1499 wt_vel(n) = wt_vel(n) * i_sum_wt_vel
1500 wt_accel2(n) = wt_accel(n)
1501 wt_accel(n) = wt_accel(n) * i_sum_wt_accel
1502 wt_eta(n) = wt_eta(n) * i_sum_wt_eta
1507 sum_wt_vel = 0.0 ; sum_wt_eta = 0.0 ; sum_wt_accel = 0.0 ; sum_wt_trans = 0.0
1510 isv=is ; iev=ie ; jsv=js ; jev=je
1511 do n=1,nstep+nfilter
1513 sum_wt_vel = sum_wt_vel + wt_vel(n)
1514 sum_wt_eta = sum_wt_eta + wt_eta(n)
1515 sum_wt_accel = sum_wt_accel + wt_accel2(n)
1516 sum_wt_trans = sum_wt_trans + wt_trans(n)
1518 if (cs%clip_velocity)
then 1519 do j=jsv,jev ;
do i=isv-1,iev
1520 if ((ubt(i,j) * (dt * g%dy_Cu(i,j))) * g%IareaT(i+1,j) < -cs%CFL_trunc)
then 1522 ubt(i,j) = (-0.95*cs%CFL_trunc) * (g%areaT(i+1,j) / (dt * g%dy_Cu(i,j)))
1523 elseif ((ubt(i,j) * (dt * g%dy_Cu(i,j))) * g%IareaT(i,j) > cs%CFL_trunc)
then 1525 ubt(i,j) = (0.95*cs%CFL_trunc) * (g%areaT(i,j) / (dt * g%dy_Cu(i,j)))
1528 do j=jsv-1,jev ;
do i=isv,iev
1529 if ((vbt(i,j) * (dt * g%dx_Cv(i,j))) * g%IareaT(i,j+1) < -cs%CFL_trunc)
then 1531 vbt(i,j) = (-0.9*cs%CFL_trunc) * (g%areaT(i,j+1) / (dt * g%dx_Cv(i,j)))
1532 elseif ((vbt(i,j) * (dt * g%dx_Cv(i,j))) * g%IareaT(i,j) > cs%CFL_trunc)
then 1534 vbt(i,j) = (0.9*cs%CFL_trunc) * (g%areaT(i,j) / (dt * g%dx_Cv(i,j)))
1539 if ((iev - stencil < ie) .or. (jev - stencil < je))
then 1542 call do_group_pass(cs%pass_eta_ubt, cs%BT_Domain)
1543 isv = isvf ; iev = ievf ; jsv = jsvf ; jev = jevf
1547 isv = isv+stencil ; iev = iev-stencil
1548 jsv = jsv+stencil ; jev = jev-stencil
1551 if ((.not.use_bt_cont) .and. cs%Nonlinear_continuity .and. &
1552 (cs%Nonlin_cont_update_period > 0))
then 1553 if ((n>1) .and. (mod(n-1,cs%Nonlin_cont_update_period) == 0)) &
1564 if (cs%dynamic_psurf .or. .not.project_velocity)
then 1565 if (use_bt_cont)
then 1567 do j=jsv-1,jev+1 ;
do i=isv-2,iev+1
1568 uhbt(i,j) =
find_uhbt(ubt(i,j),btcl_u(i,j)) + uhbt0(i,j)
1571 do j=jsv-2,jev+1 ;
do i=isv-1,iev+1
1572 vhbt(i,j) =
find_vhbt(vbt(i,j),btcl_v(i,j)) + vhbt0(i,j)
1575 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1576 eta_pred(i,j) = (eta(i,j) + eta_src(i,j)) + (dtbt * cs%IareaT(i,j)) * &
1577 ((uhbt(i-1,j) - uhbt(i,j)) + (vhbt(i,j-1) - vhbt(i,j)))
1581 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1582 eta_pred(i,j) = (eta(i,j) + eta_src(i,j)) + (dtbt * cs%IareaT(i,j)) * &
1583 (((datu(i-1,j)*ubt(i-1,j) + uhbt0(i-1,j)) - &
1584 (datu(i,j)*ubt(i,j) + uhbt0(i,j))) + &
1585 ((datv(i,j-1)*vbt(i,j-1) + vhbt0(i,j-1)) - &
1586 (datv(i,j)*vbt(i,j) + vhbt0(i,j))))
1590 if (cs%dynamic_psurf)
then 1592 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1593 p_surf_dyn(i,j) = dyn_coef_eta(i,j) * (eta_pred(i,j) - eta(i,j))
1601 if (find_etaav)
then 1603 do j=js,je ;
do i=is,ie
1604 eta_sum(i,j) = eta_sum(i,j) + wt_accel2(n) * eta_pf_bt(i,j)
1608 if (interp_eta_pf)
then 1611 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1612 eta_pf(i,j) = eta_pf_1(i,j) + wt_end*d_eta_pf(i,j)
1616 if (apply_obc_flather .or. apply_obc_open)
then 1618 do j=jsv,jev ;
do i=isv-2,iev+1
1619 ubt_old(i,j) = ubt(i,j)
1622 do j=jsv-2,jev+1 ;
do i=isv,iev
1623 vbt_old(i,j) = vbt(i,j)
1628 if (apply_obcs)
then 1629 if (mod(n+g%first_direction,2)==1)
then 1635 if (cs%BT_OBC%apply_u_OBCs)
then 1639 do j=jsv-joff,jev+joff ;
do i=isv-1,iev
1640 ubt_prev(i,j) = ubt(i,j); uhbt_prev(i,j) = uhbt(i,j)
1641 ubt_sum_prev(i,j)=ubt_sum(i,j); uhbt_sum_prev(i,j)=uhbt_sum(i,j) ; ubt_wtd_prev(i,j)=ubt_wtd(i,j)
1645 if (cs%BT_OBC%apply_v_OBCs)
then 1649 do j=jsv-1,jev ;
do i=isv-ioff,iev+ioff
1650 vbt_prev(i,j) = vbt(i,j); vhbt_prev(i,j) = vhbt(i,j)
1651 vbt_sum_prev(i,j)=vbt_sum(i,j); vhbt_sum_prev(i,j)=vhbt_sum(i,j) ; vbt_wtd_prev(i,j) = vbt_wtd(i,j)
1666 if (mod(n+g%first_direction,2)==1)
then 1669 do j=jsv-1,jev ;
do i=isv-1,iev+1
1670 cor_v(i,j) = -1.0*((amer(i-1,j) * ubt(i-1,j) + cmer(i,j+1) * ubt(i,j+1)) + &
1671 (bmer(i,j) * ubt(i,j) + dmer(i-1,j+1) * ubt(i-1,j+1))) - cor_ref_v(i,j)
1672 pfv(i,j) = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_n(i,j) - &
1673 (eta_pf_bt(i,j+1)-eta_pf(i,j+1))*gtot_s(i,j+1)) * &
1674 dgeo_de * cs%IdyCv(i,j)
1676 if (cs%dynamic_psurf)
then 1678 do j=jsv-1,jev ;
do i=isv-1,iev+1
1679 pfv(i,j) = pfv(i,j) + (p_surf_dyn(i,j) - p_surf_dyn(i,j+1)) * cs%IdyCv(i,j)
1683 if (cs%BT_OBC%apply_v_OBCs)
then 1685 do j=jsv-1,jev ;
do i=isv-1,iev+1 ;
if (obc%segnum_v(i,j) /= obc_none)
then 1687 endif ;
enddo ;
enddo 1690 do j=jsv-1,jev ;
do i=isv-1,iev+1
1691 v_accel_bt(i,j) = v_accel_bt(i,j) + wt_accel(n) * (cor_v(i,j) + pfv(i,j))
1693 vbt(i,j) = bt_rem_v(i,j) * (vbt(i,j) + &
1694 dtbt * ((bt_force_v(i,j) + cor_v(i,j)) + pfv(i,j)))
1695 vbt_trans(i,j) = trans_wt1*vbt(i,j) + trans_wt2*vel_prev
1698 if (use_bt_cont)
then 1700 do j=jsv-1,jev ;
do i=isv-1,iev+1
1701 vhbt(i,j) =
find_vhbt(vbt_trans(i,j),btcl_v(i,j)) + vhbt0(i,j)
1705 do j=jsv-1,jev ;
do i=isv-1,iev+1
1706 vhbt(i,j) = datv(i,j)*vbt_trans(i,j) + vhbt0(i,j)
1709 if (cs%BT_OBC%apply_v_OBCs)
then 1711 do j=jsv-1,jev ;
do i=isv-1,iev+1 ;
if (obc%segnum_v(i,j) /= obc_none)
then 1712 vbt(i,j) = vbt_prev(i,j); vhbt(i,j) = vhbt_prev(i,j)
1713 endif ;
enddo ;
enddo 1717 do j=jsv,jev ;
do i=isv-1,iev
1718 cor_u(i,j) = ((azon(i,j) * vbt(i+1,j) + czon(i,j) * vbt(i,j-1)) + &
1719 (bzon(i,j) * vbt(i,j) + dzon(i,j) * vbt(i+1,j-1))) - &
1721 pfu(i,j) = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_e(i,j) - &
1722 (eta_pf_bt(i+1,j)-eta_pf(i+1,j))*gtot_w(i+1,j)) * &
1723 dgeo_de * cs%IdxCu(i,j)
1726 if (cs%dynamic_psurf)
then 1728 do j=jsv,jev ;
do i=isv-1,iev
1729 pfu(i,j) = pfu(i,j) + (p_surf_dyn(i,j) - p_surf_dyn(i+1,j)) * cs%IdxCu(i,j)
1733 if (cs%BT_OBC%apply_u_OBCs)
then 1735 do j=jsv,jev ;
do i=isv-1,iev ;
if (obc%segnum_u(i,j) /= obc_none)
then 1737 endif ;
enddo ;
enddo 1740 do j=jsv,jev ;
do i=isv-1,iev
1741 u_accel_bt(i,j) = u_accel_bt(i,j) + wt_accel(n) * (cor_u(i,j) + pfu(i,j))
1743 ubt(i,j) = bt_rem_u(i,j) * (ubt(i,j) + &
1744 dtbt * ((bt_force_u(i,j) + cor_u(i,j)) + pfu(i,j)))
1745 ubt_trans(i,j) = trans_wt1*ubt(i,j) + trans_wt2*vel_prev
1748 if (use_bt_cont)
then 1750 do j=jsv,jev ;
do i=isv-1,iev
1751 uhbt(i,j) =
find_uhbt(ubt_trans(i,j), btcl_u(i,j)) + uhbt0(i,j)
1755 do j=jsv,jev ;
do i=isv-1,iev
1756 uhbt(i,j) = datu(i,j)*ubt_trans(i,j) + uhbt0(i,j)
1759 if (cs%BT_OBC%apply_u_OBCs)
then 1761 do j=jsv,jev ;
do i=isv-1,iev ;
if (obc%segnum_u(i,j) /= obc_none)
then 1762 ubt(i,j) = ubt_prev(i,j); uhbt(i,j) = uhbt_prev(i,j)
1763 endif ;
enddo ;
enddo 1768 do j=jsv-1,jev+1 ;
do i=isv-1,iev
1769 cor_u(i,j) = ((azon(i,j) * vbt(i+1,j) + czon(i,j) * vbt(i,j-1)) + &
1770 (bzon(i,j) * vbt(i,j) + dzon(i,j) * vbt(i+1,j-1))) - &
1772 pfu(i,j) = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_e(i,j) - &
1773 (eta_pf_bt(i+1,j)-eta_pf(i+1,j))*gtot_w(i+1,j)) * &
1774 dgeo_de * cs%IdxCu(i,j)
1777 if (cs%dynamic_psurf)
then 1779 do j=jsv-1,jev+1 ;
do i=isv-1,iev
1780 pfu(i,j) = pfu(i,j) + (p_surf_dyn(i,j) - p_surf_dyn(i+1,j)) * cs%IdxCu(i,j)
1784 if (cs%BT_OBC%apply_u_OBCs)
then 1786 do j=jsv,jev ;
do i=isv-1,iev ;
if (obc%segnum_u(i,j) /= obc_none)
then 1788 endif ;
enddo ;
enddo 1792 do j=jsv-1,jev+1 ;
do i=isv-1,iev
1793 u_accel_bt(i,j) = u_accel_bt(i,j) + wt_accel(n) * (cor_u(i,j) + pfu(i,j))
1795 ubt(i,j) = bt_rem_u(i,j) * (ubt(i,j) + &
1796 dtbt * ((bt_force_u(i,j) + cor_u(i,j)) + pfu(i,j)))
1797 ubt_trans(i,j) = trans_wt1*ubt(i,j) + trans_wt2*vel_prev
1800 if (use_bt_cont)
then 1802 do j=jsv-1,jev+1 ;
do i=isv-1,iev
1803 uhbt(i,j) =
find_uhbt(ubt_trans(i,j),btcl_u(i,j)) + uhbt0(i,j)
1807 do j=jsv-1,jev+1 ;
do i=isv-1,iev
1808 uhbt(i,j) = datu(i,j)*ubt_trans(i,j) + uhbt0(i,j)
1811 if (cs%BT_OBC%apply_u_OBCs)
then 1813 do j=jsv-1,jev+1 ;
do i=isv-1,iev ;
if (obc%segnum_u(i,j) /= obc_none)
then 1814 ubt(i,j) = ubt_prev(i,j); uhbt(i,j) = uhbt_prev(i,j)
1815 endif ;
enddo ;
enddo 1820 do j=jsv-1,jev ;
do i=isv,iev
1821 cor_v(i,j) = -1.0*((amer(i-1,j) * ubt(i-1,j) + cmer(i,j+1) * ubt(i,j+1)) + &
1822 (bmer(i,j) * ubt(i,j) + dmer(i-1,j+1) * ubt(i-1,j+1))) - cor_ref_v(i,j)
1823 pfv(i,j) = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_n(i,j) - &
1824 (eta_pf_bt(i,j+1)-eta_pf(i,j+1))*gtot_s(i,j+1)) * &
1825 dgeo_de * cs%IdyCv(i,j)
1828 if (cs%dynamic_psurf)
then 1830 do j=jsv-1,jev ;
do i=isv,iev
1831 pfv(i,j) = pfv(i,j) + (p_surf_dyn(i,j) - p_surf_dyn(i,j+1)) * cs%IdyCv(i,j)
1835 if (cs%BT_OBC%apply_v_OBCs)
then 1837 do j=jsv-1,jev ;
do i=isv-1,iev+1 ;
if (obc%segnum_v(i,j) /= obc_none)
then 1839 endif ;
enddo ;
enddo 1843 do j=jsv-1,jev ;
do i=isv,iev
1844 v_accel_bt(i,j) = v_accel_bt(i,j) + wt_accel(n) * (cor_v(i,j) + pfv(i,j))
1846 vbt(i,j) = bt_rem_v(i,j) * (vbt(i,j) + &
1847 dtbt * ((bt_force_v(i,j) + cor_v(i,j)) + pfv(i,j)))
1848 vbt_trans(i,j) = trans_wt1*vbt(i,j) + trans_wt2*vel_prev
1850 if (use_bt_cont)
then 1852 do j=jsv-1,jev ;
do i=isv,iev
1853 vhbt(i,j) =
find_vhbt(vbt_trans(i,j),btcl_v(i,j)) + vhbt0(i,j)
1857 do j=jsv-1,jev ;
do i=isv,iev
1858 vhbt(i,j) = datv(i,j)*vbt_trans(i,j) + vhbt0(i,j)
1861 if (cs%BT_OBC%apply_v_OBCs)
then 1863 do j=jsv-1,jev ;
do i=isv,iev ;
if (obc%segnum_v(i,j) /= obc_none)
then 1864 vbt(i,j) = vbt_prev(i,j); vhbt(i,j) = vhbt_prev(i,j)
1865 endif ;
enddo ;
enddo 1878 do j=js,je ;
do i=is-1,ie
1879 pfu_bt_sum(i,j) = pfu_bt_sum(i,j) + wt_accel2(n) * pfu(i,j)
1882 do j=js-1,je ;
do i=is,ie
1883 pfv_bt_sum(i,j) = pfv_bt_sum(i,j) + wt_accel2(n) * pfv(i,j)
1888 do j=js,je ;
do i=is-1,ie
1889 coru_bt_sum(i,j) = coru_bt_sum(i,j) + wt_accel2(n) * cor_u(i,j)
1892 do j=js-1,je ;
do i=is,ie
1893 corv_bt_sum(i,j) = corv_bt_sum(i,j) + wt_accel2(n) * cor_v(i,j)
1898 do j=js,je ;
do i=is-1,ie
1899 ubt_sum(i,j) = ubt_sum(i,j) + wt_trans(n) * ubt_trans(i,j)
1900 uhbt_sum(i,j) = uhbt_sum(i,j) + wt_trans(n) * uhbt(i,j)
1901 ubt_wtd(i,j) = ubt_wtd(i,j) + wt_vel(n) * ubt(i,j)
1904 do j=js-1,je ;
do i=is,ie
1905 vbt_sum(i,j) = vbt_sum(i,j) + wt_trans(n) * vbt_trans(i,j)
1906 vhbt_sum(i,j) = vhbt_sum(i,j) + wt_trans(n) * vhbt(i,j)
1907 vbt_wtd(i,j) = vbt_wtd(i,j) + wt_vel(n) * vbt(i,j)
1911 if (apply_obcs)
then 1912 if (cs%BT_OBC%apply_u_OBCs)
then 1915 do j=js,je ;
do i=is-1,ie
1916 if (obc%segnum_u(i,j) /= obc_none)
then 1917 ubt_sum(i,j)=ubt_sum_prev(i,j); uhbt_sum(i,j)=uhbt_sum_prev(i,j) ; ubt_wtd(i,j)=ubt_wtd_prev(i,j)
1922 if (cs%BT_OBC%apply_v_OBCs)
then 1925 do j=js-1,je ;
do i=is,ie
1926 if (obc%segnum_v(i,j) /= obc_none)
then 1927 vbt_sum(i,j)=vbt_sum_prev(i,j); vhbt_sum(i,j)=vhbt_sum_prev(i,j) ; vbt_wtd(i,j)=vbt_wtd_prev(i,j)
1933 ubt_trans, vbt_trans, eta, ubt_old, vbt_old, cs%BT_OBC, &
1934 g, ms, iev-ie, dtbt, bebt, use_bt_cont, datu, datv, btcl_u, btcl_v, &
1936 if (cs%BT_OBC%apply_u_OBCs)
then ;
do j=js,je ;
do i=is-1,ie
1937 if (obc%segnum_u(i,j) /= obc_none)
then 1938 ubt_sum(i,j) = ubt_sum(i,j) + wt_trans(n) * ubt_trans(i,j)
1939 uhbt_sum(i,j) = uhbt_sum(i,j) + wt_trans(n) * uhbt(i,j)
1940 ubt_wtd(i,j) = ubt_wtd(i,j) + wt_vel(n) * ubt(i,j)
1942 enddo ;
enddo ;
endif 1943 if (cs%BT_OBC%apply_v_OBCs)
then ;
do j=js-1,je ;
do i=is,ie
1944 if (obc%segnum_v(i,j) /= obc_none)
then 1945 vbt_sum(i,j) = vbt_sum(i,j) + wt_trans(n) * vbt_trans(i,j)
1946 vhbt_sum(i,j) = vhbt_sum(i,j) + wt_trans(n) * vhbt(i,j)
1947 vbt_wtd(i,j) = vbt_wtd(i,j) + wt_vel(n) * vbt(i,j)
1949 enddo ;
enddo ;
endif 1952 if (cs%debug_bt)
then 1953 call uvchksum(
"BT [uv]hbt just after OBC", uhbt, vhbt, &
1954 cs%debug_BT_HI, haloshift=iev-ie, scale=gv%H_to_m)
1958 do j=jsv,jev ;
do i=isv,iev
1959 eta(i,j) = (eta(i,j) + eta_src(i,j)) + (dtbt * cs%IareaT(i,j)) * &
1960 ((uhbt(i-1,j) - uhbt(i,j)) + (vhbt(i,j-1) - vhbt(i,j)))
1961 eta_wtd(i,j) = eta_wtd(i,j) + eta(i,j) * wt_eta(n)
1964 if (apply_obcs)
call apply_eta_obcs(obc, eta, ubt_old, vbt_old, cs%BT_OBC, &
1965 g, ms, iev-ie, dtbt)
1967 if (do_hifreq_output)
then 1968 time_step_end = time_bt_start + set_time(int(floor(n*dtbt+0.5)))
1970 if (cs%id_ubt_hifreq > 0)
call post_data(cs%id_ubt_hifreq, ubt(isdb:iedb,jsd:jed), cs%diag)
1971 if (cs%id_vbt_hifreq > 0)
call post_data(cs%id_vbt_hifreq, vbt(isd:ied,jsdb:jedb), cs%diag)
1972 if (cs%id_eta_hifreq > 0)
call post_data(cs%id_eta_hifreq, eta(isd:ied,jsd:jed), cs%diag)
1973 if (cs%id_uhbt_hifreq > 0)
call post_data(cs%id_uhbt_hifreq, uhbt(isdb:iedb,jsd:jed), cs%diag)
1974 if (cs%id_vhbt_hifreq > 0)
call post_data(cs%id_vhbt_hifreq, vhbt(isd:ied,jsdb:jedb), cs%diag)
1975 if (cs%id_eta_pred_hifreq > 0)
call post_data(cs%id_eta_pred_hifreq, eta_pf_bt(isd:ied,jsd:jed), cs%diag)
1978 if (cs%debug_bt)
then 1979 write(mesg,
'("BT step ",I4)') n
1980 call uvchksum(trim(mesg)//
" [uv]bt", ubt, vbt, &
1981 cs%debug_BT_HI, haloshift=iev-ie)
1982 call hchksum(eta, trim(mesg)//
" eta",cs%debug_BT_HI,haloshift=iev-ie, scale=gv%H_to_m)
1990 if (do_hifreq_output)
call enable_averaging(time_int_in, time_end_in, cs%diag)
1992 i_sum_wt_vel = 1.0 / sum_wt_vel ; i_sum_wt_eta = 1.0 / sum_wt_eta
1993 i_sum_wt_accel = 1.0 / sum_wt_accel ; i_sum_wt_trans = 1.0 / sum_wt_trans
1995 if (find_etaav)
then ;
do j=js,je ;
do i=is,ie
1996 etaav(i,j) = eta_sum(i,j) * i_sum_wt_accel
1997 enddo ;
enddo ;
endif 1998 do j=js-1,je+1 ;
do i=is-1,ie+1 ; e_anom(i,j) = 0.0 ;
enddo ;
enddo 1999 if (interp_eta_pf)
then 2000 do j=js,je ;
do i=is,ie
2001 e_anom(i,j) = dgeo_de * (0.5 * (eta(i,j) + eta_in(i,j)) - &
2002 (eta_pf_1(i,j) + 0.5*d_eta_pf(i,j)))
2005 do j=js,je ;
do i=is,ie
2006 e_anom(i,j) = dgeo_de * (0.5 * (eta(i,j) + eta_in(i,j)) - eta_pf(i,j))
2009 if (apply_obcs)
then 2011 if (cs%BT_OBC%apply_u_OBCs)
then 2014 do j=js,je ;
do i=is-1,ie
2015 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2016 e_anom(i+1,j) = e_anom(i,j)
2017 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2018 e_anom(i,j) = e_anom(i+1,j)
2023 if (cs%BT_OBC%apply_v_OBCs)
then 2026 do j=js-1,je ;
do i=is,ie
2028 e_anom(i,j+1) = e_anom(i,j)
2029 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2030 e_anom(i,j) = e_anom(i,j+1)
2037 do j=js,je ;
do i=is,ie
2038 eta_out(i,j) = eta_wtd(i,j) * i_sum_wt_eta
2043 if (g%nonblocking_updates)
then 2046 if (find_etaav)
call do_group_pass(cs%pass_etaav, g%Domain)
2047 call do_group_pass(cs%pass_e_anom, g%Domain)
2052 do j=js,je ;
do i=is-1,ie
2053 cs%ubtav(i,j) = ubt_sum(i,j) * i_sum_wt_trans
2054 uhbtav(i,j) = uhbt_sum(i,j) * i_sum_wt_trans
2056 ubt_wtd(i,j) = ubt_wtd(i,j) * i_sum_wt_vel
2059 do j=js-1,je ;
do i=is,ie
2060 cs%vbtav(i,j) = vbt_sum(i,j) * i_sum_wt_trans
2061 vhbtav(i,j) = vhbt_sum(i,j) * i_sum_wt_trans
2063 vbt_wtd(i,j) = vbt_wtd(i,j) * i_sum_wt_vel
2068 if (g%nonblocking_updates)
then 2073 call do_group_pass(cs%pass_ubta_uhbta, g%Domain)
2079 if (apply_obcs)
then 2081 if (cs%BT_OBC%apply_u_OBCs)
then ;
do j=js,je ;
do i=is-1,ie
2082 if (obc%segnum_u(i,j) /= obc_none)
then 2083 u_accel_bt(i,j) = (ubt_wtd(i,j) - ubt_first(i,j)) / dt
2085 enddo ;
enddo ;
endif 2086 if (cs%BT_OBC%apply_v_OBCs)
then ;
do j=js-1,je ;
do i=is,ie
2087 if (obc%segnum_v(i,j) /= obc_none)
then 2088 v_accel_bt(i,j) = (vbt_wtd(i,j) - vbt_first(i,j)) / dt
2090 enddo ;
enddo ;
endif 2096 do j=js,je ;
do i=is-1,ie
2097 accel_layer_u(i,j,k) = u_accel_bt(i,j) - &
2098 ((pbce(i+1,j,k) - gtot_w(i+1,j)) * e_anom(i+1,j) - &
2099 (pbce(i,j,k) - gtot_e(i,j)) * e_anom(i,j)) * cs%IdxCu(i,j)
2101 do j=js-1,je ;
do i=is,ie
2102 accel_layer_v(i,j,k) = v_accel_bt(i,j) - &
2103 ((pbce(i,j+1,k) - gtot_s(i,j+1))*e_anom(i,j+1) - &
2104 (pbce(i,j,k) - gtot_n(i,j))*e_anom(i,j)) * cs%IdyCv(i,j)
2111 if (query_averaging_enabled(cs%diag))
then 2113 do j=js,je ;
do i=is-1,ie ; cs%ubt_IC(i,j) = ubt_wtd(i,j) ;
enddo ;
enddo 2114 do j=js-1,je ;
do i=is,ie ; cs%vbt_IC(i,j) = vbt_wtd(i,j) ;
enddo ;
enddo 2115 if (use_bt_cont)
then 2116 do j=js,je ;
do i=is-1,ie
2117 cs%uhbt_IC(i,j) =
find_uhbt(ubt_wtd(i,j), btcl_u(i,j)) + uhbt0(i,j)
2119 do j=js-1,je ;
do i=is,ie
2120 cs%vhbt_IC(i,j) =
find_vhbt(vbt_wtd(i,j), btcl_v(i,j)) + vhbt0(i,j)
2123 do j=js,je ;
do i=is-1,ie
2124 cs%uhbt_IC(i,j) = ubt_wtd(i,j) * datu(i,j) + uhbt0(i,j)
2126 do j=js-1,je ;
do i=is,ie
2127 cs%vhbt_IC(i,j) = vbt_wtd(i,j) * datv(i,j) + vhbt0(i,j)
2132 if (cs%id_PFu_bt > 0)
then 2133 do j=js,je ;
do i=is-1,ie
2134 pfu_bt_sum(i,j) = pfu_bt_sum(i,j) * i_sum_wt_accel
2136 call post_data(cs%id_PFu_bt, pfu_bt_sum(isdb:iedb,jsd:jed), cs%diag)
2138 if (cs%id_PFv_bt > 0)
then 2139 do j=js-1,je ;
do i=is,ie
2140 pfv_bt_sum(i,j) = pfv_bt_sum(i,j) * i_sum_wt_accel
2142 call post_data(cs%id_PFv_bt, pfv_bt_sum(isd:ied,jsdb:jedb), cs%diag)
2144 if (cs%id_Coru_bt > 0)
then 2145 do j=js,je ;
do i=is-1,ie
2146 coru_bt_sum(i,j) = coru_bt_sum(i,j) * i_sum_wt_accel
2148 call post_data(cs%id_Coru_bt, coru_bt_sum(isdb:iedb,jsd:jed), cs%diag)
2150 if (cs%id_Corv_bt > 0)
then 2151 do j=js-1,je ;
do i=is,ie
2152 corv_bt_sum(i,j) = corv_bt_sum(i,j) * i_sum_wt_accel
2154 call post_data(cs%id_Corv_bt, corv_bt_sum(isd:ied,jsdb:jedb), cs%diag)
2156 if (cs%id_ubtforce > 0)
call post_data(cs%id_ubtforce, bt_force_u(isdb:iedb,jsd:jed), cs%diag)
2157 if (cs%id_vbtforce > 0)
call post_data(cs%id_vbtforce, bt_force_v(isd:ied,jsdb:jedb), cs%diag)
2158 if (cs%id_uaccel > 0)
call post_data(cs%id_uaccel, u_accel_bt(isdb:iedb,jsd:jed), cs%diag)
2159 if (cs%id_vaccel > 0)
call post_data(cs%id_vaccel, v_accel_bt(isd:ied,jsdb:jedb), cs%diag)
2161 if (cs%id_eta_cor > 0)
call post_data(cs%id_eta_cor, cs%eta_cor, cs%diag)
2162 if (cs%id_eta_bt > 0)
call post_data(cs%id_eta_bt, eta_out, cs%diag)
2163 if (cs%id_gtotn > 0)
call post_data(cs%id_gtotn, gtot_n(isd:ied,jsd:jed), cs%diag)
2164 if (cs%id_gtots > 0)
call post_data(cs%id_gtots, gtot_s(isd:ied,jsd:jed), cs%diag)
2165 if (cs%id_gtote > 0)
call post_data(cs%id_gtote, gtot_e(isd:ied,jsd:jed), cs%diag)
2166 if (cs%id_gtotw > 0)
call post_data(cs%id_gtotw, gtot_w(isd:ied,jsd:jed), cs%diag)
2167 if (cs%id_ubt > 0)
call post_data(cs%id_ubt, ubt_wtd(isdb:iedb,jsd:jed), cs%diag)
2168 if (cs%id_vbt > 0)
call post_data(cs%id_vbt, vbt_wtd(isd:ied,jsdb:jedb), cs%diag)
2169 if (cs%id_ubtav > 0)
call post_data(cs%id_ubtav, cs%ubtav, cs%diag)
2170 if (cs%id_vbtav > 0)
call post_data(cs%id_vbtav, cs%vbtav, cs%diag)
2171 if (cs%id_visc_rem_u > 0)
call post_data(cs%id_visc_rem_u, visc_rem_u, cs%diag)
2172 if (cs%id_visc_rem_v > 0)
call post_data(cs%id_visc_rem_v, visc_rem_v, cs%diag)
2174 if (cs%id_frhatu > 0)
call post_data(cs%id_frhatu, cs%frhatu, cs%diag)
2175 if (cs%id_uhbt > 0)
call post_data(cs%id_uhbt, uhbtav, cs%diag)
2176 if (cs%id_frhatv > 0)
call post_data(cs%id_frhatv, cs%frhatv, cs%diag)
2177 if (cs%id_vhbt > 0)
call post_data(cs%id_vhbt, vhbtav, cs%diag)
2178 if (cs%id_uhbt0 > 0)
call post_data(cs%id_uhbt0, uhbt0(isdb:iedb,jsd:jed), cs%diag)
2179 if (cs%id_vhbt0 > 0)
call post_data(cs%id_vhbt0, vhbt0(isd:ied,jsdb:jedb), cs%diag)
2181 if (cs%id_frhatu1 > 0)
call post_data(cs%id_frhatu1, cs%frhatu1, cs%diag)
2182 if (cs%id_frhatv1 > 0)
call post_data(cs%id_frhatv1, cs%frhatv1, cs%diag)
2184 if (use_bt_cont)
then 2185 if (cs%id_BTC_FA_u_EE > 0)
call post_data(cs%id_BTC_FA_u_EE, bt_cont%FA_u_EE, cs%diag)
2186 if (cs%id_BTC_FA_u_E0 > 0)
call post_data(cs%id_BTC_FA_u_E0, bt_cont%FA_u_E0, cs%diag)
2187 if (cs%id_BTC_FA_u_W0 > 0)
call post_data(cs%id_BTC_FA_u_W0, bt_cont%FA_u_W0, cs%diag)
2188 if (cs%id_BTC_FA_u_WW > 0)
call post_data(cs%id_BTC_FA_u_WW, bt_cont%FA_u_WW, cs%diag)
2189 if (cs%id_BTC_uBT_EE > 0)
call post_data(cs%id_BTC_uBT_EE, bt_cont%uBT_EE, cs%diag)
2190 if (cs%id_BTC_uBT_WW > 0)
call post_data(cs%id_BTC_uBT_WW, bt_cont%uBT_WW, cs%diag)
2191 if (cs%id_BTC_FA_v_NN > 0)
call post_data(cs%id_BTC_FA_v_NN, bt_cont%FA_v_NN, cs%diag)
2192 if (cs%id_BTC_FA_v_N0 > 0)
call post_data(cs%id_BTC_FA_v_N0, bt_cont%FA_v_N0, cs%diag)
2193 if (cs%id_BTC_FA_v_S0 > 0)
call post_data(cs%id_BTC_FA_v_S0, bt_cont%FA_v_S0, cs%diag)
2194 if (cs%id_BTC_FA_v_SS > 0)
call post_data(cs%id_BTC_FA_v_SS, bt_cont%FA_v_SS, cs%diag)
2195 if (cs%id_BTC_vBT_NN > 0)
call post_data(cs%id_BTC_vBT_NN, bt_cont%vBT_NN, cs%diag)
2196 if (cs%id_BTC_vBT_SS > 0)
call post_data(cs%id_BTC_vBT_SS, bt_cont%vBT_SS, cs%diag)
2199 if (cs%id_frhatu1 > 0) cs%frhatu1(:,:,:) = cs%frhatu(:,:,:)
2200 if (cs%id_frhatv1 > 0) cs%frhatv1(:,:,:) = cs%frhatv(:,:,:)
2203 if (g%nonblocking_updates)
then 2212 subroutine set_dtbt(G, GV, CS, eta, pbce, BT_cont, gtot_est, SSH_add)
2216 real,
dimension(SZI_(G),SZJ_(G)),
intent(in),
optional :: eta
2218 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in),
optional :: pbce
2224 real,
intent(in),
optional :: gtot_est
2226 real,
intent(in),
optional :: SSH_add
2231 real,
dimension(SZI_(G),SZJ_(G)) :: &
2238 real,
dimension(SZIBS_(G),SZJ_(G)) :: &
2241 real,
dimension(SZI_(G),SZJBS_(G)) :: &
2253 real :: min_max_dt2, Idt_max2, dtbt_max
2254 logical :: use_BT_cont
2257 character(len=200) :: mesg
2258 integer :: i, j, k, is, ie, js, je, nz
2260 if (.not.
associated(cs))
call mom_error(fatal, &
2261 "set_dtbt: Module MOM_barotropic must be initialized before it is used.")
2262 if (.not.cs%split)
return 2263 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2264 ms%isdw = g%isd ; ms%iedw = g%ied ; ms%jsdw = g%jsd ; ms%jedw = g%jed
2266 if (.not.(
present(pbce) .or.
present(gtot_est)))
call mom_error(fatal, &
2267 "set_dtbt: Either pbce or gtot_est must be present.")
2269 add_ssh = 0.0 ;
if (
present(ssh_add)) add_ssh = ssh_add
2271 use_bt_cont = .false.
2272 if (
present(bt_cont)) use_bt_cont = (
associated(bt_cont))
2274 if (use_bt_cont)
then 2276 elseif (cs%Nonlinear_continuity .and.
present(eta))
then 2279 call find_face_areas(datu, datv, g, gv, cs, ms, halo=0, add_max=add_ssh)
2284 dgeo_de = 1.0 + max(0.0, det_de + cs%G_extra)
2285 if (
present(pbce))
then 2286 do j=js,je ;
do i=is,ie
2287 gtot_e(i,j) = 0.0 ; gtot_w(i,j) = 0.0
2288 gtot_n(i,j) = 0.0 ; gtot_s(i,j) = 0.0
2290 do k=1,nz ;
do j=js,je ;
do i=is,ie
2291 gtot_e(i,j) = gtot_e(i,j) + pbce(i,j,k) * cs%frhatu(i,j,k)
2292 gtot_w(i,j) = gtot_w(i,j) + pbce(i,j,k) * cs%frhatu(i-1,j,k)
2293 gtot_n(i,j) = gtot_n(i,j) + pbce(i,j,k) * cs%frhatv(i,j,k)
2294 gtot_s(i,j) = gtot_s(i,j) + pbce(i,j,k) * cs%frhatv(i,j-1,k)
2295 enddo ;
enddo ;
enddo 2297 do j=js,je ;
do i=is,ie
2298 gtot_e(i,j) = gtot_est * gv%H_to_m ; gtot_w(i,j) = gtot_est * gv%H_to_m
2299 gtot_n(i,j) = gtot_est * gv%H_to_m ; gtot_s(i,j) = gtot_est * gv%H_to_m
2303 min_max_dt2 = 1.0e38
2304 do j=js,je ;
do i=is,ie
2307 idt_max2 = 0.5 * (1.0 + 2.0*cs%bebt) * (g%IareaT(i,j) * &
2308 ((gtot_e(i,j)*datu(i,j)*g%IdxCu(i,j) + gtot_w(i,j)*datu(i-1,j)*g%IdxCu(i-1,j)) + &
2309 (gtot_n(i,j)*datv(i,j)*g%IdyCv(i,j) + gtot_s(i,j)*datv(i,j-1)*g%IdyCv(i,j-1))) + &
2310 ((g%CoriolisBu(i,j)**2 + g%CoriolisBu(i-1,j-1)**2) + &
2311 (g%CoriolisBu(i-1,j)**2 + g%CoriolisBu(i,j-1)**2)))
2312 if (idt_max2 * min_max_dt2 > 1.0) min_max_dt2 = 1.0 / idt_max2
2314 dtbt_max = sqrt(min_max_dt2 / dgeo_de)
2316 call min_across_pes(dtbt_max)
2319 cs%dtbt = cs%dtbt_fraction * dtbt_max
2320 cs%dtbt_max = dtbt_max
2327 eta, ubt_old, vbt_old, BT_OBC, &
2328 G, MS, halo, dtbt, bebt, use_BT_cont, Datu, Datv, &
2329 BTCL_u, BTCL_v, uhbt0, vhbt0)
2334 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(inout) :: ubt
2335 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(inout) :: uhbt
2336 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(inout) :: ubt_trans
2338 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(inout) :: vbt
2339 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(inout) :: vhbt
2340 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(inout) :: vbt_trans
2342 real,
dimension(SZIW_(MS),SZJW_(MS)),
intent(in) :: eta
2344 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: ubt_old
2346 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: vbt_old
2351 integer,
intent(in) :: halo
2352 real,
intent(in) :: dtbt
2353 real,
intent(in) :: bebt
2355 logical,
intent(in) :: use_BT_cont
2357 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: Datu
2358 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: Datv
2365 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: uhbt0
2366 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: vhbt0
2378 real :: cff, Cx, Cy, tau
2379 real :: dhdt, dhdx, dhdy
2380 integer :: i, j, is, ie, js, je
2381 real,
dimension(SZIB_(G),SZJB_(G)) :: grad
2382 real,
parameter :: eps = 1.0e-20
2383 real :: rx_max, ry_max
2384 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
2385 rx_max = obc%rx_max ; ry_max = obc%rx_max
2387 if (bt_obc%apply_u_OBCs)
then 2388 do j=js,je ;
do i=is-1,ie ;
if (obc%segnum_u(i,j) /= obc_none)
then 2389 if (obc%segment(obc%segnum_u(i,j))%specified)
then 2390 uhbt(i,j) = bt_obc%uhbt(i,j)
2391 ubt(i,j) = bt_obc%ubt_outer(i,j)
2392 vel_trans = ubt(i,j)
2393 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2394 if (obc%segment(obc%segnum_u(i,j))%Flather)
then 2395 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2396 u_inlet = cfl*ubt_old(i-1,j) + (1.0-cfl)*ubt_old(i,j)
2398 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i-1,j))
2399 h_u = bt_obc%H_u(i,j)
2401 ubt(i,j) = 0.5*((u_inlet + bt_obc%ubt_outer(i,j)) + &
2402 (bt_obc%Cg_u(i,j)/h_u) * (h_in-bt_obc%eta_outer_u(i,j)))
2403 vel_trans = (1.0-bebt)*vel_prev + bebt*ubt(i,j)
2404 elseif (obc%segment(obc%segnum_u(i,j))%oblique)
then 2405 grad(i,j) = (ubt_old(i,j+1) - ubt_old(i,j)) * g%mask2dBu(i,j)
2406 grad(i,j-1) = (ubt_old(i,j) - ubt_old(i,j-1)) * g%mask2dBu(i,j-1)
2407 grad(i-1,j) = (ubt_old(i-1,j+1) - ubt_old(i-1,j)) * g%mask2dBu(i-1,j)
2408 grad(i-1,j-1) = (ubt_old(i-1,j) - ubt_old(i-1,j-1)) * g%mask2dBu(i-1,j-1)
2409 dhdt = ubt_old(i-1,j)-ubt(i-1,j)
2410 dhdx = ubt(i-1,j)-ubt(i-2,j)
2412 if (dhdt*(grad(i-1,j) + grad(i-1,j-1)) > 0.0)
then 2413 dhdy = grad(i-1,j-1)
2414 elseif (dhdt*(grad(i-1,j) + grad(i-1,j-1)) == 0.0)
then 2420 if (dhdt*dhdx < 0.0) dhdt = 0.0
2421 if (dhdx == 0.0) dhdx=eps
2422 cx = min(dhdt/dhdx,rx_max)
2424 cff = max(dhdx*dhdx, eps)
2426 cff = max(dhdx*dhdx + dhdy*dhdy, eps)
2427 if (dhdy==0.) dhdy=eps
2428 cy = min(cff, max(dhdt/dhdy, -cff))
2430 ubt(i,j) = ((cff*ubt_old(i,j) + cx*ubt(i-1,j)) - &
2431 (max(cy,0.0)*grad(i,j-1) + min(cy,0.0)*grad(i,j))) / (cff + cx)
2432 vel_trans = ubt(i,j)
2433 elseif (obc%segment(obc%segnum_u(i,j))%gradient)
then 2434 ubt(i,j) = ubt(i-1,j)
2435 vel_trans = ubt(i,j)
2437 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2438 if (obc%segment(obc%segnum_u(i,j))%Flather)
then 2439 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2440 u_inlet = cfl*ubt_old(i+1,j) + (1.0-cfl)*ubt_old(i,j)
2442 h_in = eta(i+1,j) + (0.5-cfl)*(eta(i+1,j)-eta(i+2,j))
2444 h_u = bt_obc%H_u(i,j)
2446 ubt(i,j) = 0.5*((u_inlet+bt_obc%ubt_outer(i,j)) + &
2447 (bt_obc%Cg_u(i,j)/h_u) * (bt_obc%eta_outer_u(i,j)-h_in))
2449 vel_trans = (1.0-bebt)*vel_prev + bebt*ubt(i,j)
2450 elseif (obc%segment(obc%segnum_u(i,j))%oblique)
then 2451 grad(i,j) = (ubt_old(i,j+1) - ubt_old(i,j)) * g%mask2dBu(i,j)
2452 grad(i,j-1) = (ubt_old(i,j) - ubt_old(i,j-1)) * g%mask2dBu(i,j-1)
2453 grad(i+1,j) = (ubt_old(i+1,j+1) - ubt_old(i+1,j)) * g%mask2dBu(i+1,j)
2454 grad(i+1,j-1) = (ubt_old(i+1,j) - ubt_old(i+1,j-1)) * g%mask2dBu(i+1,j-1)
2455 dhdt = ubt_old(i+1,j)-ubt(i+1,j)
2456 dhdx = ubt(i+1,j)-ubt(i+2,j)
2458 if (dhdt*(grad(i+1,j) + grad(i+1,j-1)) > 0.0)
then 2459 dhdy = grad(i+1,j-1)
2460 elseif (dhdt*(grad(i+1,j) + grad(i+1,j-1)) == 0.0)
then 2466 if (dhdt*dhdx < 0.0) dhdt = 0.0
2467 if (dhdx == 0.0) dhdx=eps
2468 cx = min(dhdt/dhdx,rx_max)
2470 cff = max(dhdx*dhdx, eps)
2472 cff = max(dhdx*dhdx + dhdy*dhdy, eps)
2473 if (dhdy==0.) dhdy=eps
2474 cy = min(cff,max(dhdt/dhdy,-cff))
2476 ubt(i,j) = ((cff*ubt_old(i,j) + cx*ubt(i+1,j)) - &
2477 (max(cy,0.0)*grad(i,j-1) + min(cy,0.0)*grad(i,j))) / (cff + cx)
2479 vel_trans = ubt(i,j)
2480 elseif (obc%segment(obc%segnum_u(i,j))%gradient)
then 2481 ubt(i,j) = ubt(i+1,j)
2482 vel_trans = ubt(i,j)
2486 if (.not. obc%segment(obc%segnum_u(i,j))%specified)
then 2487 if (use_bt_cont)
then 2488 uhbt(i,j) =
find_uhbt(vel_trans,btcl_u(i,j)) + uhbt0(i,j)
2490 uhbt(i,j) = datu(i,j)*vel_trans + uhbt0(i,j)
2494 ubt_trans(i,j) = vel_trans
2495 endif ;
enddo ;
enddo 2498 if (bt_obc%apply_v_OBCs)
then 2499 do j=js-1,je ;
do i=is,ie ;
if (obc%segnum_v(i,j) /= obc_none)
then 2500 if (obc%segment(obc%segnum_v(i,j))%specified)
then 2501 vhbt(i,j) = bt_obc%vhbt(i,j)
2502 vbt(i,j) = bt_obc%vbt_outer(i,j)
2503 vel_trans = vbt(i,j)
2504 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_n)
then 2505 if (obc%segment(obc%segnum_v(i,j))%Flather)
then 2506 cfl = dtbt * bt_obc%Cg_v(i,j) * g%IdyCv(i,j)
2507 v_inlet = cfl*vbt_old(i,j-1) + (1.0-cfl)*vbt_old(i,j)
2509 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i,j-1))
2511 h_v = bt_obc%H_v(i,j)
2513 vbt(i,j) = 0.5*((v_inlet+bt_obc%vbt_outer(i,j)) + &
2514 (bt_obc%Cg_v(i,j)/h_v) * (h_in-bt_obc%eta_outer_v(i,j)))
2516 vel_trans = (1.0-bebt)*vel_prev + bebt*vbt(i,j)
2517 elseif (obc%segment(obc%segnum_v(i,j))%oblique)
then 2518 grad(i,j) = (vbt_old(i+1,j) - vbt_old(i,j)) * g%mask2dBu(i,j)
2519 grad(i-1,j) = (vbt_old(i,j) - vbt_old(i-1,j)) * g%mask2dBu(i-1,j)
2520 grad(i,j-1) = (vbt_old(i+1,j-1) - vbt_old(i,j-1)) * g%mask2dBu(i,j-1)
2521 grad(i-1,j-1) = (vbt_old(i,j-1) - vbt_old(i-1,j-1)) * g%mask2dBu(i-1,j-1)
2522 dhdt = vbt_old(i,j-1)-vbt(i,j-1)
2523 dhdy = vbt(i,j-1)-vbt(i,j-2)
2525 if (dhdt*(grad(i,j-1) + grad(i-1,j-1)) > 0.0)
then 2526 dhdx = grad(i-1,j-1)
2527 elseif (dhdt*(grad(i,j-1) + grad(i-1,j-1)) == 0.0)
then 2533 if (dhdt*dhdy < 0.0) dhdt = 0.0
2534 if (dhdy == 0.0) dhdy=eps
2535 cy = min(dhdt/dhdy,rx_max)
2537 cff = max(dhdy*dhdy, eps)
2539 cff = max(dhdx*dhdx + dhdy*dhdy, eps)
2540 if (dhdx==0.) dhdx=eps
2541 cx = min(cff,max(dhdt/dhdx,-cff))
2543 vbt(i,j) = ((cff*vbt_old(i,j) + cy*vbt(i,j-1)) - &
2544 (max(cx,0.0)*grad(i-1,j) + min(cx,0.0)*grad(i,j))) / (cff + cy)
2546 vel_trans = vbt(i,j)
2547 elseif (obc%segment(obc%segnum_v(i,j))%gradient)
then 2548 vbt(i,j) = vbt(i,j-1)
2549 vel_trans = vbt(i,j)
2551 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2552 if (obc%segment(obc%segnum_v(i,j))%Flather)
then 2553 cfl = dtbt * bt_obc%Cg_v(i,j) * g%IdyCv(i,j)
2554 v_inlet = cfl*vbt_old(i,j+1) + (1.0-cfl)*vbt_old(i,j)
2556 h_in = eta(i,j+1) + (0.5-cfl)*(eta(i,j+1)-eta(i,j+2))
2558 h_v = bt_obc%H_v(i,j)
2560 vbt(i,j) = 0.5*((v_inlet+bt_obc%vbt_outer(i,j)) + &
2561 (bt_obc%Cg_v(i,j)/h_v) * (bt_obc%eta_outer_v(i,j)-h_in))
2563 vel_trans = (1.0-bebt)*vel_prev + bebt*vbt(i,j)
2564 elseif (obc%segment(obc%segnum_v(i,j))%oblique)
then 2565 grad(i,j) = (vbt_old(i+1,j) - vbt_old(i,j)) * g%mask2dBu(i,j)
2566 grad(i-1,j) = (vbt_old(i,j) - vbt_old(i-1,j)) * g%mask2dBu(i-1,j)
2567 grad(i,j+1) = (vbt_old(i+1,j+1) - vbt_old(i,j+1)) * g%mask2dBu(i,j+1)
2568 grad(i-1,j+1) = (vbt_old(i,j+1) - vbt_old(i-1,j+1)) * g%mask2dBu(i-1,j+1)
2569 dhdt = vbt_old(i,j+1)-vbt(i,j+1)
2570 dhdy = vbt(i,j+1)-vbt(i,j+2)
2572 if (dhdt*(grad(i,j+1) + grad(i-1,j+1)) > 0.0)
then 2573 dhdx = grad(i-1,j+1)
2574 elseif (dhdt*(grad(i,j+1) + grad(i-1,j+1)) == 0.0)
then 2580 if (dhdt*dhdy < 0.0) dhdt = 0.0
2581 if (dhdy == 0.0) dhdy=eps
2582 cy = min(dhdt/dhdy,rx_max)
2584 cff = max(dhdy*dhdy, eps)
2586 cff = max(dhdx*dhdx + dhdy*dhdy, eps)
2587 if (dhdx==0.) dhdx=eps
2588 cx = min(cff,max(dhdt/dhdx,-cff))
2590 vbt(i,j) = ((cff*vbt_old(i,j) + cy*vbt(i,j+1)) - &
2591 (max(cx,0.0)*grad(i-1,j) + min(cx,0.0)*grad(i,j))) / (cff + cy)
2593 vel_trans = vbt(i,j)
2594 elseif (obc%segment(obc%segnum_v(i,j))%gradient)
then 2595 vbt(i,j) = vbt(i,j+1)
2596 vel_trans = vbt(i,j)
2600 if (.not. obc%segment(obc%segnum_v(i,j))%specified)
then 2601 if (use_bt_cont)
then 2602 vhbt(i,j) =
find_vhbt(vel_trans,btcl_v(i,j)) + vhbt0(i,j)
2604 vhbt(i,j) = vel_trans*datv(i,j) + vhbt0(i,j)
2608 vbt_trans(i,j) = vel_trans
2609 endif ;
enddo ;
enddo 2616 subroutine apply_eta_obcs(OBC, eta, ubt, vbt, BT_OBC, G, MS, halo, dtbt)
2620 real,
dimension(SZIW_(MS),SZJW_(MS)),
intent(inout) :: eta
2622 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: ubt
2623 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: vbt
2628 integer,
intent(in) :: halo
2629 real,
intent(in) :: dtbt
2638 integer :: i, j, is, ie, js, je
2639 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
2641 if (obc%open_u_BCs_exist_globally .and. bt_obc%apply_u_OBCS)
then 2642 do j=js,je ;
do i=is-1,ie ;
if (obc%segnum_u(i,j) /= obc_none)
then 2643 if (obc%segment(obc%segnum_u(i,j))%Flather)
then 2644 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2645 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2646 u_inlet = cfl*ubt(i-1,j) + (1.0-cfl)*ubt(i,j)
2648 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i-1,j))
2650 h_u = bt_obc%H_u(i,j)
2651 eta(i+1,j) = 2.0 * 0.5*((bt_obc%eta_outer_u(i,j)+h_in) + &
2652 (h_u/bt_obc%Cg_u(i,j))*(u_inlet-bt_obc%ubt_outer(i,j))) - eta(i,j)
2653 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2654 cfl = dtbt*bt_obc%Cg_u(i,j)*g%IdxCu(i,j)
2655 u_inlet = cfl*ubt(i+1,j) + (1.0-cfl)*ubt(i,j)
2657 h_in = eta(i+1,j) + (0.5-cfl)*(eta(i+1,j)-eta(i+2,j))
2659 h_u = bt_obc%H_u(i,j)
2660 eta(i,j) = 2.0 * 0.5*((bt_obc%eta_outer_u(i,j)+h_in) + &
2661 (h_u/bt_obc%Cg_u(i,j))*(bt_obc%ubt_outer(i,j)-u_inlet)) - eta(i+1,j)
2663 elseif (obc%segment(obc%segnum_u(i,j))%radiation)
then 2665 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2666 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2667 eta(i+1,j) = 1.0/(1 + cfl) * (eta(i,j) + cfl*eta(i-1,j))
2668 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2669 cfl = dtbt*bt_obc%Cg_u(i,j)*g%IdxCu(i,j)
2670 eta(i,j) = 1.0/(1 + cfl) * (eta(i+1,j) + cfl*eta(i+2,j))
2672 elseif (obc%segment(obc%segnum_u(i,j))%gradient)
then 2673 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2674 eta(i+1,j) = eta(i,j)
2675 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2676 eta(i,j) = eta(i+1,j)
2679 endif ;
enddo ;
enddo 2682 if (obc%open_v_BCs_exist_globally .and. bt_obc%apply_v_OBCs)
then 2683 do j=js-1,je ;
do i=is,ie ;
if (obc%segnum_v(i,j) /= obc_none)
then 2684 if (obc%segment(obc%segnum_v(i,j))%Flather)
then 2686 cfl = dtbt*bt_obc%Cg_v(i,j)*g%IdyCv(i,j)
2687 v_inlet = cfl*vbt(i,j-1) + (1.0-cfl)*vbt(i,j)
2689 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i,j-1))
2691 h_v = bt_obc%H_v(i,j)
2692 eta(i,j+1) = 2.0 * 0.5*((bt_obc%eta_outer_v(i,j)+h_in) + &
2693 (h_v/bt_obc%Cg_v(i,j))*(v_inlet-bt_obc%vbt_outer(i,j))) - eta(i,j)
2694 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2695 cfl = dtbt*bt_obc%Cg_v(i,j)*g%IdyCv(i,j)
2696 v_inlet = cfl*vbt(i,j+1) + (1.0-cfl)*vbt(i,j)
2698 h_in = eta(i,j+1) + (0.5-cfl)*(eta(i,j+1)-eta(i,j+2))
2700 h_v = bt_obc%H_v(i,j)
2701 eta(i,j) = 2.0 * 0.5*((bt_obc%eta_outer_v(i,j)+h_in) + &
2702 (h_v/bt_obc%Cg_v(i,j))*(bt_obc%vbt_outer(i,j)-v_inlet)) - eta(i,j+1)
2704 elseif (obc%segment(obc%segnum_v(i,j))%radiation)
then 2707 cfl = dtbt*bt_obc%Cg_v(i,j)*g%IdyCv(i,j)
2708 eta(i,j+1) = 1.0/(1 + cfl) * (eta(i,j) + cfl*eta(i,j-1))
2709 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2710 cfl = dtbt*bt_obc%Cg_v(i,j)*g%IdyCv(i,j)
2711 eta(i,j) = 1.0/(1 + cfl) * (eta(i,j+1) + cfl*eta(i,j+2))
2713 elseif (obc%segment(obc%segnum_v(i,j))%gradient)
then 2715 eta(i,j+1) = eta(i,j)
2716 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2717 eta(i,j) = eta(i,j+1)
2720 endif ;
enddo ;
enddo 2727 subroutine set_up_bt_obc(OBC, eta, BT_OBC, G, GV, MS, halo, use_BT_cont, Datu, Datv, BTCL_u, BTCL_v)
2731 real,
dimension(SZIW_(MS),SZJW_(MS)),
intent(in) :: eta
2738 integer,
intent(in) :: halo
2739 logical,
intent(in) :: use_BT_cont
2741 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: Datu
2742 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: Datv
2751 integer :: i, j, k, is, ie, js, je, n, nz, Isq, Ieq, Jsq, Jeq
2752 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
2753 integer :: isdw, iedw, jsdw, jedw
2756 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
2757 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
2758 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
2759 isdw = ms%isdw ; iedw = ms%iedw ; jsdw = ms%jsdw ; jedw = ms%jedw
2761 if ((isdw < isd) .or. (jsdw < jsd))
then 2762 call mom_error(fatal,
"set_up_BT_OBC: Open boundary conditions are not "//&
2763 "yet fully implemented with wide barotropic halos.")
2766 if (.not. bt_obc%is_alloced)
then 2767 allocate(bt_obc%Cg_u(isdw-1:iedw,jsdw:jedw)) ; bt_obc%Cg_u(:,:) = 0.0
2768 allocate(bt_obc%H_u(isdw-1:iedw,jsdw:jedw)) ; bt_obc%H_u(:,:) = 0.0
2769 allocate(bt_obc%uhbt(isdw-1:iedw,jsdw:jedw)) ; bt_obc%uhbt(:,:) = 0.0
2770 allocate(bt_obc%ubt_outer(isdw-1:iedw,jsdw:jedw)) ; bt_obc%ubt_outer(:,:) = 0.0
2771 allocate(bt_obc%eta_outer_u(isdw-1:iedw,jsdw:jedw)) ; bt_obc%eta_outer_u(:,:) = 0.0
2773 allocate(bt_obc%Cg_v(isdw:iedw,jsdw-1:jedw)) ; bt_obc%Cg_v(:,:) = 0.0
2774 allocate(bt_obc%H_v(isdw:iedw,jsdw-1:jedw)) ; bt_obc%H_v(:,:) = 0.0
2775 allocate(bt_obc%vhbt(isdw:iedw,jsdw-1:jedw)) ; bt_obc%vhbt(:,:) = 0.0
2776 allocate(bt_obc%vbt_outer(isdw:iedw,jsdw-1:jedw)) ; bt_obc%vbt_outer(:,:) = 0.0
2777 allocate(bt_obc%eta_outer_v(isdw:iedw,jsdw-1:jedw)) ; bt_obc%eta_outer_v(:,:)=0.0
2778 bt_obc%is_alloced = .true.
2781 if (bt_obc%apply_u_OBCs)
then 2782 if (obc%specified_u_BCs_exist_globally)
then 2783 do n = 1, obc%number_of_segments
2784 segment => obc%segment(n)
2785 if (segment%is_E_or_W .and. segment%specified)
then 2786 do j=segment%HI%jsd,segment%HI%jed ;
do i=segment%HI%IsdB,segment%HI%IedB
2787 bt_obc%uhbt(i,j) = 0.
2789 do k=1,nz ;
do j=segment%HI%jsd,segment%HI%jed ;
do i=segment%HI%IsdB,segment%HI%IedB
2790 bt_obc%uhbt(i,j) = bt_obc%uhbt(i,j) + segment%normal_trans(i,j,k)
2791 enddo ;
enddo ;
enddo 2795 do j=js,je ;
do i=is-1,ie ;
if (obc%segnum_u(i,j) /= obc_none)
then 2797 if (obc%segment(obc%segnum_u(i,j))%specified)
then 2798 if (use_bt_cont)
then 2799 bt_obc%ubt_outer(i,j) =
uhbt_to_ubt(bt_obc%uhbt(i,j),btcl_u(i,j))
2801 if (datu(i,j) > 0.0) bt_obc%ubt_outer(i,j) = bt_obc%uhbt(i,j) / datu(i,j)
2804 bt_obc%Cg_u(i,j) = sqrt(gv%g_prime(1)*(0.5* &
2805 (g%bathyT(i,j) + g%bathyT(i+1,j))))
2806 if (gv%Boussinesq)
then 2807 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2808 bt_obc%H_u(i,j) = g%bathyT(i,j)*gv%m_to_H + eta(i,j)
2809 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2810 bt_obc%H_u(i,j) = g%bathyT(i+1,j)*gv%m_to_H + eta(i+1,j)
2813 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2814 bt_obc%H_u(i,j) = eta(i,j)
2815 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2816 bt_obc%H_u(i,j) = eta(i+1,j)
2820 endif ;
enddo ;
enddo 2821 if (obc%Flather_u_BCs_exist_globally)
then 2822 do n = 1, obc%number_of_segments
2823 segment => obc%segment(n)
2824 if (segment%is_E_or_W .and. segment%Flather)
then 2825 do j=segment%HI%jsd,segment%HI%jed ;
do i=segment%HI%IsdB,segment%HI%IedB
2826 bt_obc%ubt_outer(i,j) = segment%normal_vel_bt(i,j)
2827 bt_obc%eta_outer_u(i,j) = segment%eta(i,j)
2834 if (bt_obc%apply_v_OBCs)
then 2835 if (obc%specified_v_BCs_exist_globally)
then 2836 do n = 1, obc%number_of_segments
2837 segment => obc%segment(n)
2838 if (segment%is_N_or_S .and. segment%specified)
then 2839 do j=segment%HI%JsdB,segment%HI%JedB ;
do i=segment%HI%isd,segment%HI%ied
2840 bt_obc%vhbt(i,j) = 0.
2842 do k=1,nz ;
do j=segment%HI%JsdB,segment%HI%JedB ;
do i=segment%HI%isd,segment%HI%ied
2843 bt_obc%vhbt(i,j) = bt_obc%vhbt(i,j) + segment%normal_trans(i,j,k)
2844 enddo ;
enddo ;
enddo 2848 do j=js-1,je ;
do i=is,ie ;
if (obc%segnum_v(i,j) /= obc_none)
then 2850 if (obc%segment(obc%segnum_v(i,j))%specified)
then 2851 if (use_bt_cont)
then 2852 bt_obc%vbt_outer(i,j) =
vhbt_to_vbt(bt_obc%vhbt(i,j),btcl_v(i,j))
2854 if (datv(i,j) > 0.0) bt_obc%vbt_outer(i,j) = bt_obc%vhbt(i,j) / datv(i,j)
2857 bt_obc%Cg_v(i,j) = sqrt(gv%g_prime(1)*(0.5* &
2858 (g%bathyT(i,j) + g%bathyT(i,j+1))))
2859 if (gv%Boussinesq)
then 2861 bt_obc%H_v(i,j) = g%bathyT(i,j)*gv%m_to_H + eta(i,j)
2862 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2863 bt_obc%H_v(i,j) = g%bathyT(i,j+1)*gv%m_to_H + eta(i,j+1)
2867 bt_obc%H_v(i,j) = eta(i,j)
2868 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then 2869 bt_obc%H_v(i,j) = eta(i,j+1)
2873 endif ;
enddo ;
enddo 2874 if (obc%Flather_v_BCs_exist_globally)
then 2875 do n = 1, obc%number_of_segments
2876 segment => obc%segment(n)
2877 if (segment%is_N_or_S .and. segment%Flather)
then 2878 do j=segment%HI%JsdB,segment%HI%JedB ;
do i=segment%HI%isd,segment%HI%ied
2879 bt_obc%vbt_outer(i,j) = segment%normal_vel_bt(i,j)
2880 bt_obc%eta_outer_v(i,j) = segment%eta(i,j)
2895 if (bt_obc%is_alloced)
then 2896 deallocate(bt_obc%Cg_u)
2897 deallocate(bt_obc%H_u)
2898 deallocate(bt_obc%uhbt)
2899 deallocate(bt_obc%ubt_outer)
2900 deallocate(bt_obc%eta_outer_u)
2902 deallocate(bt_obc%Cg_v)
2903 deallocate(bt_obc%H_v)
2904 deallocate(bt_obc%vhbt)
2905 deallocate(bt_obc%vbt_outer)
2906 deallocate(bt_obc%eta_outer_v)
2907 bt_obc%is_alloced = .false.
2916 subroutine btcalc(h, G, GV, CS, h_u, h_v, may_use_default, OBC)
2919 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
2922 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)),
intent(in),
optional :: h_u
2924 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)),
intent(in),
optional :: h_v
2926 logical,
intent(in),
optional :: may_use_default
2936 real :: hatutot(szib_(g))
2937 real :: hatvtot(szi_(g))
2938 real :: Ihatutot(szib_(g))
2939 real :: Ihatvtot(szi_(g))
2948 real :: e_u(szib_(g),szk_(g)+1)
2949 real :: e_v(szi_(g),szk_(g)+1)
2950 real :: D_shallow_u(szi_(g))
2951 real :: D_shallow_v(szib_(g))
2955 logical :: use_default, test_dflt, apply_OBCs
2956 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, i, j, k
2957 integer :: iss, ies, n
2961 if (.not.
associated(cs))
call mom_error(fatal, &
2962 "btcalc: Module MOM_barotropic must be initialized before it is used.")
2963 if (.not.cs%split)
return 2965 use_default = .false.
2966 test_dflt = .false. ;
if (
present(may_use_default)) test_dflt = may_use_default
2969 if (.not.((
present(h_u) .and.
present(h_v)) .or. &
2970 (cs%hvel_scheme ==
harmonic) .or. (cs%hvel_scheme ==
hybrid) .or.&
2971 (cs%hvel_scheme ==
arithmetic))) use_default = .true.
2973 if (.not.((
present(h_u) .and.
present(h_v)) .or. &
2974 (cs%hvel_scheme ==
harmonic) .or. (cs%hvel_scheme ==
hybrid) .or.&
2976 "btcalc: Inconsistent settings of optional arguments and hvel_scheme.")
2979 apply_obcs = .false.
2980 if (
present(obc))
then ;
if (
associated(obc))
then ;
if (obc%OBC_pe)
then 2983 apply_obcs = (obc%number_of_segments > 0)
2984 endif ;
endif ;
endif 2986 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2987 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
2988 h_neglect = gv%H_subroundoff
2996 if (
present(h_u))
then 2997 do i=is-1,ie ; hatutot(i) = h_u(i,j,1) ;
enddo 2998 do k=2,nz ;
do i=is-1,ie
2999 hatutot(i) = hatutot(i) + h_u(i,j,k)
3001 do i=is-1,ie ; ihatutot(i) = g%mask2dCu(i,j) / (hatutot(i) + h_neglect) ;
enddo 3002 do k=1,nz ;
do i=is-1,ie
3003 cs%frhatu(i,j,k) = h_u(i,j,k) * ihatutot(i)
3008 cs%frhatu(i,j,1) = 0.5 * (h(i+1,j,1) + h(i,j,1))
3009 hatutot(i) = cs%frhatu(i,j,1)
3011 do k=2,nz ;
do i=is-1,ie
3012 cs%frhatu(i,j,k) = 0.5 * (h(i+1,j,k) + h(i,j,k))
3013 hatutot(i) = hatutot(i) + cs%frhatu(i,j,k)
3015 elseif (cs%hvel_scheme ==
hybrid .or. use_default)
then 3017 e_u(i,nz+1) = -0.5 * gv%m_to_H * (g%bathyT(i+1,j) + g%bathyT(i,j))
3018 d_shallow_u(i) = -gv%m_to_H * min(g%bathyT(i+1,j), g%bathyT(i,j))
3021 do k=nz,1,-1 ;
do i=is-1,ie
3022 e_u(i,k) = e_u(i,k+1) + 0.5 * (h(i+1,j,k) + h(i,j,k))
3023 h_arith = 0.5 * (h(i+1,j,k) + h(i,j,k))
3024 if (e_u(i,k+1) >= d_shallow_u(i))
then 3025 cs%frhatu(i,j,k) = h_arith
3027 h_harm = (h(i+1,j,k) * h(i,j,k)) / (h_arith + h_neglect)
3028 if (e_u(i,k) <= d_shallow_u(i))
then 3029 cs%frhatu(i,j,k) = h_harm
3031 wt_arith = (e_u(i,k) - d_shallow_u(i)) / (h_arith + h_neglect)
3032 cs%frhatu(i,j,k) = wt_arith*h_arith + (1.0-wt_arith)*h_harm
3035 hatutot(i) = hatutot(i) + cs%frhatu(i,j,k)
3037 elseif (cs%hvel_scheme ==
harmonic)
then 3039 cs%frhatu(i,j,1) = 2.0*(h(i+1,j,1) * h(i,j,1)) / &
3040 ((h(i+1,j,1) + h(i,j,1)) + h_neglect)
3041 hatutot(i) = cs%frhatu(i,j,1)
3043 do k=2,nz ;
do i=is-1,ie
3044 cs%frhatu(i,j,k) = 2.0*(h(i+1,j,k) * h(i,j,k)) / &
3045 ((h(i+1,j,k) + h(i,j,k)) + h_neglect)
3046 hatutot(i) = hatutot(i) + cs%frhatu(i,j,k)
3049 do i=is-1,ie ; ihatutot(i) = g%mask2dCu(i,j) / (hatutot(i) + h_neglect) ;
enddo 3050 do k=1,nz ;
do i=is-1,ie
3051 cs%frhatu(i,j,k) = cs%frhatu(i,j,k) * ihatutot(i)
3059 if (
present(h_v))
then 3060 do i=is,ie ; hatvtot(i) = h_v(i,j,1) ;
enddo 3061 do k=2,nz ;
do i=is,ie
3062 hatvtot(i) = hatvtot(i) + h_v(i,j,k)
3064 do i=is,ie ; ihatvtot(i) = g%mask2dCv(i,j) / (hatvtot(i) + h_neglect) ;
enddo 3065 do k=1,nz ;
do i=is,ie
3066 cs%frhatv(i,j,k) = h_v(i,j,k) * ihatvtot(i)
3071 cs%frhatv(i,j,1) = 0.5 * (h(i,j+1,1) + h(i,j,1))
3072 hatvtot(i) = cs%frhatv(i,j,1)
3074 do k=2,nz ;
do i=is,ie
3075 cs%frhatv(i,j,k) = 0.5 * (h(i,j+1,k) + h(i,j,k))
3076 hatvtot(i) = hatvtot(i) + cs%frhatv(i,j,k)
3078 elseif (cs%hvel_scheme ==
hybrid .or. use_default)
then 3080 e_v(i,nz+1) = -0.5 * gv%m_to_H * (g%bathyT(i,j+1) + g%bathyT(i,j))
3081 d_shallow_v(i) = -gv%m_to_H * min(g%bathyT(i,j+1), g%bathyT(i,j))
3084 do k=nz,1,-1 ;
do i=is,ie
3085 e_v(i,k) = e_v(i,k+1) + 0.5 * (h(i,j+1,k) + h(i,j,k))
3086 h_arith = 0.5 * (h(i,j+1,k) + h(i,j,k))
3087 if (e_v(i,k+1) >= d_shallow_v(i))
then 3088 cs%frhatv(i,j,k) = h_arith
3090 h_harm = (h(i,j+1,k) * h(i,j,k)) / (h_arith + h_neglect)
3091 if (e_v(i,k) <= d_shallow_v(i))
then 3092 cs%frhatv(i,j,k) = h_harm
3094 wt_arith = (e_v(i,k) - d_shallow_v(i)) / (h_arith + h_neglect)
3095 cs%frhatv(i,j,k) = wt_arith*h_arith + (1.0-wt_arith)*h_harm
3098 hatvtot(i) = hatvtot(i) + cs%frhatv(i,j,k)
3100 elseif (cs%hvel_scheme ==
harmonic)
then 3102 cs%frhatv(i,j,1) = 2.0*(h(i,j+1,1) * h(i,j,1)) / &
3103 ((h(i,j+1,1) + h(i,j,1)) + h_neglect)
3104 hatvtot(i) = cs%frhatv(i,j,1)
3106 do k=2,nz ;
do i=is,ie
3107 cs%frhatv(i,j,k) = 2.0*(h(i,j+1,k) * h(i,j,k)) / &
3108 ((h(i,j+1,k) + h(i,j,k)) + h_neglect)
3109 hatvtot(i) = hatvtot(i) + cs%frhatv(i,j,k)
3112 do i=is,ie ; ihatvtot(i) = g%mask2dCv(i,j) / (hatvtot(i) + h_neglect) ;
enddo 3113 do k=1,nz ;
do i=is,ie
3114 cs%frhatv(i,j,k) = cs%frhatv(i,j,k) * ihatvtot(i)
3119 if (apply_obcs)
then ;
do n=1,obc%number_of_segments
3120 if (.not. obc%segment(n)%on_pe) cycle
3122 j = obc%segment(n)%HI%JsdB
3123 if ((j >= js-1) .and. (j <= je))
then 3124 iss = max(is,obc%segment(n)%HI%isd) ; ies = min(ie,obc%segment(n)%HI%ied)
3125 do i=iss,ies ; hatvtot(i) = h(i,j,1) ;
enddo 3126 do k=2,nz ;
do i=iss,ies
3127 hatvtot(i) = hatvtot(i) + h(i,j,k)
3130 ihatvtot(i) = g%mask2dCv(i,j) / (hatvtot(i) + h_neglect)
3132 do k=1,nz ;
do i=iss,ies
3133 cs%frhatv(i,j,k) = h(i,j,k) * ihatvtot(i)
3137 j = obc%segment(n)%HI%JsdB
3138 if ((j >= js-1) .and. (j <= je))
then 3139 iss = max(is,obc%segment(n)%HI%isd) ; ies = min(ie,obc%segment(n)%HI%ied)
3140 do i=iss,ies ; hatvtot(i) = h(i,j+1,1) ;
enddo 3141 do k=2,nz ;
do i=iss,ies
3142 hatvtot(i) = hatvtot(i) + h(i,j+1,k)
3145 ihatvtot(i) = g%mask2dCv(i,j) / (hatvtot(i) + h_neglect)
3147 do k=1,nz ;
do i=iss,ies
3148 cs%frhatv(i,j,k) = h(i,j+1,k) * ihatvtot(i)
3151 elseif (obc%segment(n)%direction == obc_direction_e)
then 3152 i = obc%segment(n)%HI%IsdB
3153 if ((i >= is-1) .and. (i <= ie))
then 3154 do j = max(js,obc%segment(n)%HI%jsd), min(je,obc%segment(n)%HI%jed)
3156 do k=2,nz ; htot = htot + h(i,j,k) ;
enddo 3157 ihtot = g%mask2dCu(i,j) / (htot + h_neglect)
3158 do k=1,nz ; cs%frhatu(i,j,k) = h(i,j,k) * ihtot ;
enddo 3161 elseif (obc%segment(n)%direction == obc_direction_w)
then 3162 i = obc%segment(n)%HI%IsdB
3163 if ((i >= is-1) .and. (i <= ie))
then 3164 do j = max(js,obc%segment(n)%HI%jsd), min(je,obc%segment(n)%HI%jed)
3166 do k=2,nz ; htot = htot + h(i+1,j,k) ;
enddo 3167 ihtot = g%mask2dCu(i,j) / (htot + h_neglect)
3168 do k=1,nz ; cs%frhatu(i,j,k) = h(i+1,j,k) * ihtot ;
enddo 3172 call mom_error(fatal,
"btcalc encountered and OBC segment of indeterminate direction.")
3177 call uvchksum(
"btcalc frhat[uv]", cs%frhatu, cs%frhatv, g%HI, 0, .true., .true.)
3178 if (
present(h_u) .and.
present(h_v)) &
3179 call uvchksum(
"btcalc h_[uv]", h_u, h_v, g%HI, 0, .true., .true., scale=gv%H_to_m)
3180 call hchksum(h,
"btcalc h",g%HI, haloshift=1, scale=gv%H_to_m)
3187 real,
intent(in) :: u
3193 elseif (u < btc%uBT_EE)
then 3194 uhbt = (u - btc%uBT_EE) * btc%FA_u_EE + btc%uh_EE
3195 elseif (u < 0.0)
then 3196 uhbt = u * (btc%FA_u_E0 + btc%uh_crvE * u**2)
3197 elseif (u <= btc%uBT_WW)
then 3198 uhbt = u * (btc%FA_u_W0 + btc%uh_crvW * u**2)
3200 uhbt = (u - btc%uBT_WW) * btc%FA_u_WW + btc%uh_WW
3206 function uhbt_to_ubt(uhbt, BTC, guess)
result(ubt)
3207 real,
intent(in) :: uhbt
3212 real,
optional,
intent(in) :: guess
3217 real :: ubt_min, ubt_max, uhbt_err, derr_du
3218 real :: uherr_min, uherr_max
3219 real,
parameter :: tol = 1.0e-10
3221 real,
parameter :: vs1 = 1.25
3222 real,
parameter :: vs2 = 2.0
3224 integer :: itt, max_itt = 20
3227 if (uhbt == 0.0)
then 3229 elseif (uhbt < btc%uh_EE)
then 3230 ubt = btc%uBT_EE + (uhbt - btc%uh_EE) / btc%FA_u_EE
3231 elseif (uhbt < 0.0)
then 3234 ubt_min = btc%uBT_EE ; uherr_min = btc%uh_EE - uhbt
3235 ubt_max = 0.0 ; uherr_max = -uhbt
3237 ubt = btc%uBT_EE * (uhbt / btc%uh_EE)
3239 uhbt_err = ubt * (btc%FA_u_E0 + btc%uh_crvE * ubt**2) - uhbt
3241 if (abs(uhbt_err) < tol*abs(uhbt))
exit 3242 if (uhbt_err > 0.0)
then ; ubt_max = ubt ; uherr_max = uhbt_err ;
endif 3243 if (uhbt_err < 0.0)
then ; ubt_min = ubt ; uherr_min = uhbt_err ;
endif 3245 derr_du = btc%FA_u_E0 + 3.0 * btc%uh_crvE * ubt**2
3246 if ((uhbt_err >= derr_du*(ubt - ubt_min)) .or. &
3247 (-uhbt_err >= derr_du*(ubt_max - ubt)) .or. (derr_du <= 0.0))
then 3249 ubt = ubt_max + (ubt_min-ubt_max) * (uherr_max / (uherr_max-uherr_min))
3251 ubt = ubt - uhbt_err / derr_du
3252 if (abs(uhbt_err) < (0.01*tol)*abs(ubt_min*derr_du))
exit 3255 elseif (uhbt <= btc%uh_WW)
then 3257 ubt_min = 0.0 ; uherr_min = -uhbt
3258 ubt_max = btc%uBT_WW ; uherr_max = btc%uh_WW - uhbt
3260 ubt = btc%uBT_WW * (uhbt / btc%uh_WW)
3262 uhbt_err = ubt * (btc%FA_u_W0 + btc%uh_crvW * ubt**2) - uhbt
3264 if (abs(uhbt_err) < tol*abs(uhbt))
exit 3265 if (uhbt_err > 0.0)
then ; ubt_max = ubt ; uherr_max = uhbt_err ;
endif 3266 if (uhbt_err < 0.0)
then ; ubt_min = ubt ; uherr_min = uhbt_err ;
endif 3268 derr_du = btc%FA_u_W0 + 3.0 * btc%uh_crvW * ubt**2
3269 if ((uhbt_err >= derr_du*(ubt - ubt_min)) .or. &
3270 (-uhbt_err >= derr_du*(ubt_max - ubt)) .or. (derr_du <= 0.0))
then 3272 ubt = ubt_min + (ubt_max-ubt_min) * (-uherr_min / (uherr_max-uherr_min))
3274 ubt = ubt - uhbt_err / derr_du
3275 if (abs(uhbt_err) < (0.01*tol)*(ubt_max*derr_du))
exit 3279 ubt = btc%uBT_WW + (uhbt - btc%uh_WW) / btc%FA_u_WW
3282 if (
present(guess))
then 3283 dvel = abs(ubt) - vs1*abs(guess)
3284 if (dvel > 0.0)
then 3285 if (dvel < 40.0 * (abs(guess)*(vs2-vs1)) )
then 3286 vsr = vs2 - (vs2-vs1) * exp(-dvel / (abs(guess)*(vs2-vs1)))
3290 ubt = sign(vsr * guess, ubt)
3298 real,
intent(in) :: v
3304 elseif (v < btc%vBT_NN)
then 3305 vhbt = (v - btc%vBT_NN) * btc%FA_v_NN + btc%vh_NN
3306 elseif (v < 0.0)
then 3307 vhbt = v * (btc%FA_v_N0 + btc%vh_crvN * v**2)
3308 elseif (v <= btc%vBT_SS)
then 3309 vhbt = v * (btc%FA_v_S0 + btc%vh_crvS * v**2)
3311 vhbt = (v - btc%vBT_SS) * btc%FA_v_SS + btc%vh_SS
3317 function vhbt_to_vbt(vhbt, BTC, guess)
result(vbt)
3318 real,
intent(in) :: vhbt
3323 real,
optional,
intent(in) :: guess
3328 real :: vbt_min, vbt_max, vhbt_err, derr_dv
3329 real :: vherr_min, vherr_max
3330 real,
parameter :: tol = 1.0e-10
3332 real,
parameter :: vs1 = 1.25
3333 real,
parameter :: vs2 = 2.0
3335 integer :: itt, max_itt = 20
3338 if (vhbt == 0.0)
then 3340 elseif (vhbt < btc%vh_NN)
then 3341 vbt = btc%vBT_NN + (vhbt - btc%vh_NN) / btc%FA_v_NN
3342 elseif (vhbt < 0.0)
then 3345 vbt_min = btc%vBT_NN ; vherr_min = btc%vh_NN - vhbt
3346 vbt_max = 0.0 ; vherr_max = -vhbt
3348 vbt = btc%vBT_NN * (vhbt / btc%vh_NN)
3350 vhbt_err = vbt * (btc%FA_v_N0 + btc%vh_crvN * vbt**2) - vhbt
3352 if (abs(vhbt_err) < tol*abs(vhbt))
exit 3353 if (vhbt_err > 0.0)
then ; vbt_max = vbt ; vherr_max = vhbt_err ;
endif 3354 if (vhbt_err < 0.0)
then ; vbt_min = vbt ; vherr_min = vhbt_err ;
endif 3356 derr_dv = btc%FA_v_N0 + 3.0 * btc%vh_crvN * vbt**2
3357 if ((vhbt_err >= derr_dv*(vbt - vbt_min)) .or. &
3358 (-vhbt_err >= derr_dv*(vbt_max - vbt)) .or. (derr_dv <= 0.0))
then 3360 vbt = vbt_max + (vbt_min-vbt_max) * (vherr_max / (vherr_max-vherr_min))
3362 vbt = vbt - vhbt_err / derr_dv
3363 if (abs(vhbt_err) < (0.01*tol)*abs(derr_dv*vbt_min))
exit 3366 elseif (vhbt <= btc%vh_SS)
then 3368 vbt_min = 0.0 ; vherr_min = -vhbt
3369 vbt_max = btc%vBT_SS ; vherr_max = btc%vh_SS - vhbt
3371 vbt = btc%vBT_SS * (vhbt / btc%vh_SS)
3373 vhbt_err = vbt * (btc%FA_v_S0 + btc%vh_crvS * vbt**2) - vhbt
3375 if (abs(vhbt_err) < tol*abs(vhbt))
exit 3376 if (vhbt_err > 0.0)
then ; vbt_max = vbt ; vherr_max = vhbt_err ;
endif 3377 if (vhbt_err < 0.0)
then ; vbt_min = vbt ; vherr_min = vhbt_err ;
endif 3379 derr_dv = btc%FA_v_S0 + 3.0 * btc%vh_crvS * vbt**2
3380 if ((vhbt_err >= derr_dv*(vbt - vbt_min)) .or. &
3381 (-vhbt_err >= derr_dv*(vbt_max - vbt)) .or. (derr_dv <= 0.0))
then 3383 vbt = vbt_min + (vbt_max-vbt_min) * (-vherr_min / (vherr_max-vherr_min))
3385 vbt = vbt - vhbt_err / derr_dv
3386 if (abs(vhbt_err) < (0.01*tol)*(vbt_max*derr_dv))
exit 3390 vbt = btc%vBT_SS + (vhbt - btc%vh_SS) / btc%FA_v_SS
3393 if (
present(guess))
then 3394 dvel = abs(vbt) - vs1*abs(guess)
3395 if (dvel > 0.0)
then 3396 if (dvel < 40.0 * (abs(guess)*(vs2-vs1)) )
then 3397 vsr = vs2 - (vs2-vs1) * exp(-dvel / (abs(guess)*(vs2-vs1)))
3401 vbt = sign(guess * vsr, vbt)
3422 integer,
optional,
intent(in) :: halo
3425 real,
dimension(SZIBW_(MS),SZJW_(MS)) :: &
3426 u_polarity, uBT_EE, uBT_WW, FA_u_EE, FA_u_E0, FA_u_W0, FA_u_WW
3427 real,
dimension(SZIW_(MS),SZJBW_(MS)) :: &
3428 v_polarity, vBT_NN, vBT_SS, FA_v_NN, FA_v_N0, FA_v_S0, FA_v_SS
3429 real,
parameter :: C1_3 = 1.0/3.0
3430 integer :: i, j, is, ie, js, je, hs
3431 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3432 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3439 do j=js-hs,je+hs ;
do i=is-hs-1,ie+hs
3440 u_polarity(i,j) = 1.0
3441 ubt_ee(i,j) = 0.0 ; ubt_ww(i,j) = 0.0
3442 fa_u_ee(i,j) = 0.0 ; fa_u_e0(i,j) = 0.0 ; fa_u_w0(i,j) = 0.0 ; fa_u_ww(i,j) = 0.0
3445 do j=js-hs-1,je+hs ;
do i=is-hs,ie+hs
3446 v_polarity(i,j) = 1.0
3447 vbt_nn(i,j) = 0.0 ; vbt_ss(i,j) = 0.0
3448 fa_v_nn(i,j) = 0.0 ; fa_v_n0(i,j) = 0.0 ; fa_v_s0(i,j) = 0.0 ; fa_v_ss(i,j) = 0.0
3451 do j=js,je;
do i=is-1,ie
3452 ubt_ee(i,j) = bt_cont%uBT_EE(i,j) ; ubt_ww(i,j) = bt_cont%uBT_WW(i,j)
3453 fa_u_ee(i,j) = bt_cont%FA_u_EE(i,j) ; fa_u_e0(i,j) = bt_cont%FA_u_E0(i,j)
3454 fa_u_w0(i,j) = bt_cont%FA_u_W0(i,j) ; fa_u_ww(i,j) = bt_cont%FA_u_WW(i,j)
3457 do j=js-1,je;
do i=is,ie
3458 vbt_nn(i,j) = bt_cont%vBT_NN(i,j) ; vbt_ss(i,j) = bt_cont%vBT_SS(i,j)
3459 fa_v_nn(i,j) = bt_cont%FA_v_NN(i,j) ; fa_v_n0(i,j) = bt_cont%FA_v_N0(i,j)
3460 fa_v_s0(i,j) = bt_cont%FA_v_S0(i,j) ; fa_v_ss(i,j) = bt_cont%FA_v_SS(i,j)
3467 call create_group_pass(bt_cont%pass_polarity_BT, u_polarity, v_polarity, bt_domain)
3471 call create_group_pass(bt_cont%pass_FA_uv, fa_u_ee, fa_v_nn, bt_domain, to_all+scalar_pair)
3472 call create_group_pass(bt_cont%pass_FA_uv, fa_u_e0, fa_v_n0, bt_domain, to_all+scalar_pair)
3473 call create_group_pass(bt_cont%pass_FA_uv, fa_u_w0, fa_v_s0, bt_domain, to_all+scalar_pair)
3474 call create_group_pass(bt_cont%pass_FA_uv, fa_u_ww, fa_v_ss, bt_domain, to_all+scalar_pair)
3477 call do_group_pass(bt_cont%pass_polarity_BT, bt_domain)
3478 call do_group_pass(bt_cont%pass_FA_uv, bt_domain)
3487 do j=js-hs,je+hs ;
do i=is-hs-1,ie+hs
3488 btcl_u(i,j)%FA_u_EE = fa_u_ee(i,j) ; btcl_u(i,j)%FA_u_E0 = fa_u_e0(i,j)
3489 btcl_u(i,j)%FA_u_W0 = fa_u_w0(i,j) ; btcl_u(i,j)%FA_u_WW = fa_u_ww(i,j)
3490 btcl_u(i,j)%uBT_EE = ubt_ee(i,j) ; btcl_u(i,j)%uBT_WW = ubt_ww(i,j)
3492 if (u_polarity(i,j) < 0.0)
then 3493 call swap(btcl_u(i,j)%FA_u_EE, btcl_u(i,j)%FA_u_WW)
3494 call swap(btcl_u(i,j)%FA_u_E0, btcl_u(i,j)%FA_u_W0)
3495 call swap(btcl_u(i,j)%uBT_EE, btcl_u(i,j)%uBT_WW)
3498 btcl_u(i,j)%uh_EE = btcl_u(i,j)%uBT_EE * &
3499 (c1_3 * (2.0*btcl_u(i,j)%FA_u_E0 + btcl_u(i,j)%FA_u_EE))
3500 btcl_u(i,j)%uh_WW = btcl_u(i,j)%uBT_WW * &
3501 (c1_3 * (2.0*btcl_u(i,j)%FA_u_W0 + btcl_u(i,j)%FA_u_WW))
3503 btcl_u(i,j)%uh_crvE = 0.0 ; btcl_u(i,j)%uh_crvW = 0.0
3504 if (abs(btcl_u(i,j)%uBT_WW) > 0.0) btcl_u(i,j)%uh_crvW = &
3505 (c1_3 * (btcl_u(i,j)%FA_u_WW - btcl_u(i,j)%FA_u_W0)) / btcl_u(i,j)%uBT_WW**2
3506 if (abs(btcl_u(i,j)%uBT_EE) > 0.0) btcl_u(i,j)%uh_crvE = &
3507 (c1_3 * (btcl_u(i,j)%FA_u_EE - btcl_u(i,j)%FA_u_E0)) / btcl_u(i,j)%uBT_EE**2
3510 do j=js-hs-1,je+hs ;
do i=is-hs,ie+hs
3511 btcl_v(i,j)%FA_v_NN = fa_v_nn(i,j) ; btcl_v(i,j)%FA_v_N0 = fa_v_n0(i,j)
3512 btcl_v(i,j)%FA_v_S0 = fa_v_s0(i,j) ; btcl_v(i,j)%FA_v_SS = fa_v_ss(i,j)
3513 btcl_v(i,j)%vBT_NN = vbt_nn(i,j) ; btcl_v(i,j)%vBT_SS = vbt_ss(i,j)
3515 if (v_polarity(i,j) < 0.0)
then 3516 call swap(btcl_v(i,j)%FA_v_NN, btcl_v(i,j)%FA_v_SS)
3517 call swap(btcl_v(i,j)%FA_v_N0, btcl_v(i,j)%FA_v_S0)
3518 call swap(btcl_v(i,j)%vBT_NN, btcl_v(i,j)%vBT_SS)
3521 btcl_v(i,j)%vh_NN = btcl_v(i,j)%vBT_NN * &
3522 (c1_3 * (2.0*btcl_v(i,j)%FA_v_N0 + btcl_v(i,j)%FA_v_NN))
3523 btcl_v(i,j)%vh_SS = btcl_v(i,j)%vBT_SS * &
3524 (c1_3 * (2.0*btcl_v(i,j)%FA_v_S0 + btcl_v(i,j)%FA_v_SS))
3526 btcl_v(i,j)%vh_crvN = 0.0 ; btcl_v(i,j)%vh_crvS = 0.0
3527 if (abs(btcl_v(i,j)%vBT_SS) > 0.0) btcl_v(i,j)%vh_crvS = &
3528 (c1_3 * (btcl_v(i,j)%FA_v_SS - btcl_v(i,j)%FA_v_S0)) / btcl_v(i,j)%vBT_SS**2
3529 if (abs(btcl_v(i,j)%vBT_NN) > 0.0) btcl_v(i,j)%vh_crvN = &
3530 (c1_3 * (btcl_v(i,j)%FA_v_NN - btcl_v(i,j)%FA_v_N0)) / btcl_v(i,j)%vBT_NN**2
3541 real,
dimension(SZIBW_(MS),SZJW_(MS)), &
3543 real,
dimension(SZIBW_(MS),SZJW_(MS)), &
3545 real,
dimension(SZIW_(MS),SZJBW_(MS)), &
3547 real,
dimension(SZIW_(MS),SZJBW_(MS)), &
3550 intent(out) :: BTCL_u
3552 intent(out) :: BTCL_v
3554 integer,
optional,
intent(in) :: halo
3557 real,
dimension(SZIBW_(MS),SZJW_(MS)) :: &
3558 u_polarity, uBT_EE, uBT_WW, FA_u_EE, FA_u_E0, FA_u_W0, FA_u_WW
3559 real,
dimension(SZIW_(MS),SZJBW_(MS)) :: &
3560 v_polarity, vBT_NN, vBT_SS, FA_v_NN, FA_v_N0, FA_v_S0, FA_v_SS
3561 real,
parameter :: C1_3 = 1.0/3.0
3562 integer :: i, j, is, ie, js, je, hs
3563 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3564 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3567 do j=js-hs,je+hs ;
do i=is-hs-1,ie+hs
3568 if ((ubt(i,j) > btcl_u(i,j)%uBT_WW) .and. (uhbt(i,j) > btcl_u(i,j)%uh_WW))
then 3570 btcl_u(i,j)%ubt_WW = ubt(i,j)
3571 if (3.0*uhbt(i,j) < 2.0*ubt(i,j) * btcl_u(i,j)%FA_u_W0)
then 3573 btcl_u(i,j)%uh_crvW = (uhbt(i,j) - ubt(i,j) * btcl_u(i,j)%FA_u_W0) / ubt(i,j)**3
3575 btcl_u(i,j)%FA_u_W0 = 1.5*uhbt(i,j) / ubt(i,j)
3576 btcl_u(i,j)%uh_crvW = -0.5*uhbt(i,j) / ubt(i,j)**3
3578 btcl_u(i,j)%uh_WW = uhbt(i,j)
3581 elseif ((ubt(i,j) < btcl_u(i,j)%uBT_EE) .and. (uhbt(i,j) < btcl_u(i,j)%uh_EE))
then 3583 btcl_u(i,j)%ubt_EE = ubt(i,j)
3584 if (3.0*uhbt(i,j) < 2.0*ubt(i,j) * btcl_u(i,j)%FA_u_E0)
then 3586 btcl_u(i,j)%uh_crvE = (uhbt(i,j) - ubt(i,j) * btcl_u(i,j)%FA_u_E0) / ubt(i,j)**3
3588 btcl_u(i,j)%FA_u_E0 = 1.5*uhbt(i,j) / ubt(i,j)
3589 btcl_u(i,j)%uh_crvE = -0.5*uhbt(i,j) / ubt(i,j)**3
3591 btcl_u(i,j)%uh_EE = uhbt(i,j)
3597 do j=js-hs-1,je+hs ;
do i=is-hs,ie+hs
3598 if ((vbt(i,j) > btcl_v(i,j)%vBT_SS) .and. (vhbt(i,j) > btcl_v(i,j)%vh_SS))
then 3600 btcl_v(i,j)%vbt_SS = vbt(i,j)
3601 if (3.0*vhbt(i,j) < 2.0*vbt(i,j) * btcl_v(i,j)%FA_v_S0)
then 3603 btcl_v(i,j)%vh_crvS = (vhbt(i,j) - vbt(i,j) * btcl_v(i,j)%FA_v_S0) / vbt(i,j)**3
3605 btcl_v(i,j)%FA_v_S0 = 1.5*vhbt(i,j) / vbt(i,j)
3606 btcl_v(i,j)%vh_crvS = -0.5*vhbt(i,j) / vbt(i,j)**3
3608 btcl_v(i,j)%vh_SS = vhbt(i,j)
3611 elseif ((vbt(i,j) < btcl_v(i,j)%vBT_NN) .and. (vhbt(i,j) < btcl_v(i,j)%vh_NN))
then 3613 btcl_v(i,j)%vbt_NN = vbt(i,j)
3614 if (3.0*vhbt(i,j) < 2.0*vbt(i,j) * btcl_v(i,j)%FA_v_N0)
then 3616 btcl_v(i,j)%vh_crvN = (vhbt(i,j) - vbt(i,j) * btcl_v(i,j)%FA_v_N0) / vbt(i,j)**3
3618 btcl_v(i,j)%FA_v_N0 = 1.5*vhbt(i,j) / vbt(i,j)
3619 btcl_v(i,j)%vh_crvN = -0.5*vhbt(i,j) / vbt(i,j)**3
3621 btcl_v(i,j)%vh_NN = vhbt(i,j)
3636 real,
dimension(MS%isdw-1:MS%iedw,MS%jsdw:MS%jedw),
intent(out) :: Datu
3637 real,
dimension(MS%isdw:MS%iedw,MS%jsdw-1:MS%jedw),
intent(out) :: Datv
3639 integer,
optional,
intent(in) :: halo
3640 logical,
optional,
intent(in) :: maximize
3644 integer :: i, j, is, ie, js, je, hs
3645 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3646 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3647 find_max = .false. ;
if (
present(maximize)) find_max = maximize
3650 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3651 datu(i,j) = max(bt_cont%FA_u_EE(i,j), bt_cont%FA_u_E0(i,j), &
3652 bt_cont%FA_u_W0(i,j), bt_cont%FA_u_WW(i,j))
3654 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3655 datv(i,j) = max(bt_cont%FA_v_NN(i,j), bt_cont%FA_v_N0(i,j), &
3656 bt_cont%FA_v_S0(i,j), bt_cont%FA_v_SS(i,j))
3659 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3660 datu(i,j) = 0.5 * (bt_cont%FA_u_E0(i,j) + bt_cont%FA_u_W0(i,j))
3662 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3663 datv(i,j) = 0.5 * (bt_cont%FA_v_N0(i,j) + bt_cont%FA_v_S0(i,j))
3669 subroutine swap(a,b)
3670 real,
intent(inout) :: a, b
3672 tmp = a ; a = b ; b = tmp
3677 subroutine find_face_areas(Datu, Datv, G, GV, CS, MS, eta, halo, add_max)
3680 real,
dimension(MS%isdw-1:MS%iedw,MS%jsdw:MS%jedw),
intent(out) :: Datu
3682 real,
dimension(MS%isdw:MS%iedw,MS%jsdw-1:MS%jedw),
intent(out) :: Datv
3688 real,
dimension(MS%isdw:MS%iedw,MS%jsdw:MS%jedw),
optional,
intent(in) :: eta
3691 integer,
optional,
intent(in) :: halo
3692 real,
optional,
intent(in) :: add_max
3699 integer :: i, j, is, ie, js, je, hs
3700 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3701 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3705 if (
present(eta))
then 3707 if (gv%Boussinesq)
then 3709 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3710 h1 = cs%bathyT(i,j)*gv%m_to_H + eta(i,j) ; h2 = cs%bathyT(i+1,j)*gv%m_to_H + eta(i+1,j)
3711 datu(i,j) = 0.0 ;
if ((h1 > 0.0) .and. (h2 > 0.0)) &
3712 datu(i,j) = cs%dy_Cu(i,j) * (2.0 * h1 * h2) / (h1 + h2)
3716 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3717 h1 = cs%bathyT(i,j)*gv%m_to_H + eta(i,j) ; h2 = cs%bathyT(i,j+1)*gv%m_to_H + eta(i,j+1)
3718 datv(i,j) = 0.0 ;
if ((h1 > 0.0) .and. (h2 > 0.0)) &
3719 datv(i,j) = cs%dx_Cv(i,j) * (2.0 * h1 * h2) / (h1 + h2)
3724 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3725 datu(i,j) = 0.0 ;
if ((eta(i,j) > 0.0) .and. (eta(i+1,j) > 0.0)) &
3726 datu(i,j) = cs%dy_Cu(i,j) * (2.0 * eta(i,j) * eta(i+1,j)) / &
3727 (eta(i,j) + eta(i+1,j))
3731 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3732 datv(i,j) = 0.0 ;
if ((eta(i,j) > 0.0) .and. (eta(i,j+1) > 0.0)) &
3733 datv(i,j) = cs%dx_Cv(i,j) * (2.0 * eta(i,j) * eta(i,j+1)) / &
3734 (eta(i,j) + eta(i,j+1))
3738 elseif (
present(add_max))
then 3740 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3741 datu(i,j) = cs%dy_Cu(i,j) * gv%m_to_H * &
3742 (max(cs%bathyT(i+1,j), cs%bathyT(i,j)) + add_max)
3745 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3746 datv(i,j) = cs%dx_Cv(i,j) * gv%m_to_H * &
3747 (max(cs%bathyT(i,j+1), cs%bathyT(i,j)) + add_max)
3751 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3754 if (cs%bathyT(i+1,j)+cs%bathyT(i,j)>0.) &
3755 datu(i,j) = 2.0*cs%dy_Cu(i,j) * gv%m_to_H * &
3756 (cs%bathyT(i+1,j) * cs%bathyT(i,j)) / &
3757 (cs%bathyT(i+1,j) + cs%bathyT(i,j))
3760 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3763 if (cs%bathyT(i,j+1)+cs%bathyT(i,j)>0.) &
3764 datv(i,j) = 2.0*cs%dx_Cv(i,j) * gv%m_to_H * &
3765 (cs%bathyT(i,j+1) * cs%bathyT(i,j)) / &
3766 (cs%bathyT(i,j+1) + cs%bathyT(i,j))
3777 subroutine bt_mass_source(h, eta, fluxes, set_cor, dt_therm, dt_since_therm, &
3781 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
3782 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: eta
3783 type(
forcing),
intent(in) :: fluxes
3785 logical,
intent(in) :: set_cor
3789 real,
intent(in) :: dt_therm
3790 real,
intent(in) :: dt_since_therm
3796 real :: h_tot(szi_(g))
3797 real :: eta_h(szi_(g))
3803 integer :: is, ie, js, je, nz, i, j, k
3804 real,
parameter :: frac_cor = 0.25
3805 real,
parameter :: slow_rate = 0.125
3807 if (.not.
associated(cs))
call mom_error(fatal,
"bt_mass_source: "// &
3808 "Module MOM_barotropic must be initialized before it is used.")
3809 if (.not.cs%split)
return 3811 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3817 do i=is,ie ; h_tot(i) = h(i,j,1) ;
enddo 3818 if (gv%Boussinesq)
then 3819 do i=is,ie ; eta_h(i) = h(i,j,1) - g%bathyT(i,j)*gv%m_to_H ;
enddo 3821 do i=is,ie ; eta_h(i) = h(i,j,1) ;
enddo 3823 do k=2,nz ;
do i=is,ie
3824 eta_h(i) = eta_h(i) + h(i,j,k)
3825 h_tot(i) = h_tot(i) + h(i,j,k)
3829 do i=is,ie ; cs%eta_source(i,j) = 0.0 ;
enddo 3830 if (cs%eta_source_limit > 0.0)
then 3831 limit_dt = cs%eta_source_limit/dt_therm
3832 if (
associated(fluxes%lprec))
then ;
do i=is,ie
3833 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%lprec(i,j)
3835 if (
associated(fluxes%fprec))
then ;
do i=is,ie
3836 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%fprec(i,j)
3838 if (
associated(fluxes%vprec))
then ;
do i=is,ie
3839 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%vprec(i,j)
3841 if (
associated(fluxes%lrunoff))
then ;
do i=is,ie
3842 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%lrunoff(i,j)
3844 if (
associated(fluxes%frunoff))
then ;
do i=is,ie
3845 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%frunoff(i,j)
3847 if (
associated(fluxes%evap))
then ;
do i=is,ie
3848 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%evap(i,j)
3851 cs%eta_source(i,j) = cs%eta_source(i,j)*gv%kg_m2_to_H
3852 if (abs(cs%eta_source(i,j)) > limit_dt * h_tot(i))
then 3853 cs%eta_source(i,j) = sign(limit_dt * h_tot(i), cs%eta_source(i,j))
3861 d_eta = eta_h(i) - (eta(i,j) - dt_since_therm*cs%eta_source(i,j))
3862 cs%eta_cor(i,j) = d_eta
3866 d_eta = eta_h(i) - (eta(i,j) - dt_since_therm*cs%eta_source(i,j))
3867 cs%eta_cor(i,j) = cs%eta_cor(i,j) + d_eta
3877 subroutine barotropic_init(u, v, h, eta, Time, G, GV, param_file, diag, CS, &
3878 restart_CS, BT_cont, tides_CSp)
3881 real,
intent(in),
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u
3882 real,
intent(in),
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v
3883 real,
intent(in),
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h
3884 real,
intent(in),
dimension(SZI_(G),SZJ_(G)) :: eta
3886 type(time_type),
target,
intent(in) :: Time
3888 type(
diag_ctrl),
target,
intent(inout) :: diag
3900 #include "version_variable.h" 3902 character(len=40) :: mdl =
"MOM_barotropic" 3903 real :: Datu(szibs_(g),szj_(g)), Datv(szi_(g),szjbs_(g))
3904 real :: gtot_estimate
3909 type(group_pass_type) :: pass_static_data, pass_q_D_Cor
3910 type(group_pass_type) :: pass_bt_hbt_btav, pass_a_polarity
3911 logical :: apply_bt_drag, use_BT_cont_type
3912 character(len=48) :: thickness_units, flux_units
3913 character*(40) :: hvel_str
3914 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
3915 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
3916 integer :: isdw, iedw, jsdw, jedw
3918 integer :: wd_halos(2), bt_halo_sz
3919 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3920 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
3921 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3922 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
3923 ms%isdw = g%isd ; ms%iedw = g%ied ; ms%jsdw = g%jsd ; ms%jedw = g%jed
3925 if (cs%module_is_initialized)
then 3926 call mom_error(warning,
"barotropic_init called with a control structure "// &
3927 "that has already been initialized.")
3930 cs%module_is_initialized = .true.
3932 cs%diag => diag ; cs%Time => time
3933 if (
present(tides_csp))
then 3934 if (
associated(tides_csp)) cs%tides_CSp => tides_csp
3939 call get_param(param_file, mdl,
"SPLIT", cs%split, &
3940 "Use the split time stepping if true.", default=.true.)
3941 if (.not.cs%split)
return 3943 call get_param(param_file, mdl,
"BOUND_BT_CORRECTION", cs%bound_BT_corr, &
3944 "If true, the corrective pseudo mass-fluxes into the \n"//&
3945 "barotropic solver are limited to values that require \n"//&
3946 "less than maxCFL_BT_cont to be accommodated.",default=.false.)
3947 call get_param(param_file, mdl,
"BT_CONT_CORR_BOUNDS", cs%BT_cont_bounds, &
3948 "If true, and BOUND_BT_CORRECTION is true, use the \n"//&
3949 "BT_cont_type variables to set limits determined by \n"//&
3950 "MAXCFL_BT_CONT on the CFL number of the velocites \n"//&
3951 "that are likely to be driven by the corrective mass fluxes.", &
3953 call get_param(param_file, mdl,
"ADJUST_BT_CONT", cs%adjust_BT_cont, &
3954 "If true, adjust the curve fit to the BT_cont type \n"//&
3955 "that is used by the barotropic solver to match the \n"//&
3956 "transport about which the flow is being linearized.", default=.false.)
3957 call get_param(param_file, mdl,
"GRADUAL_BT_ICS", cs%gradual_BT_ICs, &
3958 "If true, adjust the initial conditions for the \n"//&
3959 "barotropic solver to the values from the layered \n"//&
3960 "solution over a whole timestep instead of instantly. \n"//&
3961 "This is a decent approximation to the inclusion of \n"//&
3962 "sum(u dh_dt) while also correcting for truncation errors.", &
3964 call get_param(param_file, mdl,
"BT_USE_VISC_REM_U_UH0", cs%visc_rem_u_uh0, &
3965 "If true, use the viscous remnants when estimating the \n"//&
3966 "barotropic velocities that were used to calculate uh0 \n"//&
3967 "and vh0. False is probably the better choice.", default=.false.)
3968 call get_param(param_file, mdl,
"BT_USE_WIDE_HALOS", cs%use_wide_halos, &
3969 "If true, use wide halos and march in during the \n"//&
3970 "barotropic time stepping for efficiency.", default=.true., &
3972 call get_param(param_file, mdl,
"BTHALO", bt_halo_sz, &
3973 "The minimum halo size for the barotropic solver.", default=0, &
3975 #ifdef STATIC_MEMORY_ 3976 if ((bt_halo_sz > 0) .and. (bt_halo_sz /= bthalo_))
call mom_error(fatal, &
3977 "barotropic_init: Run-time values of BTHALO must agree with the \n"//&
3978 "macro BTHALO_ with STATIC_MEMORY_.")
3979 wd_halos(1) = whaloi_+nihalo_ ; wd_halos(2) = whaloj_+njhalo_
3981 wd_halos(1) = bt_halo_sz; wd_halos(2) = bt_halo_sz
3983 call log_param(param_file, mdl,
"!BT x-halo", wd_halos(1), &
3984 "The barotropic x-halo size that is actually used.", &
3986 call log_param(param_file, mdl,
"!BT y-halo", wd_halos(2), &
3987 "The barotropic y-halo size that is actually used.", &
3990 call get_param(param_file, mdl,
"USE_BT_CONT_TYPE", use_bt_cont_type, &
3991 "If true, use a structure with elements that describe \n"//&
3992 "effective face areas from the summed continuity solver \n"//&
3993 "as a function the barotropic flow in coupling between \n"//&
3994 "the barotropic and baroclinic flow. This is only used \n"//&
3995 "if SPLIT is true. \n", default=.true.)
3996 call get_param(param_file, mdl,
"NONLINEAR_BT_CONTINUITY", &
3997 cs%Nonlinear_continuity, &
3998 "If true, use nonlinear transports in the barotropic \n"//&
3999 "continuity equation. This does not apply if \n"//&
4000 "USE_BT_CONT_TYPE is true.", default=.false.)
4001 cs%Nonlin_cont_update_period = 1
4002 if (cs%Nonlinear_continuity) &
4003 call get_param(param_file, mdl,
"NONLIN_BT_CONT_UPDATE_PERIOD", &
4004 cs%Nonlin_cont_update_period, &
4005 "If NONLINEAR_BT_CONTINUITY is true, this is the number \n"//&
4006 "of barotropic time steps between updates to the face \n"//&
4007 "areas, or 0 to update only before the barotropic stepping.",&
4008 units=
"nondim", default=1)
4009 call get_param(param_file, mdl,
"BT_MASS_SOURCE_LIMIT", cs%eta_source_limit, &
4010 "The fraction of the initial depth of the ocean that can \n"//&
4011 "be added to or removed from the bartropic solution \n"//&
4012 "within a thermodynamic time step. By default this is 0 \n"//&
4013 "for no correction.", units=
"nondim", default=0.0)
4014 call get_param(param_file, mdl,
"BT_PROJECT_VELOCITY", cs%BT_project_velocity,&
4015 "If true, step the barotropic velocity first and project \n"//&
4016 "out the velocity tendancy by 1+BEBT when calculating the \n"//&
4017 "transport. The default (false) is to use a predictor \n"//&
4018 "continuity step to find the pressure field, and then \n"//&
4019 "to do a corrector continuity step using a weighted \n"//&
4020 "average of the old and new velocities, with weights \n"//&
4021 "of (1-BEBT) and BEBT.", default=.false.)
4023 call get_param(param_file, mdl,
"DYNAMIC_SURFACE_PRESSURE", cs%dynamic_psurf, &
4024 "If true, add a dynamic pressure due to a viscous ice \n"//&
4025 "shelf, for instance.", default=.false.)
4026 if (cs%dynamic_psurf)
then 4027 call get_param(param_file, mdl,
"ICE_LENGTH_DYN_PSURF", cs%ice_strength_length, &
4028 "The length scale at which the Rayleigh damping rate due \n"//&
4029 "to the ice strength should be the same as if a Laplacian \n"//&
4030 "were applied, if DYNAMIC_SURFACE_PRESSURE is true.", &
4031 units=
"m", default=1.0e4)
4032 call get_param(param_file, mdl,
"DEPTH_MIN_DYN_PSURF", cs%Dmin_dyn_psurf, &
4033 "The minimum depth to use in limiting the size of the \n"//&
4034 "dynamic surface pressure for stability, if \n"//&
4035 "DYNAMIC_SURFACE_PRESSURE is true..", units=
"m", &
4037 call get_param(param_file, mdl,
"CONST_DYN_PSURF", cs%const_dyn_psurf, &
4038 "The constant that scales the dynamic surface pressure, \n"//&
4039 "if DYNAMIC_SURFACE_PRESSURE is true. Stable values \n"//&
4040 "are < ~1.0.", units=
"nondim", default=0.9)
4043 call get_param(param_file, mdl,
"TIDES", cs%tides, &
4044 "If true, apply tidal momentum forcing.", default=.false.)
4045 call get_param(param_file, mdl,
"SADOURNY", cs%Sadourny, &
4046 "If true, the Coriolis terms are discretized with the \n"//&
4047 "Sadourny (1975) energy conserving scheme, otherwise \n"//&
4048 "the Arakawa & Hsu scheme is used. If the internal \n"//&
4049 "deformation radius is not resolved, the Sadourny scheme \n"//&
4050 "should probably be used.", default=.true.)
4052 call get_param(param_file, mdl,
"BT_THICK_SCHEME", hvel_str, &
4053 "A string describing the scheme that is used to set the \n"//&
4054 "open face areas used for barotropic transport and the \n"//&
4055 "relative weights of the accelerations. Valid values are:\n"//&
4056 "\t ARITHMETIC - arithmetic mean layer thicknesses \n"//&
4057 "\t HARMONIC - harmonic mean layer thicknesses \n"//&
4058 "\t HYBRID (the default) - use arithmetic means for \n"//&
4059 "\t layers above the shallowest bottom, the harmonic \n"//&
4060 "\t mean for layers below, and a weighted average for \n"//&
4061 "\t layers that straddle that depth \n"//&
4062 "\t FROM_BT_CONT - use the average thicknesses kept \n"//&
4063 "\t in the h_u and h_v fields of the BT_cont_type", &
4065 select case (hvel_str)
4071 call mom_mesg(
'barotropic_init: BT_THICK_SCHEME ="'//trim(hvel_str)//
'"', 0)
4072 call mom_error(fatal,
"barotropic_init: Unrecognized setting "// &
4073 "#define BT_THICK_SCHEME "//trim(hvel_str)//
" found in input file.")
4075 if ((cs%hvel_scheme ==
from_bt_cont) .and. .not.use_bt_cont_type) &
4076 call mom_error(fatal,
"barotropic_init: BT_THICK_SCHEME FROM_BT_CONT "//&
4077 "can only be used if USE_BT_CONT_TYPE is defined.")
4079 call get_param(param_file, mdl,
"BT_STRONG_DRAG", cs%strong_drag, &
4080 "If true, use a stronger estimate of the retarding \n"//&
4081 "effects of strong bottom drag, by making it implicit \n"//&
4082 "with the barotropic time-step instead of implicit with \n"//&
4083 "the baroclinic time-step and dividing by the number of \n"//&
4084 "barotropic steps.", default=.false.)
4086 call get_param(param_file, mdl,
"CLIP_BT_VELOCITY", cs%clip_velocity, &
4087 "If true, limit any velocity components that exceed \n"//&
4088 "CFL_TRUNCATE. This should only be used as a desperate \n"//&
4089 "debugging measure.", default=.false.)
4090 call get_param(param_file, mdl,
"CFL_TRUNCATE", cs%CFL_trunc, &
4091 "The value of the CFL number that will cause velocity \n"//&
4092 "components to be truncated; instability can occur past 0.5.", &
4093 units=
"nondim", default=0.5, do_not_log=.not.cs%clip_velocity)
4094 call get_param(param_file, mdl,
"MAXVEL", cs%maxvel, &
4095 "The maximum velocity allowed before the velocity \n"//&
4096 "components are truncated.", units=
"m s-1", default=3.0e8, &
4097 do_not_log=.not.cs%clip_velocity)
4098 call get_param(param_file, mdl,
"MAXCFL_BT_CONT", cs%maxCFL_BT_cont, &
4099 "The maximum permitted CFL number associated with the \n"//&
4100 "barotropic accelerations from the summed velocities \n"//&
4101 "times the time-derivatives of thicknesses.", units=
"nondim", &
4104 call get_param(param_file, mdl,
"DT_BT_FILTER", cs%dt_bt_filter, &
4105 "A time-scale over which the barotropic mode solutions \n"//&
4106 "are filtered, in seconds if positive, or as a fraction \n"//&
4107 "of DT if negative. When used this can never be taken to \n"//&
4108 "be longer than 2*dt. Set this to 0 to apply no filtering.", &
4109 units=
"sec or nondim", default=-0.25)
4110 call get_param(param_file, mdl,
"G_BT_EXTRA", cs%G_extra, &
4111 "A nondimensional factor by which gtot is enhanced.", &
4112 units=
"nondim", default=0.0)
4113 call get_param(param_file, mdl,
"SSH_EXTRA", ssh_extra, &
4114 "An estimate of how much higher SSH might get, for use \n"//&
4115 "in calculating the safe external wave speed. The \n"//&
4116 "default is the minimum of 10 m or 5% of MAXIMUM_DEPTH.", &
4117 units=
"m", default=min(10.0,0.05*g%max_depth))
4119 call get_param(param_file, mdl,
"DEBUG", cs%debug, &
4120 "If true, write out verbose debugging data.", default=.false.)
4121 call get_param(param_file, mdl,
"DEBUG_BT", cs%debug_bt, &
4122 "If true, write out verbose debugging data within the \n"//&
4123 "barotropic time-stepping loop. The data volume can be \n"//&
4124 "quite large if this is true.", default=cs%debug)
4126 cs%linearized_BT_PV = .true.
4127 call get_param(param_file, mdl,
"BEBT", cs%bebt, &
4128 "BEBT determines whether the barotropic time stepping \n"//&
4129 "uses the forward-backward time-stepping scheme or a \n"//&
4130 "backward Euler scheme. BEBT is valid in the range from \n"//&
4131 "0 (for a forward-backward treatment of nonrotating \n"//&
4132 "gravity waves) to 1 (for a backward Euler treatment). \n"//&
4133 "In practice, BEBT must be greater than about 0.05.", &
4134 units=
"nondim", default=0.1)
4135 call get_param(param_file, mdl,
"DTBT", cs%dtbt, &
4136 "The barotropic time step, in s. DTBT is only used with \n"//&
4137 "the split explicit time stepping. To set the time step \n"//&
4138 "automatically based the maximum stable value use 0, or \n"//&
4139 "a negative value gives the fraction of the stable value. \n"//&
4140 "Setting DTBT to 0 is the same as setting it to -0.98. \n"//&
4141 "The value of DTBT that will actually be used is an \n"//&
4142 "integer fraction of DT, rounding down.", units=
"s or nondim",&
4146 call clone_mom_domain(g%Domain, cs%BT_Domain, min_halo=wd_halos, symmetric=.true.)
4147 #ifdef STATIC_MEMORY_ 4148 if (wd_halos(1) /= whaloi_+nihalo_)
call mom_error(fatal,
"barotropic_init: "//&
4149 "Barotropic x-halo sizes are incorrectly resized with STATIC_MEMORY_.")
4150 if (wd_halos(2) /= whaloj_+njhalo_)
call mom_error(fatal,
"barotropic_init: "//&
4151 "Barotropic y-halo sizes are incorrectly resized with STATIC_MEMORY_.")
4153 if (bt_halo_sz > 0)
then 4154 if (wd_halos(1) > bt_halo_sz) &
4155 call mom_mesg(
"barotropic_init: barotropic x-halo size increased.", 3)
4156 if (wd_halos(2) > bt_halo_sz) &
4157 call mom_mesg(
"barotropic_init: barotropic y-halo size increased.", 3)
4161 cs%isdw = g%isc-wd_halos(1) ; cs%iedw = g%iec+wd_halos(1)
4162 cs%jsdw = g%jsc-wd_halos(2) ; cs%jedw = g%jec+wd_halos(2)
4163 isdw = cs%isdw ; iedw = cs%iedw ; jsdw = cs%jsdw ; jedw = cs%jedw
4165 alloc_(cs%frhatu(isdb:iedb,jsd:jed,nz)) ; alloc_(cs%frhatv(isd:ied,jsdb:jedb,nz))
4166 alloc_(cs%eta_source(isd:ied,jsd:jed)) ; alloc_(cs%eta_cor(isd:ied,jsd:jed))
4167 if (cs%bound_BT_corr)
then 4168 alloc_(cs%eta_cor_bound(isd:ied,jsd:jed)) ; cs%eta_cor_bound(:,:) = 0.0
4170 alloc_(cs%IDatu(isdb:iedb,jsd:jed)) ; alloc_(cs%IDatv(isd:ied,jsdb:jedb))
4172 alloc_(cs%ua_polarity(isdw:iedw,jsdw:jedw))
4173 alloc_(cs%va_polarity(isdw:iedw,jsdw:jedw))
4175 cs%frhatu(:,:,:) = 0.0 ; cs%frhatv(:,:,:) = 0.0
4176 cs%eta_source(:,:) = 0.0 ; cs%eta_cor(:,:) = 0.0
4177 cs%IDatu(:,:) = 0.0 ; cs%IDatv(:,:) = 0.0
4179 cs%ua_polarity(:,:) = 1.0 ; cs%va_polarity(:,:) = 1.0
4180 call create_group_pass(pass_a_polarity, cs%ua_polarity, cs%va_polarity, cs%BT_domain, to_all, agrid)
4181 call do_group_pass(pass_a_polarity, cs%BT_domain)
4183 if (use_bt_cont_type) &
4187 allocate(cs%debug_BT_HI)
4188 cs%debug_BT_HI%isc=g%isc
4189 cs%debug_BT_HI%iec=g%iec
4190 cs%debug_BT_HI%jsc=g%jsc
4191 cs%debug_BT_HI%jec=g%jec
4192 cs%debug_BT_HI%IscB=g%isc-1
4193 cs%debug_BT_HI%IecB=g%iec
4194 cs%debug_BT_HI%JscB=g%jsc-1
4195 cs%debug_BT_HI%JecB=g%jec
4196 cs%debug_BT_HI%isd=cs%isdw
4197 cs%debug_BT_HI%ied=cs%iedw
4198 cs%debug_BT_HI%jsd=cs%jsdw
4199 cs%debug_BT_HI%jed=cs%jedw
4200 cs%debug_BT_HI%IsdB=cs%isdw-1
4201 cs%debug_BT_HI%IedB=cs%iedw
4202 cs%debug_BT_HI%JsdB=cs%jsdw-1
4203 cs%debug_BT_HI%JedB=cs%jedw
4207 alloc_(cs%IareaT(cs%isdw:cs%iedw,cs%jsdw:cs%jedw)) ; cs%IareaT(:,:) = 0.0
4208 alloc_(cs%bathyT(cs%isdw:cs%iedw,cs%jsdw:cs%jedw)) ; cs%bathyT(:,:) = gv%Angstrom_z
4209 alloc_(cs%IdxCu(cs%isdw-1:cs%iedw,cs%jsdw:cs%jedw)) ; cs%IdxCu(:,:) = 0.0
4210 alloc_(cs%IdyCv(cs%isdw:cs%iedw,cs%jsdw-1:cs%jedw)) ; cs%IdyCv(:,:) = 0.0
4211 alloc_(cs%dy_Cu(cs%isdw-1:cs%iedw,cs%jsdw:cs%jedw)) ; cs%dy_Cu(:,:) = 0.0
4212 alloc_(cs%dx_Cv(cs%isdw:cs%iedw,cs%jsdw-1:cs%jedw)) ; cs%dx_Cv(:,:) = 0.0
4213 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
4214 cs%IareaT(i,j) = g%IareaT(i,j)
4215 cs%bathyT(i,j) = g%bathyT(i,j)
4219 do j=g%jsd,g%jed ;
do i=g%IsdB,g%IedB
4220 cs%IdxCu(i,j) = g%IdxCu(i,j) ; cs%dy_Cu(i,j) = g%dy_Cu(i,j)
4222 do j=g%JsdB,g%JedB ;
do i=g%isd,g%ied
4223 cs%IdyCv(i,j) = g%IdyCv(i,j) ; cs%dx_Cv(i,j) = g%dx_Cv(i,j)
4231 call do_group_pass(pass_static_data, cs%BT_domain)
4233 if (cs%linearized_BT_PV)
then 4234 alloc_(cs%q_D(cs%isdw-1:cs%iedw,cs%jsdw-1:cs%jedw))
4235 alloc_(cs%D_u_Cor(cs%isdw-1:cs%iedw,cs%jsdw:cs%jedw))
4236 alloc_(cs%D_v_Cor(cs%isdw:cs%iedw,cs%jsdw-1:cs%jedw))
4237 cs%q_D(:,:) = 0.0 ; cs%D_u_Cor(:,:) = 0.0 ; cs%D_v_Cor(:,:) = 0.0
4238 do j=js,je ;
do i=is-1,ie
4239 cs%D_u_Cor(i,j) = 0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j))
4241 do j=js-1,je ;
do i=is,ie
4242 cs%D_v_Cor(i,j) = 0.5 * (g%bathyT(i,j+1) + g%bathyT(i,j))
4244 do j=js-1,je ;
do i=is-1,ie
4245 if (g%mask2dT(i,j)+g%mask2dT(i,j+1)+g%mask2dT(i+1,j)+g%mask2dT(i+1,j+1)>0.)
then 4246 cs%q_D(i,j) = 0.25 * g%CoriolisBu(i,j) * &
4247 ((g%areaT(i,j) + g%areaT(i+1,j+1)) + (g%areaT(i+1,j) + g%areaT(i,j+1))) / &
4248 ((g%areaT(i,j) * g%bathyT(i,j) + g%areaT(i+1,j+1) * g%bathyT(i+1,j+1)) + &
4249 (g%areaT(i+1,j) * g%bathyT(i+1,j) + g%areaT(i,j+1) * g%bathyT(i,j+1)))
4256 call create_group_pass(pass_q_d_cor, cs%q_D, cs%BT_Domain, to_all, position=corner)
4259 call do_group_pass(pass_q_d_cor, cs%BT_Domain)
4263 dtbt_input = cs%dtbt
4264 cs%dtbt_fraction = 0.98 ;
if (cs%dtbt < 0.0) cs%dtbt_fraction = -cs%dtbt
4266 do k=1,g%ke ; gtot_estimate = gtot_estimate + gv%g_prime(k) ;
enddo 4267 call set_dtbt(g, gv, cs, gtot_est = gtot_estimate, ssh_add = ssh_extra)
4268 if (dtbt_input > 0.0) cs%dtbt = dtbt_input
4270 call log_param(param_file, mdl,
"DTBT as used", cs%dtbt)
4271 call log_param(param_file, mdl,
"estimated maximum DTBT", cs%dtbt_max)
4276 if (gv%Boussinesq)
then 4277 thickness_units =
"meter" ; flux_units =
"meter3 second-1" 4279 thickness_units =
"kilogram meter-2" ; flux_units =
"kilogram second-1" 4282 cs%id_PFu_bt = register_diag_field(
'ocean_model',
'PFuBT', diag%axesCu1, time, &
4283 'Zonal Anomalous Barotropic Pressure Force Force Acceleration',
'meter second-2')
4284 cs%id_PFv_bt = register_diag_field(
'ocean_model',
'PFvBT', diag%axesCv1, time, &
4285 'Meridional Anomalous Barotropic Pressure Force Acceleration',
'meter second-2')
4286 cs%id_Coru_bt = register_diag_field(
'ocean_model',
'CoruBT', diag%axesCu1, time, &
4287 'Zonal Barotropic Coriolis Acceleration',
'meter second-2')
4288 cs%id_Corv_bt = register_diag_field(
'ocean_model',
'CorvBT', diag%axesCv1, time, &
4289 'Meridional Barotropic Coriolis Acceleration',
'meter second-2')
4290 cs%id_uaccel = register_diag_field(
'ocean_model',
'u_accel_bt', diag%axesCu1, time, &
4291 'Barotropic zonal acceleration',
'meter second-2')
4292 cs%id_vaccel = register_diag_field(
'ocean_model',
'v_accel_bt', diag%axesCv1, time, &
4293 'Barotropic meridional acceleration',
'meter second-2')
4294 cs%id_ubtforce = register_diag_field(
'ocean_model',
'ubtforce', diag%axesCu1, time, &
4295 'Barotropic zonal acceleration from baroclinic terms',
'meter second-2')
4296 cs%id_vbtforce = register_diag_field(
'ocean_model',
'vbtforce', diag%axesCv1, time, &
4297 'Barotropic meridional acceleration from baroclinic terms',
'meter second-2')
4299 cs%id_eta_bt = register_diag_field(
'ocean_model',
'eta_bt', diag%axesT1, time, &
4300 'Barotropic end SSH', thickness_units)
4301 cs%id_ubt = register_diag_field(
'ocean_model',
'ubt', diag%axesCu1, time, &
4302 'Barotropic end zonal velocity',
'meter second-1')
4303 cs%id_vbt = register_diag_field(
'ocean_model',
'vbt', diag%axesCv1, time, &
4304 'Barotropic end meridional velocity',
'meter second-1')
4305 cs%id_eta_st = register_diag_field(
'ocean_model',
'eta_st', diag%axesT1, time, &
4306 'Barotropic start SSH', thickness_units)
4307 cs%id_ubt_st = register_diag_field(
'ocean_model',
'ubt_st', diag%axesCu1, time, &
4308 'Barotropic start zonal velocity',
'meter second-1')
4309 cs%id_vbt_st = register_diag_field(
'ocean_model',
'vbt_st', diag%axesCv1, time, &
4310 'Barotropic start meridional velocity',
'meter second-1')
4311 cs%id_ubtav = register_diag_field(
'ocean_model',
'ubtav', diag%axesCu1, time, &
4312 'Barotropic time-average zonal velocity',
'meter second-1')
4313 cs%id_vbtav = register_diag_field(
'ocean_model',
'vbtav', diag%axesCv1, time, &
4314 'Barotropic time-average meridional velocity',
'meter second-1')
4315 cs%id_eta_cor = register_diag_field(
'ocean_model',
'eta_cor', diag%axesT1, time, &
4316 'Corrective mass flux',
'meter second-1')
4317 cs%id_visc_rem_u = register_diag_field(
'ocean_model',
'visc_rem_u', diag%axesCuL, time, &
4318 'Viscous remnant at u',
'Nondim')
4319 cs%id_visc_rem_v = register_diag_field(
'ocean_model',
'visc_rem_v', diag%axesCvL, time, &
4320 'Viscous remnant at v',
'Nondim')
4321 cs%id_gtotn = register_diag_field(
'ocean_model',
'gtot_n', diag%axesT1, time, &
4322 'gtot to North',
'm s-2')
4323 cs%id_gtots = register_diag_field(
'ocean_model',
'gtot_s', diag%axesT1, time, &
4324 'gtot to South',
'm s-2')
4325 cs%id_gtote = register_diag_field(
'ocean_model',
'gtot_e', diag%axesT1, time, &
4326 'gtot to East',
'm s-2')
4327 cs%id_gtotw = register_diag_field(
'ocean_model',
'gtot_w', diag%axesT1, time, &
4328 'gtot to West',
'm s-2')
4329 cs%id_eta_hifreq = register_diag_field(
'ocean_model',
'eta_hifreq', diag%axesT1, time, &
4330 'High Frequency Barotropic SSH', thickness_units)
4331 cs%id_ubt_hifreq = register_diag_field(
'ocean_model',
'ubt_hifreq', diag%axesCu1, time, &
4332 'High Frequency Barotropic zonal velocity',
'meter second-1')
4333 cs%id_vbt_hifreq = register_diag_field(
'ocean_model',
'vbt_hifreq', diag%axesCv1, time, &
4334 'High Frequency Barotropic meridional velocity',
'meter second-1')
4335 cs%id_eta_pred_hifreq = register_diag_field(
'ocean_model',
'eta_pred_hifreq', diag%axesT1, time, &
4336 'High Frequency Predictor Barotropic SSH', thickness_units)
4337 cs%id_uhbt_hifreq = register_diag_field(
'ocean_model',
'uhbt_hifreq', diag%axesCu1, time, &
4338 'High Frequency Barotropic zonal transport',
'meter3 second-1')
4339 cs%id_vhbt_hifreq = register_diag_field(
'ocean_model',
'vhbt_hifreq', diag%axesCv1, time, &
4340 'High Frequency Barotropic meridional transport',
'meter3 second-1')
4341 cs%id_frhatu = register_diag_field(
'ocean_model',
'frhatu', diag%axesCuL, time, &
4342 'Fractional thickness of layers in u-columns',
'Nondim')
4343 cs%id_frhatv = register_diag_field(
'ocean_model',
'frhatv', diag%axesCvL, time, &
4344 'Fractional thickness of layers in v-columns',
'Nondim')
4345 cs%id_frhatu1 = register_diag_field(
'ocean_model',
'frhatu1', diag%axesCuL, time, &
4346 'Predictor Fractional thickness of layers in u-columns',
'Nondim')
4347 cs%id_frhatv1 = register_diag_field(
'ocean_model',
'frhatv1', diag%axesCvL, time, &
4348 'Predictor Fractional thickness of layers in v-columns',
'Nondim')
4349 cs%id_uhbt = register_diag_field(
'ocean_model',
'uhbt', diag%axesCu1, time, &
4350 'Barotropic zonal transport averaged over a baroclinic step',
'meter3 second-1')
4351 cs%id_vhbt = register_diag_field(
'ocean_model',
'vhbt', diag%axesCv1, time, &
4352 'Barotropic meridional transport averaged over a baroclinic step',
'meter3 second-1')
4354 if (use_bt_cont_type)
then 4355 cs%id_BTC_FA_u_EE = register_diag_field(
'ocean_model',
'BTC_FA_u_EE', diag%axesCu1, time, &
4356 'BTCont type far east face area',
'meter2')
4357 cs%id_BTC_FA_u_E0 = register_diag_field(
'ocean_model',
'BTC_FA_u_E0', diag%axesCu1, time, &
4358 'BTCont type near east face area',
'meter2')
4359 cs%id_BTC_FA_u_WW = register_diag_field(
'ocean_model',
'BTC_FA_u_WW', diag%axesCu1, time, &
4360 'BTCont type far west face area',
'meter2')
4361 cs%id_BTC_FA_u_W0 = register_diag_field(
'ocean_model',
'BTC_FA_u_W0', diag%axesCu1, time, &
4362 'BTCont type near west face area',
'meter2')
4363 cs%id_BTC_ubt_EE = register_diag_field(
'ocean_model',
'BTC_ubt_EE', diag%axesCu1, time, &
4364 'BTCont type far east velocity',
'meter second-1')
4365 cs%id_BTC_ubt_WW = register_diag_field(
'ocean_model',
'BTC_ubt_WW', diag%axesCu1, time, &
4366 'BTCont type far west velocity',
'meter second-1')
4367 cs%id_BTC_FA_v_NN = register_diag_field(
'ocean_model',
'BTC_FA_v_NN', diag%axesCv1, time, &
4368 'BTCont type far north face area',
'meter2')
4369 cs%id_BTC_FA_v_N0 = register_diag_field(
'ocean_model',
'BTC_FA_v_N0', diag%axesCv1, time, &
4370 'BTCont type near north face area',
'meter2')
4371 cs%id_BTC_FA_v_SS = register_diag_field(
'ocean_model',
'BTC_FA_v_SS', diag%axesCv1, time, &
4372 'BTCont type far south face area',
'meter2')
4373 cs%id_BTC_FA_v_S0 = register_diag_field(
'ocean_model',
'BTC_FA_v_S0', diag%axesCv1, time, &
4374 'BTCont type near south face area',
'meter2')
4375 cs%id_BTC_vbt_NN = register_diag_field(
'ocean_model',
'BTC_vbt_NN', diag%axesCv1, time, &
4376 'BTCont type far north velocity',
'meter second-1')
4377 cs%id_BTC_vbt_SS = register_diag_field(
'ocean_model',
'BTC_vbt_SS', diag%axesCv1, time, &
4378 'BTCont type far south velocity',
'meter second-1')
4380 cs%id_uhbt0 = register_diag_field(
'ocean_model',
'uhbt0', diag%axesCu1, time, &
4381 'Barotropic zonal transport difference',
'meter3 second-1')
4382 cs%id_vhbt0 = register_diag_field(
'ocean_model',
'vhbt0', diag%axesCv1, time, &
4383 'Barotropic meridional transport difference',
'meter3 second-1')
4385 if (cs%id_frhatu1 > 0)
call safe_alloc_ptr(cs%frhatu1, isdb,iedb,jsd,jed,nz)
4386 if (cs%id_frhatv1 > 0)
call safe_alloc_ptr(cs%frhatv1, isd,ied,jsdb,jedb,nz)
4390 call btcalc(h, g, gv, cs, may_use_default=.true.)
4391 cs%ubtav(:,:) = 0.0 ; cs%vbtav(:,:) = 0.0
4392 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
4393 cs%ubtav(i,j) = cs%ubtav(i,j) + cs%frhatu(i,j,k) * u(i,j,k)
4394 enddo ;
enddo ;
enddo 4395 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
4396 cs%vbtav(i,j) = cs%vbtav(i,j) + cs%frhatv(i,j,k) * v(i,j,k)
4397 enddo ;
enddo ;
enddo 4402 do j=js,je ;
do i=is-1,ie ; cs%ubt_IC(i,j) = cs%ubtav(i,j) ;
enddo ;
enddo 4403 do j=js-1,je ;
do i=is,ie ; cs%vbt_IC(i,j) = cs%vbtav(i,j) ;
enddo ;
enddo 4410 do j=js,je ;
do i=is-1,ie
4411 if (g%mask2dCu(i,j)>0.)
then 4412 cs%IDatu(i,j) = g%mask2dCu(i,j) * 2.0 / (g%bathyT(i+1,j) + g%bathyT(i,j))
4417 do j=js-1,je ;
do i=is,ie
4418 if (g%mask2dCv(i,j)>0.)
then 4419 cs%IDatv(i,j) = g%mask2dCv(i,j) * 2.0 / (g%bathyT(i,j+1) + g%bathyT(i,j))
4434 if (cs%bound_BT_corr)
then 4437 do j=js,je ;
do i=is,ie
4438 cs%eta_cor_bound(i,j) = gv%m_to_H * g%IareaT(i,j) * 0.1 * cs%maxvel * &
4439 ((datu(i-1,j) + datu(i,j)) + (datv(i,j) + datv(i,j-1)))
4445 do j=js,je ;
do i=is-1,ie ; cs%uhbt_IC(i,j) = cs%ubtav(i,j) * datu(i,j) ;
enddo ;
enddo 4446 do j=js-1,je ;
do i=is,ie ; cs%vhbt_IC(i,j) = cs%vbtav(i,j) * datv(i,j) ;
enddo ;
enddo 4452 call do_group_pass(pass_bt_hbt_btav, g%Domain)
4455 id_clock_calc_pre = cpu_clock_id(
'(Ocean BT pre-calcs only)', grain=clock_routine)
4456 id_clock_pass_pre = cpu_clock_id(
'(Ocean BT pre-step halo updates)', grain=clock_routine)
4457 id_clock_calc = cpu_clock_id(
'(Ocean BT stepping calcs only)', grain=clock_routine)
4458 id_clock_pass_step = cpu_clock_id(
'(Ocean BT stepping halo updates)', grain=clock_routine)
4460 id_clock_pass_post = cpu_clock_id(
'(Ocean BT post-step halo updates)', grain=clock_routine)
4461 if (dtbt_input <= 0.0) &
4462 id_clock_sync = cpu_clock_id(
'(Ocean BT global synch)', grain=clock_routine)
4469 dealloc_(cs%frhatu) ; dealloc_(cs%frhatv)
4470 dealloc_(cs%IDatu) ; dealloc_(cs%IDatv)
4471 dealloc_(cs%ubtav) ; dealloc_(cs%vbtav)
4472 dealloc_(cs%eta_cor) ; dealloc_(cs%eta_source)
4473 dealloc_(cs%ua_polarity) ; dealloc_(cs%va_polarity)
4474 if (cs%bound_BT_corr)
then 4475 dealloc_(cs%eta_cor_bound)
4496 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
4497 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed
4498 isdb = hi%IsdB ; iedb = hi%IedB ; jsdb = hi%JsdB ; jedb = hi%JedB
4500 if (
associated(cs))
then 4501 call mom_error(warning,
"register_barotropic_restarts called with an associated "// &
4502 "control structure.")
4507 alloc_(cs%ubtav(isdb:iedb,jsd:jed)) ; cs%ubtav(:,:) = 0.0
4508 alloc_(cs%vbtav(isd:ied,jsdb:jedb)) ; cs%vbtav(:,:) = 0.0
4509 alloc_(cs%ubt_IC(isdb:iedb,jsd:jed)) ; cs%ubt_IC(:,:) = 0.0
4510 alloc_(cs%vbt_IC(isd:ied,jsdb:jedb)) ; cs%vbt_IC(:,:) = 0.0
4511 alloc_(cs%uhbt_IC(isdb:iedb,jsd:jed)) ; cs%uhbt_IC(:,:) = 0.0
4512 alloc_(cs%vhbt_IC(isd:ied,jsdb:jedb)) ; cs%vhbt_IC(:,:) = 0.0
4514 vd(2) =
var_desc(
"ubtav",
"meter second-1",
"Time mean barotropic zonal velocity", &
4515 hor_grid=
'u', z_grid=
'1')
4516 vd(3) =
var_desc(
"vbtav",
"meter second-1",
"Time mean barotropic meridional velocity",&
4517 hor_grid=
'v', z_grid=
'1')
4521 vd(2) =
var_desc(
"ubt_IC",
"meter second-1", &
4522 longname=
"Next initial condition for the barotropic zonal velocity", &
4523 hor_grid=
'u', z_grid=
'1')
4524 vd(3) =
var_desc(
"vbt_IC",
"meter second-1", &
4525 longname=
"Next initial condition for the barotropic meridional velocity",&
4526 hor_grid=
'v', z_grid=
'1')
4530 if (gv%Boussinesq)
then 4531 vd(2) =
var_desc(
"uhbt_IC",
"meter3 second-1", &
4532 longname=
"Next initial condition for the barotropic zonal transport", &
4533 hor_grid=
'u', z_grid=
'1')
4534 vd(3) =
var_desc(
"vhbt_IC",
"meter3 second-1", &
4535 longname=
"Next initial condition for the barotropic meridional transport",&
4536 hor_grid=
'v', z_grid=
'1')
4538 vd(2) =
var_desc(
"uhbt_IC",
"kg second-1", &
4539 longname=
"Next initial condition for the barotropic zonal transport", &
4540 hor_grid=
'u', z_grid=
'1')
4541 vd(3) =
var_desc(
"vhbt_IC",
"kg second-1", &
4542 longname=
"Next initial condition for the barotropic meridional transport",&
4543 hor_grid=
'v', z_grid=
'1')
subroutine, public register_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 barotropic_init(u, v, h, eta, Time, G, GV, param_file, diag, CS, restart_CS, BT_cont, tides_CSp)
barotropic_init initializes a number of time-invariant fields used in the barotropic calculation and ...
integer, parameter hybrid_bt_cont
integer id_clock_pass_post
subroutine adjust_local_bt_cont_types(ubt, uhbt, vbt, vhbt, BTCL_u, BTCL_v, G, MS, halo)
Adjust_local_BT_cont_types sets up reordered versions of the BT_cont type in the local_BT_cont types...
integer, parameter, public obc_direction_s
Indicates the boundary is an effective southern boundary.
character *(20), parameter arithmetic_string
integer, parameter harmonic
subroutine, public tidal_forcing_sensitivity(G, CS, deta_tidal_deta)
This subroutine calculates returns the partial derivative of the local geopotential height with the i...
integer id_clock_calc_post
integer, parameter, public obc_direction_w
Indicates the boundary is an effective western boundary.
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...
integer, parameter, public obc_direction_n
Indicates the boundary is an effective northern boundary.
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...
This module implements boundary forcing for MOM6.
integer, parameter arithmetic
integer, parameter, public to_all
Ocean grid type. See mom_grid for details.
integer, parameter from_bt_cont
Provides the ocean grid type.
subroutine, public do_group_pass(group, MOM_dom)
Open boundary segment data structure.
subroutine apply_eta_obcs(OBC, eta, ubt, vbt, BT_OBC, G, MS, halo, dtbt)
This subroutine applies the open boundary conditions on the free surface height, as coded by Mehmet I...
This module contains I/O framework code.
Defines the horizontal index type (hor_index_type) used for providing index ranges.
character *(20), parameter hybrid_string
subroutine set_local_bt_cont_types(BT_cont, BTCL_u, BTCL_v, G, MS, BT_Domain, halo)
This subroutine sets up reordered versions of the BT_cont type in the local_BT_cont types...
Container for horizontal index ranges for data, computational and global domains. ...
integer id_clock_pass_pre
subroutine, public set_dtbt(G, GV, CS, eta, pbce, BT_cont, gtot_est, SSH_add)
This subroutine automatically determines an optimal value for dtbt based on some state of the ocean...
real function uhbt_to_ubt(uhbt, BTC, guess)
This function inverts the transport function to determine the barotopic velocity that is consistent w...
integer, parameter, public obc_simple
real function find_uhbt(u, BTC)
The function find_uhbt determines the zonal transport for a given velocity.
subroutine, public start_group_pass(group, MOM_dom)
The BT_cont_type structure contains information about the summed layer transports and how they will v...
subroutine set_up_bt_obc(OBC, eta, BT_OBC, G, GV, MS, halo, use_BT_cont, Datu, Datv, BTCL_u, BTCL_v)
This subroutine sets up the private structure used to apply the open boundary conditions, as developed by Mehmet Ilicak.
subroutine, public bt_mass_source(h, eta, fluxes, set_cor, dt_therm, dt_since_therm, G, GV, CS)
bt_mass_source determines the appropriately limited mass source for the barotropic solver...
subroutine apply_velocity_obcs(OBC, ubt, vbt, uhbt, vhbt, ubt_trans, vbt_trans, eta, ubt_old, vbt_old, BT_OBC, G, MS, halo, dtbt, bebt, use_BT_cont, Datu, Datv, BTCL_u, BTCL_v, uhbt0, vhbt0)
The following 4 subroutines apply the open boundary conditions. This subroutine applies the open boun...
logical function, public is_root_pe()
subroutine, public complete_group_pass(group, MOM_dom)
subroutine destroy_bt_obc(BT_OBC)
Clean up the BT_OBC memory.
real function find_vhbt(v, BTC)
The function find_vhbt determines the meridional transport for a given velocity.
integer, parameter hybrid
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine, public btstep(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, OBC, BT_cont, eta_PF_start, taux_bot, tauy_bot, uh0, vh0, u_uh0, v_vh0)
This subroutine time steps the barotropic equations explicitly. For gravity waves, anything between a forwards-backwards scheme and a simulated backwards Euler scheme is used, with bebt between 0.0 and 1.0 determining the scheme. In practice, bebt must be of order 0.2 or greater. A forwards-backwards treatment of the Coriolis terms is always used.
subroutine, public mom_mesg(message, verb, all_print)
integer, parameter, public obc_direction_e
Indicates the boundary is an effective eastern boundary.
Type for describing a variable, typically a tracer.
The MOM_domain_type contains information about the domain decompositoin.
integer id_clock_calc_pre
character *(20), parameter bt_cont_string
subroutine bt_cont_to_face_areas(BT_cont, Datu, Datv, G, MS, halo, maximize)
This subroutine uses the BTCL types to find typical or maximum face areas, which can then be used for...
integer, parameter, public obc_none
Controls where open boundary conditions are applied.
integer id_clock_pass_step
subroutine find_face_areas(Datu, Datv, G, GV, CS, MS, eta, halo, add_max)
This subroutine determines the open face areas of cells for calculating the barotropic transport...
real function vhbt_to_vbt(vhbt, BTC, guess)
This function inverts the transport function to determine the barotopic velocity that is consistent w...
character *(20), parameter harmonic_string
subroutine, public barotropic_end(CS)
Clean up the barotropic control structure.
subroutine, public mom_error(level, message, all_print)
subroutine, public btcalc(h, G, GV, CS, h_u, h_v, may_use_default, OBC)
btcalc calculates the barotropic velocities from the full velocity and thickness fields, determines the fraction of the total water column in each layer at velocity points, and determines a corrective fictitious mass source that will drive the barotropic estimate of the free surface height toward the baroclinic estimate.