95 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
119 implicit none ;
private 121 #include <MOM_memory.h> 122 #ifdef STATIC_MEMORY_ 126 # define WHALOI_ MAX(BTHALO_-NIHALO_,0) 127 # define WHALOJ_ MAX(BTHALO_-NJHALO_,0) 128 # define NIMEMW_ 1-WHALOI_:NIMEM_+WHALOI_ 129 # define NJMEMW_ 1-WHALOJ_:NJMEM_+WHALOJ_ 130 # define NIMEMBW_ -WHALOI_:NIMEM_+WHALOI_ 131 # define NJMEMBW_ -WHALOJ_:NJMEM_+WHALOJ_ 132 # define SZIW_(G) NIMEMW_ 133 # define SZJW_(G) NJMEMW_ 134 # define SZIBW_(G) NIMEMBW_ 135 # define SZJBW_(G) NJMEMBW_ 141 # define SZIW_(G) G%isdw:G%iedw 142 # define SZJW_(G) G%jsdw:G%jedw 143 # define SZIBW_(G) G%isdw-1:G%iedw 144 # define SZJBW_(G) G%jsdw-1:G%jedw 151 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: frhatu
152 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: frhatv
155 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_) :: &
165 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_) :: &
175 real allocable_,
dimension(NIMEM_,NJMEM_) :: &
186 real allocable_,
dimension(NIMEMW_,NJMEMW_) :: &
190 real allocable_,
dimension(NIMEMW_,NJMEMW_) :: &
193 real allocable_,
dimension(NIMEMBW_,NJMEMW_) :: &
201 real allocable_,
dimension(NIMEMW_,NJMEMBW_) :: &
209 real allocable_,
dimension(NIMEMBW_,NJMEMBW_) :: &
212 real,
pointer,
dimension(:,:,:) :: frhatu1, frhatv1
217 real :: dtbt_fraction
224 integer :: nstep_last = 0
232 real :: eta_source_limit
236 logical :: bound_bt_corr
241 logical :: gradual_bt_ics
252 logical :: nonlinear_continuity
254 integer :: nonlin_cont_update_period
258 logical :: bt_project_velocity
266 logical :: dynamic_psurf
268 real :: dmin_dyn_psurf
271 real :: ice_strength_length
274 real :: const_dyn_psurf
282 integer :: hvel_scheme
286 logical :: strong_drag
288 logical :: rescale_d_bt
292 logical :: linearized_bt_pv
295 logical :: use_wide_halos
297 logical :: clip_velocity
304 real :: maxcfl_bt_cont
309 type(time_type),
pointer :: time
315 logical :: module_is_initialized = .false.
317 integer :: isdw, iedw, jsdw, jedw
319 integer :: id_pfu_bt = -1, id_pfv_bt = -1, id_coru_bt = -1, id_corv_bt = -1
320 integer :: id_ubtforce = -1, id_vbtforce = -1, id_uaccel = -1, id_vaccel = -1
321 integer :: id_visc_rem_u = -1, id_visc_rem_v = -1, id_eta_cor = -1
322 integer :: id_ubt = -1, id_vbt = -1, id_eta_bt = -1, id_ubtav = -1, id_vbtav = -1
323 integer :: id_ubt_st = -1, id_vbt_st = -1, id_eta_st = -1
324 integer :: id_ubt_hifreq = -1, id_vbt_hifreq = -1, id_eta_hifreq = -1
325 integer :: id_uhbt_hifreq = -1, id_vhbt_hifreq = -1, id_eta_pred_hifreq = -1
326 integer :: id_gtotn = -1, id_gtots = -1, id_gtote = -1, id_gtotw = -1
327 integer :: id_datu_res = -1, id_datv_res = -1
328 integer :: id_uhbt = -1, id_frhatu = -1, id_vhbt = -1, id_frhatv = -1
329 integer :: id_frhatu1 = -1, id_frhatv1 = -1
333 real :: fa_u_ee, fa_u_e0, fa_u_w0, fa_u_ww
334 real :: ubt_ee, ubt_ww
335 real :: uh_crve, uh_crvw
339 real :: fa_v_nn, fa_v_n0, fa_v_s0, fa_v_ss
340 real :: vbt_nn, vbt_ss
341 real :: vh_crvn, vh_crvs
346 integer :: isdw, iedw, jsdw, jedw
351 real,
dimension(:,:),
pointer :: &
359 ubt_outer => null(), &
360 vbt_outer => null(), &
362 eta_outer_u => null(), &
363 eta_outer_v => null()
365 integer :: is_u_obc, ie_u_obc, js_u_obc, je_u_obc
366 integer :: is_v_obc, ie_v_obc, js_v_obc, je_v_obc
387 subroutine legacy_btstep(use_fluxes, U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, &
388 fluxes, pbce, eta_PF_in, U_Cor, V_Cor, &
389 accel_layer_u, accel_layer_v, eta_out, uhbtav, vhbtav, G, GV, CS, &
390 visc_rem_u, visc_rem_v, etaav, uhbt_out, vhbt_out, OBC, &
391 BT_cont, eta_PF_start, &
392 taux_bot, tauy_bot, uh0, vh0, u_uh0, v_vh0)
395 logical,
intent(in) :: use_fluxes
397 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
400 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
403 real,
dimension(SZI_(G),SZJ_(G)), &
409 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
410 intent(in) :: bc_accel_u
412 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
413 intent(in) :: bc_accel_v
415 type(
forcing),
intent(in) :: fluxes
417 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
420 real,
dimension(SZI_(G),SZJ_(G)), &
421 intent(in) :: eta_PF_in
424 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
428 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
432 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
433 intent(out) :: accel_layer_u
435 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
436 intent(out) :: accel_layer_v
438 real,
dimension(SZI_(G),SZJ_(G)), &
439 intent(inout) :: eta_out
441 real,
dimension(SZIB_(G),SZJ_(G)), &
442 intent(out) :: uhbtav
444 real,
dimension(SZI_(G),SZJB_(G)), &
445 intent(out) :: vhbtav
449 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
450 intent(in),
optional :: visc_rem_u
455 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
456 intent(in),
optional :: visc_rem_v
461 real,
dimension(SZI_(G),SZJ_(G)), &
462 intent(out),
optional :: etaav
464 real,
dimension(SZIB_(G),SZJ_(G)), &
465 intent(out),
optional :: uhbt_out
467 real,
dimension(SZI_(G),SZJB_(G)), &
468 intent(out),
optional :: vhbt_out
471 pointer,
optional :: OBC
474 pointer,
optional :: BT_cont
476 real,
dimension(:,:), &
477 pointer,
optional :: eta_PF_start
479 real,
dimension(:,:), &
480 pointer,
optional :: taux_bot
482 real,
dimension(:,:), &
483 pointer,
optional :: tauy_bot
485 real,
dimension(:,:,:), &
486 pointer,
optional :: uh0, u_uh0
487 real,
dimension(:,:,:), &
488 pointer,
optional :: vh0, v_vh0
559 real :: ubt_Cor(szib_(g),szj_(g))
560 real :: vbt_Cor(szi_(g),szjb_(g))
562 real :: wt_u(szib_(g),szj_(g),szk_(g))
563 real :: wt_v(szi_(g),szjb_(g),szk_(g))
566 real,
dimension(SZIB_(G),SZJ_(G)) :: &
569 real,
dimension(SZI_(G),SZJB_(G)) :: &
572 real,
dimension(SZI_(G),SZJ_(G)) :: &
579 real :: q(szibw_(cs),szjbw_(cs))
580 real,
dimension(SZIBW_(CS),SZJW_(CS)) :: &
609 real,
dimension(SZIW_(CS),SZJBW_(CS)) :: &
636 real,
target,
dimension(SZIW_(CS),SZJW_(CS)) :: &
640 real,
pointer,
dimension(:,:) :: &
643 real,
dimension(SZIW_(CS),SZJW_(CS)) :: &
697 logical :: do_hifreq_output
698 logical :: use_visc_rem, use_BT_cont
699 logical :: do_ave, find_etaav, find_PF, find_Cor
700 logical :: ice_is_rigid, nonblock_setup, interp_eta_PF
701 logical :: project_velocity, add_uh0
704 real :: ice_strength = 0.0
713 real,
allocatable,
dimension(:) :: wt_vel, wt_eta, wt_accel, wt_trans, wt_accel2
714 real :: sum_wt_vel, sum_wt_eta, sum_wt_accel, sum_wt_trans
715 real :: I_sum_wt_vel, I_sum_wt_eta, I_sum_wt_accel, I_sum_wt_trans
719 logical :: apply_OBCs, apply_OBC_flather
723 character(len=200) :: mesg
724 integer :: pid_ubt, pid_eta, pid_e_anom, pid_etaav, pid_uhbtav, pid_ubtav
725 integer :: pid_q, pid_eta_PF, pid_dyn_coef_eta, pid_eta_src
726 integer :: pid_DCor_u, pid_Datu_res, pid_tmp_u, pid_gtot_E, pid_gtot_W
727 integer :: pid_bt_rem_u, pid_Datu, pid_BT_force_u, pid_Cor_ref
728 integer :: pid_eta_PF_1, pid_d_eta_PF, pid_uhbt0
729 integer :: isv, iev, jsv, jev
731 integer :: isvf, ievf, jsvf, jevf, num_cycles
732 integer :: i, j, k, n
733 integer :: is, ie, js, je, nz, Isq, Ieq, Jsq, Jeq
734 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
736 if (.not.
associated(cs))
call mom_error(fatal, &
737 "legacy_btstep: Module MOM_legacy_barotropic must be initialized before it is used.")
738 if (.not.cs%split)
return 739 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
740 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
741 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
742 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
743 ms%isdw = cs%isdw ; ms%iedw = cs%iedw ; ms%jsdw = cs%jsdw ; ms%jedw = cs%jedw
746 use_bt_cont = .false.
747 if (
present(bt_cont)) use_bt_cont = (
associated(bt_cont))
749 interp_eta_pf = .false.
750 if (
present(eta_pf_start)) interp_eta_pf = (
associated(eta_pf_start))
752 project_velocity = cs%BT_project_velocity
756 if ((.not.use_bt_cont) .and. cs%Nonlinear_continuity .and. &
757 (cs%Nonlin_cont_update_period > 0)) stencil = 2
760 if (cs%use_wide_halos) &
761 num_cycles = min((is-cs%isdw) / stencil, (js-cs%jsdw) / stencil)
762 isvf = is - (num_cycles-1)*stencil ; ievf = ie + (num_cycles-1)*stencil
763 jsvf = js - (num_cycles-1)*stencil ; jevf = je + (num_cycles-1)*stencil
765 do_ave = query_averaging_enabled(cs%diag)
766 find_etaav =
present(etaav)
767 use_visc_rem =
present(visc_rem_u)
768 if ((use_visc_rem) .neqv.
present(visc_rem_v))
call mom_error(fatal, &
769 "btstep: Either both visc_rem_u and visc_rem_v or neither"// &
770 " one must be present in call to btstep.")
771 find_pf = (do_ave .and. ((cs%id_PFu_bt > 0) .or. (cs%id_PFv_bt > 0)))
772 find_cor = (do_ave .and. ((cs%id_Coru_bt > 0) .or. (cs%id_Corv_bt > 0)))
775 if (
present(uh0)) add_uh0 =
associated(uh0)
776 if (add_uh0 .and. .not.(
present(vh0) .and.
present(u_uh0) .and. &
778 "legacy_btstep: vh0, u_uh0, and v_vh0 must be present if uh0 is used.")
779 if (add_uh0 .and. .not.(
associated(vh0) .and.
associated(u_uh0) .and. &
780 associated(v_vh0)))
call mom_error(fatal, &
781 "legacy_btstep: vh0, u_uh0, and v_vh0 must be associated if uh0 is used.")
782 if (add_uh0 .and. use_fluxes)
call mom_error(warning, &
783 "legacy_btstep: with use_fluxes, add_uh0 does nothing!")
784 if (use_fluxes) add_uh0 = .false.
787 nonblock_setup = g%nonblocking_updates
792 apply_obc_flather = .false.
793 if (
present(obc))
then ;
if (
associated(obc))
then 794 apply_u_obcs = obc%Flather_u_BCs_exist_globally .or. obc%specified_u_BCs_exist_globally
795 apply_v_obcs = obc%Flather_v_BCs_exist_globally .or. obc%specified_v_BCs_exist_globally
796 apply_obc_flather = obc%Flather_u_BCs_exist_globally .or. obc%Flather_v_BCs_exist_globally
797 apply_obcs = obc%specified_u_BCs_exist_globally .or. obc%specified_v_BCs_exist_globally .or. apply_obc_flather
799 if (apply_obc_flather .and. .not.gv%Boussinesq)
call mom_error(fatal, &
800 "legacy_btstep: Flather open boundary conditions have not yet been "// &
801 "implemented for a non-Boussinesq model.")
804 nstep = ceiling(dt/cs%dtbt - 0.0001)
805 if (
is_root_pe() .and. (nstep /= cs%nstep_last))
then 806 write(mesg,
'("legacy_btstep is using a dynamic barotropic timestep of ", ES12.6, & 807 & " seconds, max ", ES12.6, ".")') (dt/nstep), cs%dtbt_max
810 cs%nstep_last = nstep
813 instep = 1.0 /
real(nstep)
818 do_ave = query_averaging_enabled(cs%diag)
820 do_hifreq_output = .false.
821 if ((cs%id_ubt_hifreq > 0) .or. (cs%id_vbt_hifreq > 0) .or. &
822 (cs%id_eta_hifreq > 0) .or. (cs%id_eta_pred_hifreq > 0) .or. &
823 (cs%id_uhbt_hifreq > 0) .or. (cs%id_vhbt_hifreq > 0))
then 824 do_hifreq_output = query_averaging_enabled(cs%diag, time_int_in, time_end_in)
825 if (do_hifreq_output) &
826 time_bt_start = time_end_in - set_time(int(floor(dt+0.5)))
832 if (cs%linearized_BT_PV)
then 834 do j=jsvf-2,jevf+1 ;
do i=isvf-2,ievf+1
838 do j=jsvf-1,jevf+1 ;
do i=isvf-2,ievf+1
839 dcor_u(i,j) = cs%D_u_Cor(i,j)
842 do j=jsvf-2,jevf+1 ;
do i=isvf-1,ievf+1
843 dcor_v(i,j) = cs%D_v_Cor(i,j)
846 q(:,:) = 0.0 ; dcor_u(:,:) = 0.0 ; dcor_v(:,:) = 0.0
850 do j=js,je ;
do i=is-1,ie
851 dcor_u(i,j) = 0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j))
854 do j=js-1,je ;
do i=is,ie
855 dcor_v(i,j) = 0.5 * (g%bathyT(i,j+1) + g%bathyT(i,j))
858 do j=js-1,je ;
do i=is-1,ie
859 q(i,j) = 0.25 * g%CoriolisBu(i,j) * &
860 ((g%areaT(i,j) + g%areaT(i+1,j+1)) + (g%areaT(i+1,j) + g%areaT(i,j+1))) / &
861 ((g%areaT(i,j) * g%bathyT(i,j) + g%areaT(i+1,j+1) * g%bathyT(i+1,j+1)) + &
862 (g%areaT(i+1,j) * g%bathyT(i+1,j) + g%areaT(i,j+1) * g%bathyT(i,j+1)))
870 if (nonblock_setup)
then 874 call pass_var(q, cs%BT_Domain, to_all, position=corner)
875 call pass_vector(dcor_u, dcor_v, cs%BT_Domain, to_all+scalar_pair)
881 if (nonblock_setup)
then 884 if ((.not.use_bt_cont) .and. cs%rescale_D_bt .and. (ievf>ie))
then 895 do j=cs%jsdw,cs%jedw ;
do i=cs%isdw,cs%iedw
896 gtot_e(i,j) = 0.0 ; gtot_w(i,j) = 0.0
897 gtot_n(i,j) = 0.0 ; gtot_s(i,j) = 0.0
900 if (interp_eta_pf)
then 901 eta_pf_1(i,j) = 0.0 ; d_eta_pf(i,j) = 0.0
903 p_surf_dyn(i,j) = 0.0
904 if (cs%dynamic_psurf) dyn_coef_eta(i,j) = 0.0
909 do j=cs%jsdw,cs%jedw ;
do i=cs%isdw-1,cs%iedw
910 cor_ref_u(i,j) = 0.0 ; bt_force_u(i,j) = 0.0 ; ubt(i,j) = 0.0
911 datu(i,j) = 0.0 ; bt_rem_u(i,j) = 0.0 ; uhbt0(i,j) = 0.0
913 do j=cs%jsdw-1,cs%jedw ;
do i=cs%isdw,cs%iedw
914 cor_ref_v(i,j) = 0.0 ; bt_force_v(i,j) = 0.0 ; vbt(i,j) = 0.0
915 datv(i,j) = 0.0 ; bt_rem_v(i,j) = 0.0 ; vhbt0(i,j) = 0.0
920 if (interp_eta_pf)
then 921 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
922 eta(i,j) = eta_in(i,j)
923 eta_pf_1(i,j) = eta_pf_start(i,j)
924 d_eta_pf(i,j) = eta_pf_in(i,j) - eta_pf_start(i,j)
927 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
928 eta(i,j) = eta_in(i,j)
929 eta_pf(i,j) = eta_pf_in(i,j)
933 if (use_visc_rem)
then 935 do k=1,nz ;
do j=js-1,je+1 ;
do i=isq-1,ieq+1
938 if (visc_rem_u(i,j,k) <= 0.0)
then ; visc_rem = 0.0
939 elseif (visc_rem_u(i,j,k) >= 1.0)
then ; visc_rem = 1.0
940 elseif (visc_rem_u(i,j,k)**2 > visc_rem_u(i,j,k) - 0.5*instep)
then 941 visc_rem = visc_rem_u(i,j,k)
942 else ; visc_rem = 1.0 - 0.5*instep/visc_rem_u(i,j,k) ;
endif 943 wt_u(i,j,k) = cs%frhatu(i,j,k) * visc_rem
944 enddo ;
enddo ;
enddo 946 do k=1,nz ;
do j=jsq-1,jeq+1 ;
do i=is-1,ie+1
948 if (visc_rem_v(i,j,k) <= 0.0)
then ; visc_rem = 0.0
949 elseif (visc_rem_v(i,j,k) >= 1.0)
then ; visc_rem = 1.0
950 elseif (visc_rem_v(i,j,k)**2 > visc_rem_v(i,j,k) - 0.5*instep)
then 951 visc_rem = visc_rem_v(i,j,k)
952 else ; visc_rem = 1.0 - 0.5*instep/visc_rem_v(i,j,k) ;
endif 953 wt_v(i,j,k) = cs%frhatv(i,j,k) * visc_rem
954 enddo ;
enddo ;
enddo 956 do k=1,nz ;
do j=js-1,je+1 ;
do i=isq-1,ieq+1
957 wt_u(i,j,k) = cs%frhatu(i,j,k)
958 enddo ;
enddo ;
enddo 959 do k=1,nz ;
do j=jsq-1,jeq+1 ;
do i=is-1,ie+1
960 wt_v(i,j,k) = cs%frhatv(i,j,k)
961 enddo ;
enddo ;
enddo 969 do j=js,je ;
do i=is-1,ie
970 gtot_e(i,j) = gtot_e(i,j) + pbce(i,j,k) * wt_u(i,j,k)
971 gtot_w(i+1,j) = gtot_w(i+1,j) + pbce(i+1,j,k) * wt_u(i,j,k)
973 do j=js-1,je ;
do i=is,ie
974 gtot_n(i,j) = gtot_n(i,j) + pbce(i,j,k) * wt_v(i,j,k)
975 gtot_s(i,j+1) = gtot_s(i,j+1) + pbce(i,j+1,k) * wt_v(i,j,k)
981 dgeo_de = 1.0 + det_de + cs%G_extra
983 dgeo_de = 1.0 + cs%G_extra
986 if (nonblock_setup .and. .not.cs%linearized_BT_PV)
then 997 if (use_bt_cont)
then 1000 if (cs%rescale_D_bt .and. (ievf>ie))
then 1005 if (nonblock_setup)
then 1007 cs%BT_Domain, to_all+scalar_pair)
1009 call pass_vector(cs%Datu_res, cs%Datv_res, cs%BT_Domain, to_all+scalar_pair)
1014 if (cs%Nonlinear_continuity)
then 1015 call find_face_areas(datu, datv, g, gv, cs, ms, cs%rescale_D_bt, eta, 1)
1017 call find_face_areas(datu, datv, g, gv, cs, ms, cs%rescale_D_bt, halo=1)
1022 if (apply_obcs)
then 1023 call set_up_bt_obc(obc, eta, bt_obc, g, gv, ms, ievf-ie, use_bt_cont, &
1024 datu, datv, btcl_u, btcl_v)
1033 if (use_visc_rem)
then 1034 do j=js,je ;
do i=is-1,ie
1035 bt_force_u(i,j) = fluxes%taux(i,j) * i_rho0*cs%IDatu(i,j)*visc_rem_u(i,j,1)
1037 do j=js-1,je ;
do i=is,ie
1038 bt_force_v(i,j) = fluxes%tauy(i,j) * i_rho0*cs%IDatv(i,j)*visc_rem_v(i,j,1)
1041 do j=js,je ;
do i=is-1,ie
1042 bt_force_u(i,j) = fluxes%taux(i,j) * i_rho0 * cs%IDatu(i,j)
1044 do j=js-1,je ;
do i=is,ie
1045 bt_force_v(i,j) = fluxes%tauy(i,j) * i_rho0 * cs%IDatv(i,j)
1048 if (
present(taux_bot) .and.
present(tauy_bot))
then 1049 if (
associated(taux_bot) .and.
associated(tauy_bot))
then 1050 do j=js,je ;
do i=is-1,ie
1051 bt_force_u(i,j) = bt_force_u(i,j) - taux_bot(i,j) * i_rho0 * cs%IDatu(i,j)
1053 do j=js-1,je ;
do i=is,ie
1054 bt_force_v(i,j) = bt_force_v(i,j) - tauy_bot(i,j) * i_rho0 * cs%IDatv(i,j)
1061 do k=1,nz ;
do j=js,je ;
do i=isq,ieq
1062 bt_force_u(i,j) = bt_force_u(i,j) + wt_u(i,j,k) * bc_accel_u(i,j,k)
1063 enddo ;
enddo ;
enddo 1064 do k=1,nz ;
do j=jsq,jeq ;
do i=is,ie
1065 bt_force_v(i,j) = bt_force_v(i,j) + wt_v(i,j,k) * bc_accel_v(i,j,k)
1066 enddo ;
enddo ;
enddo 1071 do j=js,je ;
do i=is-1,ie ; uhbt(i,j) = 0.0 ; ubt(i,j) = 0.0 ;
enddo ;
enddo 1072 do j=js-1,je ;
do i=is,ie ; vhbt(i,j) = 0.0 ; vbt(i,j) = 0.0 ;
enddo ;
enddo 1073 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
1074 uhbt(i,j) = uhbt(i,j) + uh0(i,j,k)
1075 ubt(i,j) = ubt(i,j) + wt_u(i,j,k) * u_uh0(i,j,k)
1076 enddo ;
enddo ;
enddo 1077 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
1078 vhbt(i,j) = vhbt(i,j) + vh0(i,j,k)
1079 vbt(i,j) = vbt(i,j) + wt_v(i,j,k) * v_vh0(i,j,k)
1080 enddo ;
enddo ;
enddo 1081 if (use_bt_cont)
then 1082 do j=js,je ;
do i=is-1,ie
1083 uhbt0(i,j) = uhbt(i,j) -
find_uhbt(ubt(i,j),btcl_u(i,j))
1085 do j=js-1,je ;
do i=is,ie
1086 vhbt0(i,j) = vhbt(i,j) -
find_vhbt(vbt(i,j),btcl_v(i,j))
1089 do j=js,je ;
do i=is-1,ie
1090 uhbt0(i,j) = uhbt(i,j) - datu(i,j)*ubt(i,j)
1092 do j=js-1,je ;
do i=is,ie
1093 vhbt0(i,j) = vhbt(i,j) - datv(i,j)*vbt(i,j)
1099 do j=jsvf-1,jevf+1 ;
do i=isvf-2,ievf+1
1100 ubt(i,j) = 0.0 ; uhbt(i,j) = 0.0 ; u_accel_bt(i,j) = 0.0
1102 do j=jsvf-2,jevf+1 ;
do i=isvf-1,ievf+1
1103 vbt(i,j) = 0.0 ; vhbt(i,j) = 0.0 ; v_accel_bt(i,j) = 0.0
1105 if (use_fluxes)
then 1106 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
1107 uhbt(i,j) = uhbt(i,j) + u_in(i,j,k)
1108 enddo ;
enddo ;
enddo 1109 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
1110 vhbt(i,j) = vhbt(i,j) + v_in(i,j,k)
1111 enddo ;
enddo ;
enddo 1112 if (use_bt_cont)
then 1113 do j=js,je ;
do i=is-1,ie
1114 ubt(i,j) =
uhbt_to_ubt(uhbt(i,j),btcl_u(i,j), guess=cs%ubt_IC(i,j))
1116 do j=js-1,je ;
do i=is,ie
1117 vbt(i,j) =
vhbt_to_vbt(vhbt(i,j),btcl_v(i,j), guess=cs%vbt_IC(i,j))
1120 do j=js,je ;
do i=is-1,ie
1121 ubt(i,j) = 0.0 ;
if (datu(i,j) > 0.0) ubt(i,j) = uhbt(i,j) / datu(i,j)
1123 do j=js-1,je ;
do i=is,ie
1124 vbt(i,j) = 0.0 ;
if (datv(i,j) > 0.0) vbt(i,j) = vhbt(i,j) / datv(i,j)
1128 do k=1,nz ;
do j=js,je ;
do i=is-1,ie
1129 ubt(i,j) = ubt(i,j) + wt_u(i,j,k) * u_in(i,j,k)
1130 enddo ;
enddo ;
enddo 1131 do k=1,nz ;
do j=js-1,je ;
do i=is,ie
1132 vbt(i,j) = vbt(i,j) + wt_v(i,j,k) * v_in(i,j,k)
1133 enddo ;
enddo ;
enddo 1136 if (cs%gradual_BT_ICs)
then 1137 if (use_fluxes)
then 1138 if (use_bt_cont)
then 1139 do j=js,je ;
do i=is-1,ie
1140 vel_tmp =
uhbt_to_ubt(cs%uhbt_IC(i,j),btcl_u(i,j), guess=cs%ubt_IC(i,j))
1141 bt_force_u(i,j) = bt_force_u(i,j) + (ubt(i,j) - vel_tmp) * idt
1144 do j=js-1,je ;
do i=is,ie
1145 vel_tmp =
vhbt_to_vbt(cs%vhbt_IC(i,j),btcl_v(i,j), guess=cs%vbt_IC(i,j))
1146 bt_force_v(i,j) = bt_force_v(i,j) + (vbt(i,j) - vel_tmp) * idt
1150 do j=js,je ;
do i=is-1,ie
1151 vel_tmp = 0.0 ;
if (datu(i,j) > 0.0) vel_tmp = cs%uhbt_IC(i,j) / datu(i,j)
1152 bt_force_u(i,j) = bt_force_u(i,j) + (ubt(i,j) - vel_tmp) * idt
1155 do j=js-1,je ;
do i=is,ie
1156 vel_tmp = 0.0 ;
if (datv(i,j) > 0.0) vel_tmp = cs%vhbt_IC(i,j) / datv(i,j)
1157 bt_force_v(i,j) = bt_force_v(i,j) + (vbt(i,j) - vel_tmp) * idt
1162 do j=js,je ;
do i=is-1,ie
1163 bt_force_u(i,j) = bt_force_u(i,j) + (ubt(i,j) - cs%ubt_IC(i,j)) * idt
1164 ubt(i,j) = cs%ubt_IC(i,j)
1166 do j=js-1,je ;
do i=is,ie
1167 bt_force_v(i,j) = bt_force_v(i,j) + (vbt(i,j) - cs%vbt_IC(i,j)) * idt
1168 vbt(i,j) = cs%vbt_IC(i,j)
1173 if ((isq > is-1) .or. (jsq > js-1))
then 1178 tmp_u(:,:) = 0.0 ; tmp_v(:,:) = 0.0
1179 do j=js,je ;
do i=isq,ieq ; tmp_u(i,j) = bt_force_u(i,j) ;
enddo ;
enddo 1180 do j=jsq,jeq ;
do i=is,ie ; tmp_v(i,j) = bt_force_v(i,j) ;
enddo ;
enddo 1181 if (nonblock_setup)
then 1184 call pass_vector(tmp_u, tmp_v, g%Domain, complete=.true.)
1185 do j=jsd,jed ;
do i=isdb,iedb ; bt_force_u(i,j) = tmp_u(i,j) ;
enddo ;
enddo 1186 do j=jsdb,jedb ;
do i=isd,ied ; bt_force_v(i,j) = tmp_v(i,j) ;
enddo ;
enddo 1192 if (nonblock_setup)
then 1196 to_all+scalar_pair, agrid, complete=.false.)
1198 to_all+scalar_pair, agrid)
1205 do j=jsvf-1,jevf ;
do i=isvf-1,ievf+1
1206 if (cs%Sadourny)
then 1207 amer(i-1,j) = dcor_u(i-1,j) * q(i-1,j)
1208 bmer(i,j) = dcor_u(i,j) * q(i,j)
1209 cmer(i,j+1) = dcor_u(i,j+1) * q(i,j)
1210 dmer(i-1,j+1) = dcor_u(i-1,j+1) * q(i-1,j)
1212 amer(i-1,j) = dcor_u(i-1,j) * &
1213 ((q(i,j) + q(i-1,j-1)) + q(i-1,j)) / 3.0
1214 bmer(i,j) = dcor_u(i,j) * &
1215 (q(i,j) + (q(i-1,j) + q(i,j-1))) / 3.0
1216 cmer(i,j+1) = dcor_u(i,j+1) * &
1217 (q(i,j) + (q(i-1,j) + q(i,j+1))) / 3.0
1218 dmer(i-1,j+1) = dcor_u(i-1,j+1) * &
1219 ((q(i,j) + q(i-1,j+1)) + q(i-1,j)) / 3.0
1224 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf
1225 if (cs%Sadourny)
then 1226 azon(i,j) = dcor_v(i+1,j) * q(i,j)
1227 bzon(i,j) = dcor_v(i,j) * q(i,j)
1228 czon(i,j) = dcor_v(i,j-1) * q(i,j-1)
1229 dzon(i,j) = dcor_v(i+1,j-1) * q(i,j-1)
1231 azon(i,j) = dcor_v(i+1,j) * &
1232 (q(i,j) + (q(i+1,j) + q(i,j-1))) / 3.0
1233 bzon(i,j) = dcor_v(i,j) * &
1234 (q(i,j) + (q(i-1,j) + q(i,j-1))) / 3.0
1235 czon(i,j) = dcor_v(i,j-1) * &
1236 ((q(i,j) + q(i-1,j-1)) + q(i,j-1)) / 3.0
1237 dzon(i,j) = dcor_v(i+1,j-1) * &
1238 ((q(i,j) + q(i+1,j-1)) + q(i,j-1)) / 3.0
1244 if (use_fluxes)
then 1245 do j=js-1,je+1 ;
do i=is-1,ie ; uhbt(i,j) = 0.0 ;
enddo ;
enddo 1246 do j=js-1,je ;
do i=is-1,ie+1 ; vhbt(i,j) = 0.0 ;
enddo ;
enddo 1247 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie
1248 uhbt(i,j) = uhbt(i,j) + u_cor(i,j,k)
1249 enddo ;
enddo ;
enddo 1250 do k=1,nz ;
do j=js-1,je ;
do i=is-1,ie+1
1251 vhbt(i,j) = vhbt(i,j) + v_cor(i,j,k)
1252 enddo ;
enddo ;
enddo 1253 if (use_bt_cont)
then 1254 do j=js-1,je+1 ;
do i=is-1,ie
1255 ubt_cor(i,j) =
uhbt_to_ubt(uhbt(i,j), btcl_u(i,j), guess=cs%ubtav(i,j))
1257 do j=js-1,je ;
do i=is-1,ie+1
1258 vbt_cor(i,j) =
vhbt_to_vbt(vhbt(i,j), btcl_v(i,j), guess=cs%vbtav(i,j))
1261 do j=js-1,je+1 ;
do i=is-1,ie
1262 ubt_cor(i,j) = 0.0 ;
if (datu(i,j)>0.0) ubt_cor(i,j) = uhbt(i,j)/datu(i,j)
1264 do j=js-1,je ;
do i=is-1,ie+1
1265 vbt_cor(i,j) = 0.0 ;
if (datv(i,j)>0.0) vbt_cor(i,j) = vhbt(i,j)/datv(i,j)
1269 do j=js-1,je+1 ;
do i=is-1,ie ; ubt_cor(i,j) = 0.0 ;
enddo ;
enddo 1270 do j=js-1,je ;
do i=is-1,ie+1 ; vbt_cor(i,j) = 0.0 ;
enddo ;
enddo 1271 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie
1272 ubt_cor(i,j) = ubt_cor(i,j) + wt_u(i,j,k) * u_cor(i,j,k)
1273 enddo ;
enddo ;
enddo 1274 do k=1,nz ;
do j=js-1,je ;
do i=is-1,ie+1
1275 vbt_cor(i,j) = vbt_cor(i,j) + wt_v(i,j,k) * v_cor(i,j,k)
1276 enddo ;
enddo ;
enddo 1280 do j=js,je ;
do i=is-1,ie
1282 ((azon(i,j) * vbt_cor(i+1,j) + czon(i,j) * vbt_cor(i ,j-1)) + &
1283 (bzon(i,j) * vbt_cor(i ,j) + dzon(i,j) * vbt_cor(i+1,j-1)))
1286 do j=js-1,je ;
do i=is,ie
1287 cor_ref_v(i,j) = -1.0 * &
1288 ((amer(i-1,j) * ubt_cor(i-1,j) + cmer(i ,j+1) * ubt_cor(i ,j+1)) + &
1289 (bmer(i ,j) * ubt_cor(i ,j) + dmer(i-1,j+1) * ubt_cor(i-1,j+1)))
1295 if (nonblock_setup)
then 1296 if ((isq > is-1) .or. (jsq > js-1))
then 1298 do j=jsd,jed ;
do i=isdb,iedb ; bt_force_u(i,j) = tmp_u(i,j) ;
enddo ;
enddo 1299 do j=jsdb,jedb ;
do i=isd,ied ; bt_force_v(i,j) = tmp_v(i,j) ;
enddo ;
enddo 1304 call pass_vector(gtot_e, gtot_n, cs%BT_Domain, to_all+scalar_pair, agrid, complete=.false.)
1305 call pass_vector(gtot_w, gtot_s, cs%BT_Domain, to_all+scalar_pair, agrid, complete=.true.)
1309 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf+1
1310 if (cs%ua_polarity(i,j) < 0.0)
call swap(gtot_e(i,j), gtot_w(i,j))
1311 if (cs%va_polarity(i,j) < 0.0)
call swap(gtot_n(i,j), gtot_s(i,j))
1315 if (nonblock_setup)
then 1316 if (.not.use_bt_cont) &
1319 if (((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) .or. (isq <= is-1) .or. (jsq <= js-1)) &
1328 do j=js-1,je+1 ;
do i=is-1,ie ; bt_rem_u(i,j) = g%mask2dCu(i,j) ;
enddo ;
enddo 1329 do j=js-1,je ;
do i=is-1,ie+1 ; bt_rem_v(i,j) = g%mask2dCv(i,j) ;
enddo ;
enddo 1330 if ((use_visc_rem) .and. (cs%drag_amp > 0.0))
then 1331 do j=js-1,je+1 ;
do i=is-1,ie ; av_rem_u(i,j) = 0.0 ;
enddo ;
enddo 1332 do j=js-1,je ;
do i=is-1,ie+1 ; av_rem_v(i,j) = 0.0 ;
enddo ;
enddo 1333 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie
1334 av_rem_u(i,j) = av_rem_u(i,j) + cs%frhatu(i,j,k) * visc_rem_u(i,j,k)
1335 enddo ;
enddo ;
enddo 1336 do k=1,nz ;
do j=js-1,je ;
do i=is-1,ie+1
1337 av_rem_v(i,j) = av_rem_v(i,j) + cs%frhatv(i,j,k) * visc_rem_v(i,j,k)
1338 enddo ;
enddo ;
enddo 1339 if (cs%strong_drag)
then 1340 do j=js-1,je+1 ;
do i=is-1,ie
1341 bt_rem_u(i,j) = g%mask2dCu(i,j) * cs%drag_amp * &
1342 ((nstep * av_rem_u(i,j)) / (1.0 + (nstep-1)*av_rem_u(i,j)))
1344 do j=js-1,je ;
do i=is-1,ie+1
1345 bt_rem_v(i,j) = g%mask2dCv(i,j) * cs%drag_amp * &
1346 ((nstep * av_rem_v(i,j)) / (1.0 + (nstep-1)*av_rem_v(i,j)))
1349 do j=js-1,je+1 ;
do i=is-1,ie
1351 if (g%mask2dCu(i,j) * av_rem_u(i,j) > 0.0) &
1352 bt_rem_u(i,j) = g%mask2dCu(i,j) * cs%drag_amp * (av_rem_u(i,j)**instep)
1354 do j=js-1,je ;
do i=is-1,ie+1
1356 if (g%mask2dCv(i,j) * av_rem_v(i,j) > 0.0) &
1357 bt_rem_v(i,j) = g%mask2dCv(i,j) * cs%drag_amp * (av_rem_v(i,j)**instep)
1363 if (find_etaav)
then ;
do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf+1
1364 eta_sum(i,j) = 0.0 ; eta_wtd(i,j) = 0.0
1365 enddo ;
enddo ;
else ;
do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf+1
1367 enddo ;
enddo ;
endif 1368 do j=jsvf-1,jevf+1 ;
do i=isvf-1,ievf
1369 ubt_sum(i,j) = 0.0 ; uhbt_sum(i,j) = 0.0
1370 pfu_bt_sum(i,j) = 0.0 ; coru_bt_sum(i,j) = 0.0
1371 ubt_wtd(i,j) = 0.0 ; ubt_trans(i,j) = 0.0
1373 do j=jsvf-1,jevf ;
do i=isvf-1,ievf+1
1374 vbt_sum(i,j) = 0.0 ; vhbt_sum(i,j) = 0.0
1375 pfv_bt_sum(i,j) = 0.0 ; corv_bt_sum(i,j) = 0.0
1376 vbt_wtd(i,j) = 0.0 ; vbt_trans(i,j) = 0.0
1380 do j=jsvf-1,jevf+1;
do i=isvf-1,ievf+1 ; eta_src(i,j) = 0.0 ;
enddo ;
enddo 1381 if (cs%bound_BT_corr)
then ;
do j=js,je ;
do i=is,ie
1382 if (abs(cs%eta_cor(i,j)) > dt*cs%eta_cor_bound(i,j)) &
1383 cs%eta_cor(i,j) = sign(dt*cs%eta_cor_bound(i,j),cs%eta_cor(i,j))
1384 enddo ;
enddo ;
endif 1385 do j=js,je ;
do i=is,ie
1386 eta_src(i,j) = g%mask2dT(i,j) * (instep * cs%eta_cor(i,j) + dtbt * cs%eta_source(i,j))
1389 if (cs%dynamic_psurf)
then 1390 ice_is_rigid = (
associated(fluxes%rigidity_ice_u) .and. &
1391 associated(fluxes%rigidity_ice_v))
1392 h_min_dyn = gv%m_to_H * cs%Dmin_dyn_psurf
1393 if (ice_is_rigid .and. use_bt_cont) &
1395 if (ice_is_rigid)
then ;
do j=js,je ;
do i=is,ie
1401 idt_max2 = 0.5 * (dgeo_de * (1.0 + 2.0*bebt)) * (g%IareaT(i,j) * &
1402 ((gtot_e(i,j) * (datu(i,j)*g%IdxCu(i,j)) + &
1403 gtot_w(i,j) * (datu(i-1,j)*g%IdxCu(i-1,j))) + &
1404 (gtot_n(i,j) * (datv(i,j)*g%IdyCv(i,j)) + &
1405 gtot_s(i,j) * (datv(i,j-1)*g%IdyCv(i,j-1)))) + &
1406 ((g%CoriolisBu(i,j)**2 + g%CoriolisBu(i-1,j-1)**2) + &
1407 (g%CoriolisBu(i-1,j)**2 + g%CoriolisBu(i,j-1)**2)))
1408 h_eff_dx2 = max(h_min_dyn * (g%IdxT(i,j)**2 + g%IdyT(i,j)**2), &
1410 ((datu(i,j)*g%IdxCu(i,j) + datu(i-1,j)*g%IdxCu(i-1,j)) + &
1411 (datv(i,j)*g%IdyCv(i,j) + datv(i,j-1)*g%IdyCv(i,j-1)) ) )
1412 dyn_coef_max = cs%const_dyn_psurf * max(0.0, 1.0 - dtbt**2 * idt_max2) / &
1413 (dtbt**2 * h_eff_dx2)
1416 ice_strength = ((fluxes%rigidity_ice_u(i,j) + fluxes%rigidity_ice_u(i-1,j)) + &
1417 (fluxes%rigidity_ice_v(i,j) + fluxes%rigidity_ice_v(i,j-1))) / &
1418 (cs%ice_strength_length**2 * dtbt)
1421 dyn_coef_eta(i,j) = min(dyn_coef_max, ice_strength * gv%H_to_m)
1422 enddo ;
enddo ;
endif 1427 if (nonblock_setup)
then 1428 if (cs%dynamic_psurf) pid_dyn_coef_eta = &
1430 if (interp_eta_pf)
then 1431 pid_eta_pf_1 =
pass_var_start(eta_pf_1, cs%BT_Domain, complete=.false.)
1432 pid_d_eta_pf =
pass_var_start(d_eta_pf, cs%BT_Domain, complete=.false.)
1434 if ((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) &
1435 pid_eta_pf =
pass_var_start(eta_pf, cs%BT_Domain, complete=.false.)
1444 if (interp_eta_pf)
then 1445 call pass_var(eta_pf_1, cs%BT_Domain, complete=.false.)
1446 call pass_var(d_eta_pf, cs%BT_Domain, complete=.false.)
1450 if ((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) &
1451 call pass_var(eta_pf, cs%BT_Domain, complete=.false.)
1453 if (cs%dynamic_psurf)
call pass_var(dyn_coef_eta, cs%BT_Domain, complete=.false.)
1456 call pass_vector(bt_rem_u, bt_rem_v, cs%BT_Domain, to_all+scalar_pair)
1457 if (.not.use_bt_cont) &
1458 call pass_vector(datu, datv, cs%BT_Domain, to_all+scalar_pair)
1459 if (((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) .or. (isq <= is-1) .or. (jsq <= js-1)) &
1460 call pass_vector(bt_force_u, bt_force_v, cs%BT_Domain, complete=.false.)
1461 if (g%nonblocking_updates)
then 1462 call pass_var(eta_src, cs%BT_Domain, complete=.true.)
1463 if (add_uh0)
call pass_vector(uhbt0, vhbt0, cs%BT_Domain, complete=.false.)
1464 call pass_vector(cor_ref_u, cor_ref_v, cs%BT_Domain, complete=.true.)
1466 call pass_var(eta_src, cs%BT_Domain, complete=.false.)
1467 if (add_uh0)
call pass_vector(uhbt0, vhbt0, cs%BT_Domain, complete=.false.)
1468 call pass_vector(cor_ref_u, cor_ref_v, cs%BT_Domain, complete=.false.)
1475 if (nonblock_setup)
then 1479 if (.not.use_bt_cont) &
1482 if (((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) .or. (isq <= is-1) .or. (jsq <= js-1)) &
1487 if (cs%dynamic_psurf) &
1489 if (interp_eta_pf)
then 1493 if ((g%isd > cs%isdw) .or. (g%jsd > cs%jsdw)) &
1507 call uvchksum(
"BT [uv]hbt", uhbt, vhbt, cs%debug_BT_HI, haloshift=0)
1508 call uvchksum(
"BT Initial [uv]bt", ubt, vbt, cs%debug_BT_HI, haloshift=0)
1509 call hchksum(eta,
"BT Initial eta",cs%debug_BT_HI, haloshift=0, scale=gv%H_to_m)
1510 call uvchksum(
"BT BT_force_[uv]", &
1511 bt_force_u, bt_force_v, cs%debug_BT_HI, haloshift=0)
1512 if (interp_eta_pf)
then 1513 call hchksum(eta_pf_1,
"BT eta_PF_1",cs%debug_BT_HI,haloshift=0, scale=gv%H_to_m)
1514 call hchksum(d_eta_pf,
"BT d_eta_PF",cs%debug_BT_HI,haloshift=0, scale=gv%H_to_m)
1516 call hchksum(eta_pf,
"BT eta_PF",cs%debug_BT_HI,haloshift=0, scale=gv%H_to_m)
1517 call hchksum(eta_pf_in,
"BT eta_PF_in",g%HI,haloshift=0, scale=gv%H_to_m)
1519 call uvchksum(
"BT Cor_ref_[uv]", cor_ref_u, cor_ref_v, &
1520 cs%debug_BT_HI, haloshift=0)
1521 call uvchksum(
"BT [uv]hbt0", uhbt0, vhbt0, cs%debug_BT_HI, haloshift=0, scale=gv%H_to_m)
1522 if (.not. use_bt_cont)
then 1523 call uvchksum(
"BT Dat[uv]", datu, datv, &
1524 cs%debug_BT_HI,haloshift=1, scale=gv%H_to_m)
1526 call uvchksum(
"BT wt_[uv]", wt_u, wt_v, g%HI,haloshift=1)
1527 call uvchksum(
"BT frhat[uv]", cs%frhatu, cs%frhatv, g%HI, haloshift=1)
1528 call uvchksum(
"BT bc_accel_[uv]", bc_accel_u, bc_accel_v, g%HI,haloshift=0)
1529 call uvchksum(
"BT IDat[uv]", cs%IDatu, cs%IDatv, g%HI,haloshift=0)
1530 if (use_visc_rem)
then 1531 call uvchksum(
"BT visc_rem_[uv]", visc_rem_u, visc_rem_v, g%HI, haloshift=1)
1535 if (query_averaging_enabled(cs%diag))
then 1536 if (cs%id_eta_st > 0)
call post_data(cs%id_eta_st, eta(isd:ied,jsd:jed), cs%diag)
1537 if (cs%id_ubt_st > 0)
call post_data(cs%id_ubt_st, ubt(isdb:iedb,jsd:jed), cs%diag)
1538 if (cs%id_vbt_st > 0)
call post_data(cs%id_vbt_st, vbt(isd:ied,jsdb:jedb), cs%diag)
1544 if (project_velocity)
then ; eta_pf_bt => eta ;
else ; eta_pf_bt => eta_pred ;
endif 1546 if (cs%dt_bt_filter >= 0.0)
then 1547 dt_filt = 0.5 * max(0.0, min(cs%dt_bt_filter, 2.0*dt))
1549 dt_filt = 0.5 * max(0.0, dt * min(-cs%dt_bt_filter, 2.0))
1551 nfilter = ceiling(dt_filt / dtbt)
1554 sum_wt_vel = 0.0 ; sum_wt_eta = 0.0 ; sum_wt_accel = 0.0 ; sum_wt_trans = 0.0
1555 allocate(wt_vel(nstep+nfilter)) ;
allocate(wt_eta(nstep+nfilter))
1556 allocate(wt_trans(nstep+nfilter+1)) ;
allocate(wt_accel(nstep+nfilter+1))
1557 allocate(wt_accel2(nstep+nfilter+1))
1558 do n=1,nstep+nfilter
1560 if ( (n==nstep) .or. (dt_filt - abs(n-nstep)*dtbt >= 0.0))
then 1561 wt_vel(n) = 1.0 ; wt_eta(n) = 1.0
1562 elseif (dtbt + dt_filt - abs(n-nstep)*dtbt > 0.0)
then 1563 wt_vel(n) = 1.0 + (dt_filt / dtbt) - abs(n-nstep) ; wt_eta(n) = wt_vel(n)
1565 wt_vel(n) = 0.0 ; wt_eta(n) = 0.0
1571 sum_wt_vel = sum_wt_vel + wt_vel(n) ; sum_wt_eta = sum_wt_eta + wt_eta(n)
1573 wt_trans(nstep+nfilter+1) = 0.0 ; wt_accel(nstep+nfilter+1) = 0.0
1574 do n=nstep+nfilter,1,-1
1575 wt_trans(n) = wt_trans(n+1) + wt_eta(n)
1576 wt_accel(n) = wt_accel(n+1) + wt_vel(n)
1577 sum_wt_accel = sum_wt_accel + wt_accel(n) ; sum_wt_trans = sum_wt_trans + wt_trans(n)
1580 i_sum_wt_vel = 1.0 / sum_wt_vel ; i_sum_wt_accel = 1.0 / sum_wt_accel
1581 i_sum_wt_eta = 1.0 / sum_wt_eta ; i_sum_wt_trans = 1.0 / sum_wt_trans
1582 do n=1,nstep+nfilter
1583 wt_vel(n) = wt_vel(n) * i_sum_wt_vel
1584 wt_accel2(n) = wt_accel(n)
1585 wt_accel(n) = wt_accel(n) * i_sum_wt_accel
1586 wt_eta(n) = wt_eta(n) * i_sum_wt_eta
1591 sum_wt_vel = 0.0 ; sum_wt_eta = 0.0 ; sum_wt_accel = 0.0 ; sum_wt_trans = 0.0
1594 isv=is ; iev=ie ; jsv=js ; jev=je
1595 do n=1,nstep+nfilter
1597 sum_wt_vel = sum_wt_vel + wt_vel(n)
1598 sum_wt_eta = sum_wt_eta + wt_eta(n)
1599 sum_wt_accel = sum_wt_accel + wt_accel2(n)
1600 sum_wt_trans = sum_wt_trans + wt_trans(n)
1602 if (cs%clip_velocity)
then 1603 do j=jsv,jev ;
do i=isv-1,iev
1604 if (abs(ubt(i,j)) > cs%maxvel)
then 1606 ubt(i,j) = sign(cs%maxvel,ubt(i,j))
1609 do j=jsv-1,jev ;
do i=isv,iev
1610 if (abs(vbt(i,j)) > cs%maxvel)
then 1612 vbt(i,j) = sign(cs%maxvel,vbt(i,j))
1617 if ((iev - stencil < ie) .or. (jev - stencil < je))
then 1620 if (g%nonblocking_updates)
then 1629 isv = isvf ; iev = ievf ; jsv = jsvf ; jev = jevf
1633 isv = isv+stencil ; iev = iev-stencil
1634 jsv = jsv+stencil ; jev = jev-stencil
1637 if ((.not.use_bt_cont) .and. cs%Nonlinear_continuity .and. &
1638 (cs%Nonlin_cont_update_period > 0))
then 1639 if ((n>1) .and. (mod(n-1,cs%Nonlin_cont_update_period) == 0)) &
1640 call find_face_areas(datu, datv, g, gv, cs, ms, cs%rescale_D_bt, eta, 1+iev-ie)
1643 if (cs%dynamic_psurf .or. .not.project_velocity)
then 1644 if (use_bt_cont)
then 1646 do j=jsv-1,jev+1 ;
do i=isv-2,iev+1
1647 uhbt(i,j) =
find_uhbt(ubt(i,j),btcl_u(i,j)) + uhbt0(i,j)
1649 do j=jsv-2,jev+1 ;
do i=isv-1,iev+1
1650 vhbt(i,j) =
find_vhbt(vbt(i,j),btcl_v(i,j)) + vhbt0(i,j)
1652 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1653 eta_pred(i,j) = (eta(i,j) + eta_src(i,j)) + (dtbt * cs%IareaT(i,j)) * &
1654 ((uhbt(i-1,j) - uhbt(i,j)) + (vhbt(i,j-1) - vhbt(i,j)))
1659 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1660 eta_pred(i,j) = (eta(i,j) + eta_src(i,j)) + (dtbt * cs%IareaT(i,j)) * &
1661 (((datu(i-1,j)*ubt(i-1,j) + uhbt0(i-1,j)) - &
1662 (datu(i,j)*ubt(i,j) + uhbt0(i,j))) + &
1663 ((datv(i,j-1)*vbt(i,j-1) + vhbt0(i,j-1)) - &
1664 (datv(i,j)*vbt(i,j) + vhbt0(i,j))))
1668 if (cs%dynamic_psurf)
then ;
do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1669 p_surf_dyn(i,j) = dyn_coef_eta(i,j) * (eta_pred(i,j) - eta(i,j))
1670 enddo ;
enddo ;
endif 1676 if (find_etaav)
then ;
do j=js,je ;
do i=is,ie
1677 eta_sum(i,j) = eta_sum(i,j) + wt_accel2(n) * eta_pf_bt(i,j)
1678 enddo ;
enddo ;
endif 1680 if (interp_eta_pf)
then 1682 do j=jsv-1,jev+1 ;
do i=isv-1,iev+1
1683 eta_pf(i,j) = eta_pf_1(i,j) + wt_end*d_eta_pf(i,j)
1687 if (apply_obc_flather)
then 1689 do j=jsv,jev ;
do i=isv-2,iev+1
1690 ubt_old(i,j) = ubt(i,j)
1693 do j=jsv-2,jev+1 ;
do i=isv,iev
1694 vbt_old(i,j) = vbt(i,j)
1710 if (mod(n+g%first_direction,2)==1)
then 1713 do j=jsv-1,jev ;
do i=isv-1,iev+1
1714 cor = -1.0*((amer(i-1,j) * ubt(i-1,j) + cmer(i,j+1) * ubt(i,j+1)) + &
1715 (bmer(i,j) * ubt(i,j) + dmer(i-1,j+1) * ubt(i-1,j+1))) - cor_ref_v(i,j)
1716 gradp = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_n(i,j) - &
1717 (eta_pf_bt(i,j+1)-eta_pf(i,j+1))*gtot_s(i,j+1)) * &
1718 dgeo_de * cs%IdyCv(i,j)
1719 if (cs%dynamic_psurf) &
1720 gradp = gradp + (p_surf_dyn(i,j) - p_surf_dyn(i,j+1)) * cs%IdyCv(i,j)
1721 v_accel_bt(i,j) = v_accel_bt(i,j) + wt_accel(n) * (cor + gradp)
1722 if (find_pf) pfv_bt_sum(i,j) = pfv_bt_sum(i,j) + wt_accel2(n) * gradp
1723 if (find_cor) corv_bt_sum(i,j) = corv_bt_sum(i,j) + wt_accel2(n) * cor
1725 if (
apply_v_obcs)
then ;
if (obc%segnum_v(i,j) /= obc_none) cycle ;
endif 1728 vbt(i,j) = bt_rem_v(i,j) * (vbt(i,j) + &
1729 dtbt * ((bt_force_v(i,j) + cor) + gradp))
1730 if (project_velocity)
then 1731 vel_trans = (1.0 + be_proj)*vbt(i,j) - be_proj*vel_prev
1733 vel_trans = (1.0-bebt)*vel_prev + bebt*vbt(i,j)
1735 if (use_bt_cont)
then 1736 vhbt(i,j) =
find_vhbt(vel_trans,btcl_v(i,j)) + vhbt0(i,j)
1738 vhbt(i,j) = datv(i,j)*vel_trans + vhbt0(i,j)
1741 vbt_sum(i,j) = vbt_sum(i,j) + wt_trans(n) * vel_trans
1742 vhbt_sum(i,j) = vhbt_sum(i,j) + wt_trans(n) * vhbt(i,j)
1743 vbt_wtd(i,j) = vbt_wtd(i,j) + wt_vel(n) * vbt(i,j)
1747 do j=jsv,jev ;
do i=isv-1,iev
1748 cor = ((azon(i,j) * vbt(i+1,j) + czon(i,j) * vbt(i,j-1)) + &
1749 (bzon(i,j) * vbt(i,j) + dzon(i,j) * vbt(i+1,j-1))) - cor_ref_u(i,j)
1750 gradp = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_e(i,j) - &
1751 (eta_pf_bt(i+1,j)-eta_pf(i+1,j))*gtot_w(i+1,j)) * &
1752 dgeo_de * cs%IdxCu(i,j)
1753 if (cs%dynamic_psurf) &
1754 gradp = gradp + (p_surf_dyn(i,j) - p_surf_dyn(i+1,j)) * cs%IdxCu(i,j)
1755 u_accel_bt(i,j) = u_accel_bt(i,j) + wt_accel(n) * (cor + gradp)
1756 if (find_pf) pfu_bt_sum(i,j) = pfu_bt_sum(i,j) + wt_accel2(n) * gradp
1757 if (find_cor) coru_bt_sum(i,j) = coru_bt_sum(i,j) + wt_accel2(n) * cor
1759 if (
apply_u_obcs)
then ;
if (obc%segnum_u(i,j) /= obc_none) cycle ;
endif 1762 ubt(i,j) = bt_rem_u(i,j) * (ubt(i,j) + &
1763 dtbt * ((bt_force_u(i,j) + cor) + gradp))
1764 if (project_velocity)
then 1765 vel_trans = (1.0 + be_proj)*ubt(i,j) - be_proj*vel_prev
1767 vel_trans = (1.0-bebt)*vel_prev + bebt*ubt(i,j)
1769 if (use_bt_cont)
then 1770 uhbt(i,j) =
find_uhbt(vel_trans, btcl_u(i,j)) + uhbt0(i,j)
1772 uhbt(i,j) = datu(i,j)*vel_trans + uhbt0(i,j)
1775 ubt_sum(i,j) = ubt_sum(i,j) + wt_trans(n) * vel_trans
1776 uhbt_sum(i,j) = uhbt_sum(i,j) + wt_trans(n) * uhbt(i,j)
1777 ubt_wtd(i,j) = ubt_wtd(i,j) + wt_vel(n) * ubt(i,j)
1783 do j=jsv-1,jev+1 ;
do i=isv-1,iev
1784 cor = ((azon(i,j) * vbt(i+1,j) + czon(i,j) * vbt(i,j-1)) + &
1785 (bzon(i,j) * vbt(i,j) + dzon(i,j) * vbt(i+1,j-1))) - cor_ref_u(i,j)
1786 gradp = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_e(i,j) - &
1787 (eta_pf_bt(i+1,j)-eta_pf(i+1,j))*gtot_w(i+1,j)) * &
1788 dgeo_de * cs%IdxCu(i,j)
1789 if (cs%dynamic_psurf) &
1790 gradp = gradp + (p_surf_dyn(i,j) - p_surf_dyn(i+1,j)) * cs%IdxCu(i,j)
1791 u_accel_bt(i,j) = u_accel_bt(i,j) + wt_accel(n) * (cor + gradp)
1792 if (find_pf) pfu_bt_sum(i,j) = pfu_bt_sum(i,j) + wt_accel2(n) * gradp
1793 if (find_cor) coru_bt_sum(i,j) = coru_bt_sum(i,j) + wt_accel2(n) * cor
1795 if (
apply_u_obcs)
then ;
if (obc%segnum_u(i,j) /= obc_none) cycle ;
endif 1798 ubt(i,j) = bt_rem_u(i,j) * (ubt(i,j) + &
1799 dtbt * ((bt_force_u(i,j) + cor) + gradp))
1800 if (project_velocity)
then 1801 vel_trans = (1.0 + be_proj)*ubt(i,j) - be_proj*vel_prev
1803 vel_trans = (1.0-bebt)*vel_prev + bebt*ubt(i,j)
1805 if (use_bt_cont)
then 1806 uhbt(i,j) =
find_uhbt(vel_trans,btcl_u(i,j)) + uhbt0(i,j)
1808 uhbt(i,j) = datu(i,j)*vel_trans + uhbt0(i,j)
1811 ubt_sum(i,j) = ubt_sum(i,j) + wt_trans(n) * vel_trans
1812 uhbt_sum(i,j) = uhbt_sum(i,j) + wt_trans(n) * uhbt(i,j)
1813 ubt_wtd(i,j) = ubt_wtd(i,j) + wt_vel(n) * ubt(i,j)
1817 do j=jsv-1,jev ;
do i=isv,iev
1818 cor = -1.0*((amer(i-1,j) * ubt(i-1,j) + bmer(i,j) * ubt(i,j)) + &
1819 (cmer(i,j+1) * ubt(i,j+1) + dmer(i-1,j+1) * ubt(i-1,j+1))) - cor_ref_v(i,j)
1820 gradp = ((eta_pf_bt(i,j)-eta_pf(i,j))*gtot_n(i,j) - &
1821 (eta_pf_bt(i,j+1)-eta_pf(i,j+1))*gtot_s(i,j+1)) * &
1822 dgeo_de * cs%IdyCv(i,j)
1823 if (cs%dynamic_psurf) &
1824 gradp = gradp + (p_surf_dyn(i,j) - p_surf_dyn(i,j+1)) * cs%IdyCv(i,j)
1825 v_accel_bt(i,j) = v_accel_bt(i,j) + wt_accel(n) * (cor + gradp)
1826 if (find_pf) pfv_bt_sum(i,j) = pfv_bt_sum(i,j) + wt_accel2(n) * gradp
1827 if (find_cor) corv_bt_sum(i,j) = corv_bt_sum(i,j) + wt_accel2(n) * cor
1829 if (
apply_v_obcs)
then ;
if (obc%segnum_v(i,j) /= obc_none) cycle ;
endif 1832 vbt(i,j) = bt_rem_v(i,j) * (vbt(i,j) + &
1833 dtbt * ((bt_force_v(i,j) + cor) + gradp))
1834 if (project_velocity)
then 1835 vel_trans = (1.0 + be_proj)*vbt(i,j) - be_proj*vel_prev
1837 vel_trans = (1.0-bebt)*vel_prev + bebt*vbt(i,j)
1839 if (use_bt_cont)
then 1840 vhbt(i,j) =
find_vhbt(vel_trans,btcl_v(i,j)) + vhbt0(i,j)
1842 vhbt(i,j) = datv(i,j)*vel_trans + vhbt0(i,j)
1845 vbt_sum(i,j) = vbt_sum(i,j) + wt_trans(n) * vel_trans
1846 vhbt_sum(i,j) = vhbt_sum(i,j) + wt_trans(n) * vhbt(i,j)
1847 vbt_wtd(i,j) = vbt_wtd(i,j) + wt_vel(n) * vbt(i,j)
1852 if (apply_obcs)
then 1854 ubt_trans, vbt_trans, eta, ubt_old, vbt_old, bt_obc, &
1855 g, ms, iev-ie, dtbt, bebt, use_bt_cont, datu, datv, btcl_u, btcl_v, &
1858 if (obc%segnum_u(i,j) /= obc_none)
then 1859 ubt_sum(i,j) = ubt_sum(i,j) + wt_trans(n) * ubt_trans(i,j)
1860 uhbt_sum(i,j) = uhbt_sum(i,j) + wt_trans(n) * uhbt(i,j)
1861 ubt_wtd(i,j) = ubt_wtd(i,j) + wt_vel(n) * ubt(i,j)
1863 enddo ;
enddo ;
endif 1865 if (obc%segnum_v(i,j) /= obc_none)
then 1866 vbt_sum(i,j) = vbt_sum(i,j) + wt_trans(n) * vbt_trans(i,j)
1867 vhbt_sum(i,j) = vhbt_sum(i,j) + wt_trans(n) * vhbt(i,j)
1868 vbt_wtd(i,j) = vbt_wtd(i,j) + wt_vel(n) * vbt(i,j)
1870 enddo ;
enddo ;
endif 1873 if (cs%debug_bt)
then 1874 call uvchksum(
"BT [uv]hbt just after OBC", &
1875 uhbt, vhbt, cs%debug_BT_HI, haloshift=iev-ie)
1879 do j=jsv,jev ;
do i=isv,iev
1880 eta(i,j) = (eta(i,j) + eta_src(i,j)) + (dtbt * cs%IareaT(i,j)) * &
1881 ((uhbt(i-1,j) - uhbt(i,j)) + (vhbt(i,j-1) - vhbt(i,j)))
1882 eta_wtd(i,j) = eta_wtd(i,j) + eta(i,j) * wt_eta(n)
1884 if (apply_obcs)
call apply_eta_obcs(obc, eta, ubt_old, vbt_old, bt_obc, &
1885 g, ms, iev-ie, dtbt)
1887 if (do_hifreq_output)
then 1888 time_step_end = time_bt_start + set_time(int(floor(n*dtbt+0.5)))
1890 if (cs%id_ubt_hifreq > 0)
call post_data(cs%id_ubt_hifreq, ubt(isdb:iedb,jsd:jed), cs%diag)
1891 if (cs%id_vbt_hifreq > 0)
call post_data(cs%id_vbt_hifreq, vbt(isd:ied,jsdb:jedb), cs%diag)
1892 if (cs%id_eta_hifreq > 0)
call post_data(cs%id_eta_hifreq, eta(isd:ied,jsd:jed), cs%diag)
1893 if (cs%id_uhbt_hifreq > 0)
call post_data(cs%id_uhbt_hifreq, uhbt(isdb:iedb,jsd:jed), cs%diag)
1894 if (cs%id_vhbt_hifreq > 0)
call post_data(cs%id_vhbt_hifreq, vhbt(isd:ied,jsdb:jedb), cs%diag)
1895 if (cs%id_eta_pred_hifreq > 0)
call post_data(cs%id_eta_pred_hifreq, eta_pf_bt(isd:ied,jsd:jed), cs%diag)
1898 if (cs%debug_bt)
then 1899 write(mesg,
'("BT step ",I4)') n
1900 call uvchksum(trim(mesg)//
" [uv]bt", &
1901 ubt, vbt, cs%debug_BT_HI, haloshift=iev-ie)
1902 call hchksum(eta, trim(mesg)//
" eta", cs%debug_BT_HI, haloshift=iev-ie, scale=gv%H_to_m)
1910 if (do_hifreq_output)
call enable_averaging(time_int_in, time_end_in, cs%diag)
1912 i_sum_wt_vel = 1.0 / sum_wt_vel ; i_sum_wt_eta = 1.0 / sum_wt_eta
1913 i_sum_wt_accel = 1.0 / sum_wt_accel ; i_sum_wt_trans = 1.0 / sum_wt_trans
1915 if (find_etaav)
then ;
do j=js,je ;
do i=is,ie
1916 etaav(i,j) = eta_sum(i,j) * i_sum_wt_accel
1917 enddo ;
enddo ;
endif 1918 do j=js-1,je+1 ;
do i=is-1,ie+1 ; e_anom(i,j) = 0.0 ;
enddo ;
enddo 1919 if (interp_eta_pf)
then 1920 do j=js,je ;
do i=is,ie
1921 e_anom(i,j) = dgeo_de * (0.5 * (eta(i,j) + eta_in(i,j)) - &
1922 (eta_pf_1(i,j) + 0.5*d_eta_pf(i,j)))
1925 do j=js,je ;
do i=is,ie
1926 e_anom(i,j) = dgeo_de * (0.5 * (eta(i,j) + eta_in(i,j)) - eta_pf(i,j))
1931 do j=js,je ;
do i=is,ie
1932 eta_out(i,j) = eta_wtd(i,j) * i_sum_wt_eta
1937 if (g%nonblocking_updates)
then 1940 if (find_etaav)
call pass_var(etaav, g%Domain, complete=.false.)
1946 do j=js,je ;
do i=is-1,ie
1947 cs%ubtav(i,j) = ubt_sum(i,j) * i_sum_wt_trans
1948 uhbtav(i,j) = uhbt_sum(i,j) * i_sum_wt_trans
1950 ubt_wtd(i,j) = ubt_wtd(i,j) * i_sum_wt_vel
1953 do j=js-1,je ;
do i=is,ie
1954 cs%vbtav(i,j) = vbt_sum(i,j) * i_sum_wt_trans
1955 vhbtav(i,j) = vhbt_sum(i,j) * i_sum_wt_trans
1957 vbt_wtd(i,j) = vbt_wtd(i,j) * i_sum_wt_vel
1960 if (
present(uhbt_out))
then 1962 if (use_bt_cont)
then ;
do j=js,je ;
do i=is-1,ie
1963 uhbt_out(i,j) =
find_uhbt(ubt_wtd(i,j), btcl_u(i,j)) + uhbt0(i,j)
1964 enddo ;
enddo ;
else ;
do j=js,je ;
do i=is-1,ie
1965 uhbt_out(i,j) = ubt_wtd(i,j) * datu(i,j) + uhbt0(i,j)
1966 enddo ;
enddo ;
endif 1969 if (use_bt_cont)
then ;
do j=js-1,je ;
do i=is,ie
1970 vhbt_out(i,j) =
find_vhbt(vbt_wtd(i,j), btcl_v(i,j)) + vhbt0(i,j)
1971 enddo ;
enddo ;
else ;
do j=js-1,je ;
do i=is,ie
1972 vhbt_out(i,j) = vbt_wtd(i,j) * datv(i,j) + vhbt0(i,j)
1973 enddo ;
enddo ;
endif 1978 if (g%nonblocking_updates)
then 1985 call pass_vector(cs%ubtav, cs%vbtav, g%Domain, complete=.false.)
1996 do j=js,je ;
do i=is-1,ie
1997 accel_layer_u(i,j,k) = u_accel_bt(i,j) - &
1998 ((pbce(i+1,j,k) - gtot_w(i+1,j)) * e_anom(i+1,j) - &
1999 (pbce(i,j,k) - gtot_e(i,j)) * e_anom(i,j)) * cs%IdxCu(i,j)
2001 do j=js-1,je ;
do i=is,ie
2002 accel_layer_v(i,j,k) = v_accel_bt(i,j) - &
2003 ((pbce(i,j+1,k) - gtot_s(i,j+1))*e_anom(i,j+1) - &
2004 (pbce(i,j,k) - gtot_n(i,j))*e_anom(i,j)) * cs%IdyCv(i,j)
2011 if (query_averaging_enabled(cs%diag))
then 2013 do j=js,je ;
do i=is-1,ie ; cs%ubt_IC(i,j) = ubt_wtd(i,j) ;
enddo ;
enddo 2014 do j=js-1,je ;
do i=is,ie ; cs%vbt_IC(i,j) = vbt_wtd(i,j) ;
enddo ;
enddo 2015 if (
present(uhbt_out))
then 2016 do j=js,je ;
do i=is-1,ie ; cs%uhbt_IC(i,j) = uhbt_out(i,j) ;
enddo ;
enddo 2017 do j=js-1,je ;
do i=is,ie ; cs%vhbt_IC(i,j) = vhbt_out(i,j) ;
enddo ;
enddo 2018 elseif (use_bt_cont)
then 2019 do j=js,je ;
do i=is-1,ie
2020 cs%uhbt_IC(i,j) =
find_uhbt(ubt_wtd(i,j), btcl_u(i,j)) + uhbt0(i,j)
2022 do j=js-1,je ;
do i=is,ie
2023 cs%vhbt_IC(i,j) =
find_vhbt(vbt_wtd(i,j), btcl_v(i,j)) + vhbt0(i,j)
2026 do j=js,je ;
do i=is-1,ie
2027 cs%uhbt_IC(i,j) = ubt_wtd(i,j) * datu(i,j) + uhbt0(i,j)
2029 do j=js-1,je ;
do i=is,ie
2030 cs%vhbt_IC(i,j) = vbt_wtd(i,j) * datv(i,j) + vhbt0(i,j)
2035 if (cs%id_PFu_bt > 0)
then 2036 do j=js,je ;
do i=is-1,ie
2037 pfu_bt_sum(i,j) = pfu_bt_sum(i,j) * i_sum_wt_accel
2039 call post_data(cs%id_PFu_bt, pfu_bt_sum(isdb:iedb,jsd:jed), cs%diag)
2041 if (cs%id_PFv_bt > 0)
then 2042 do j=js-1,je ;
do i=is,ie
2043 pfv_bt_sum(i,j) = pfv_bt_sum(i,j) * i_sum_wt_accel
2045 call post_data(cs%id_PFv_bt, pfv_bt_sum(isd:ied,jsdb:jedb), cs%diag)
2047 if (cs%id_Coru_bt > 0)
then 2048 do j=js,je ;
do i=is-1,ie
2049 coru_bt_sum(i,j) = coru_bt_sum(i,j) * i_sum_wt_accel
2051 call post_data(cs%id_Coru_bt, coru_bt_sum(isdb:iedb,jsd:jed), cs%diag)
2053 if (cs%id_Corv_bt > 0)
then 2054 do j=js-1,je ;
do i=is,ie
2055 corv_bt_sum(i,j) = corv_bt_sum(i,j) * i_sum_wt_accel
2057 call post_data(cs%id_Corv_bt, corv_bt_sum(isd:ied,jsdb:jedb), cs%diag)
2059 if (cs%id_ubtforce > 0)
call post_data(cs%id_ubtforce, bt_force_u(isdb:iedb,jsd:jed), cs%diag)
2060 if (cs%id_vbtforce > 0)
call post_data(cs%id_vbtforce, bt_force_v(isd:ied,jsdb:jedb), cs%diag)
2061 if (cs%id_uaccel > 0)
call post_data(cs%id_uaccel, u_accel_bt(isdb:iedb,jsd:jed), cs%diag)
2062 if (cs%id_vaccel > 0)
call post_data(cs%id_vaccel, v_accel_bt(isd:ied,jsdb:jedb), cs%diag)
2063 if (cs%id_Datu_res > 0)
call post_data(cs%id_Datu_res, cs%Datu_res(isdb:iedb,jsd:jed), cs%diag)
2064 if (cs%id_Datv_res > 0)
call post_data(cs%id_Datv_res, cs%Datv_res(isd:ied,jsdb:jedb), cs%diag)
2066 if (cs%id_eta_cor > 0)
call post_data(cs%id_eta_cor, cs%eta_cor, cs%diag)
2067 if (cs%id_eta_bt > 0)
call post_data(cs%id_eta_bt, eta_out, cs%diag)
2068 if (cs%id_gtotn > 0)
call post_data(cs%id_gtotn, gtot_n(isd:ied,jsd:jed), cs%diag)
2069 if (cs%id_gtots > 0)
call post_data(cs%id_gtots, gtot_s(isd:ied,jsd:jed), cs%diag)
2070 if (cs%id_gtote > 0)
call post_data(cs%id_gtote, gtot_e(isd:ied,jsd:jed), cs%diag)
2071 if (cs%id_gtotw > 0)
call post_data(cs%id_gtotw, gtot_w(isd:ied,jsd:jed), cs%diag)
2072 if (cs%id_ubt > 0)
call post_data(cs%id_ubt, ubt_wtd(isdb:iedb,jsd:jed), cs%diag)
2073 if (cs%id_vbt > 0)
call post_data(cs%id_vbt, vbt_wtd(isd:ied,jsdb:jedb), cs%diag)
2074 if (cs%id_ubtav > 0)
call post_data(cs%id_ubtav, cs%ubtav, cs%diag)
2075 if (cs%id_vbtav > 0)
call post_data(cs%id_vbtav, cs%vbtav, cs%diag)
2076 if (use_visc_rem)
then 2077 if (cs%id_visc_rem_u > 0)
call post_data(cs%id_visc_rem_u, visc_rem_u, cs%diag)
2078 if (cs%id_visc_rem_v > 0)
call post_data(cs%id_visc_rem_v, visc_rem_v, cs%diag)
2081 if (cs%id_frhatu > 0)
call post_data(cs%id_frhatu, cs%frhatu, cs%diag)
2082 if (cs%id_uhbt > 0)
call post_data(cs%id_uhbt, uhbtav, cs%diag)
2083 if (cs%id_frhatv > 0)
call post_data(cs%id_frhatv, cs%frhatv, cs%diag)
2084 if (cs%id_vhbt > 0)
call post_data(cs%id_vhbt, vhbtav, cs%diag)
2086 if (cs%id_frhatu1 > 0)
call post_data(cs%id_frhatu1, cs%frhatu1, cs%diag)
2087 if (cs%id_frhatv1 > 0)
call post_data(cs%id_frhatv1, cs%frhatv1, cs%diag)
2089 if (cs%id_frhatu1 > 0) cs%frhatu1(:,:,:) = cs%frhatu(:,:,:)
2090 if (cs%id_frhatv1 > 0) cs%frhatv1(:,:,:) = cs%frhatv(:,:,:)
2093 if (g%nonblocking_updates)
then 2103 subroutine legacy_set_dtbt(G, GV, CS, eta, pbce, BT_cont, gtot_est, SSH_add)
2104 type(ocean_grid_type),
intent(inout) :: G
2105 type(verticalgrid_type),
intent(in) :: GV
2109 real,
dimension(SZI_(G),SZJ_(G)), &
2110 intent(in),
optional :: eta
2112 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
2113 intent(in),
optional :: pbce
2115 type(bt_cont_type),
pointer,
optional :: BT_cont
2117 real,
intent(in),
optional :: gtot_est
2119 real,
intent(in),
optional :: SSH_add
2138 real,
dimension(SZI_(G),SZJ_(G)) :: &
2145 real,
dimension(SZIBS_(G),SZJ_(G)) :: &
2148 real,
dimension(SZI_(G),SZJBS_(G)) :: &
2160 real :: min_max_dt2, Idt_max2, dtbt_max
2161 logical :: use_BT_cont
2164 character(len=200) :: mesg
2165 integer :: i, j, k, is, ie, js, je, nz
2167 if (.not.
associated(cs))
call mom_error(fatal, &
2168 "legacy_set_dtbt: Module MOM_barotropic must be initialized before it is used.")
2169 if (.not.cs%split)
return 2170 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2171 ms%isdw = g%isd ; ms%iedw = g%ied ; ms%jsdw = g%jsd ; ms%jedw = g%jed
2173 if (.not.(
present(pbce) .or.
present(gtot_est)))
call mom_error(fatal, &
2174 "legacy_set_dtbt: Either pbce or gtot_est must be present.")
2176 add_ssh = 0.0 ;
if (
present(ssh_add)) add_ssh = ssh_add
2178 use_bt_cont = .false.
2179 if (
present(bt_cont)) use_bt_cont = (
associated(bt_cont))
2181 if (use_bt_cont)
then 2183 elseif (cs%Nonlinear_continuity .and.
present(eta))
then 2186 call find_face_areas(datu, datv, g, gv, cs, ms, halo=0, add_max=add_ssh)
2190 if (cs%tides)
call tidal_forcing_sensitivity(g, cs%tides_CSp, det_de)
2191 dgeo_de = 1.0 + max(0.0, det_de + cs%G_extra)
2192 if (
present(pbce))
then 2193 do j=js,je ;
do i=is,ie
2194 gtot_e(i,j) = 0.0 ; gtot_w(i,j) = 0.0
2195 gtot_n(i,j) = 0.0 ; gtot_s(i,j) = 0.0
2197 do k=1,nz ;
do j=js,je ;
do i=is,ie
2198 gtot_e(i,j) = gtot_e(i,j) + pbce(i,j,k) * cs%frhatu(i,j,k)
2199 gtot_w(i,j) = gtot_w(i,j) + pbce(i,j,k) * cs%frhatu(i-1,j,k)
2200 gtot_n(i,j) = gtot_n(i,j) + pbce(i,j,k) * cs%frhatv(i,j,k)
2201 gtot_s(i,j) = gtot_s(i,j) + pbce(i,j,k) * cs%frhatv(i,j-1,k)
2202 enddo ;
enddo ;
enddo 2204 do j=js,je ;
do i=is,ie
2205 gtot_e(i,j) = gtot_est * gv%H_to_m ; gtot_w(i,j) = gtot_est * gv%H_to_m
2206 gtot_n(i,j) = gtot_est * gv%H_to_m ; gtot_s(i,j) = gtot_est * gv%H_to_m
2210 min_max_dt2 = 1.0e38
2211 do j=js,je ;
do i=is,ie
2214 idt_max2 = 0.5 * (1.0 + 2.0*cs%bebt) * (g%IareaT(i,j) * &
2215 ((gtot_e(i,j)*datu(i,j)*g%IdxCu(i,j) + gtot_w(i,j)*datu(i-1,j)*g%IdxCu(i-1,j)) + &
2216 (gtot_n(i,j)*datv(i,j)*g%IdyCv(i,j) + gtot_s(i,j)*datv(i,j-1)*g%IdyCv(i,j-1))) + &
2217 ((g%CoriolisBu(i,j)**2 + g%CoriolisBu(i-1,j-1)**2) + &
2218 (g%CoriolisBu(i-1,j)**2 + g%CoriolisBu(i,j-1)**2)))
2219 if (idt_max2 * min_max_dt2 > 1.0) min_max_dt2 = 1.0 / idt_max2
2221 dtbt_max = sqrt(min_max_dt2 / dgeo_de)
2223 call min_across_pes(dtbt_max)
2226 cs%dtbt = cs%dtbt_fraction * dtbt_max
2227 cs%dtbt_max = dtbt_max
2234 eta, ubt_old, vbt_old, BT_OBC, &
2235 G, MS, halo, dtbt, bebt, use_BT_cont, Datu, Datv, &
2236 BTCL_u, BTCL_v, uhbt0, vhbt0)
2237 type(ocean_obc_type),
pointer :: OBC
2239 type(ocean_grid_type),
intent(inout) :: G
2242 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(inout) :: ubt
2244 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(inout) :: uhbt
2246 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(inout) :: ubt_trans
2248 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(inout) :: vbt
2250 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(inout) :: vhbt
2252 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(inout) :: vbt_trans
2254 real,
dimension(SZIW_(MS),SZJW_(MS)),
intent(in) :: eta
2256 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: ubt_old
2258 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: vbt_old
2263 integer,
intent(in) :: halo
2265 real,
intent(in) :: dtbt
2266 real,
intent(in) :: bebt
2268 logical,
intent(in) :: use_BT_cont
2270 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: Datu
2272 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: Datv
2275 intent(in) :: BTCL_u
2278 intent(in) :: BTCL_v
2280 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: uhbt0
2281 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: vhbt0
2318 integer :: i, j, is, ie, js, je
2319 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
2322 do j=js,je ;
do i=is-1,ie ;
if (obc%segnum_u(i,j) /= obc_none)
then 2323 if (obc%segment(obc%segnum_u(i,j))%specified)
then 2324 uhbt(i,j) = bt_obc%uhbt(i,j)
2325 ubt(i,j) = bt_obc%ubt_outer(i,j)
2326 vel_trans = ubt(i,j)
2327 elseif (obc%segment(obc%segnum_u(i,j))%Flather)
then 2328 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2329 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2330 u_inlet = cfl*ubt_old(i-1,j) + (1.0-cfl)*ubt_old(i,j)
2332 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i-1,j))
2334 h_u = bt_obc%H_u(i,j)
2336 ubt(i,j) = 0.5*((u_inlet + bt_obc%ubt_outer(i,j)) + &
2337 (bt_obc%Cg_u(i,j)/h_u) * (h_in-bt_obc%eta_outer_u(i,j)))
2339 vel_trans = (1.0-bebt)*vel_prev + bebt*ubt(i,j)
2340 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2341 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2342 u_inlet = cfl*ubt_old(i+1,j) + (1.0-cfl)*ubt_old(i,j)
2344 h_in = eta(i+1,j) + (0.5-cfl)*(eta(i+1,j)-eta(i+2,j))
2346 h_u = bt_obc%H_u(i,j)
2348 ubt(i,j) = 0.5*((u_inlet+bt_obc%ubt_outer(i,j)) + &
2349 (bt_obc%Cg_u(i,j)/h_u) * (bt_obc%eta_outer_u(i,j)-h_in))
2351 vel_trans = (1.0-bebt)*vel_prev + bebt*ubt(i,j)
2352 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_n)
then 2353 if ((vbt(i,j-1)+vbt(i+1,j-1)) > 0.0)
then 2354 ubt(i,j) = 2.0*ubt(i,j-1)-ubt(i,j-2)
2356 ubt(i,j) = bt_obc%ubt_outer(i,j)
2358 vel_trans = ubt(i,j)
2359 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_s)
then 2360 if ((vbt(i,j)+vbt(i+1,j)) < 0.0)
then 2361 ubt(i,j) = 2.0*ubt(i,j+1)-ubt(i,j+2)
2363 ubt(i,j) = bt_obc%ubt_outer(i,j)
2365 vel_trans = ubt(i,j)
2369 if (.not. obc%segment(obc%segnum_u(i,j))%specified)
then 2370 if (use_bt_cont)
then 2371 uhbt(i,j) =
find_uhbt(vel_trans,btcl_u(i,j)) + uhbt0(i,j)
2373 uhbt(i,j) = datu(i,j)*vel_trans + uhbt0(i,j)
2377 ubt_trans(i,j) = vel_trans
2378 endif ;
enddo ;
enddo 2382 do j=js-1,je ;
do i=is,ie ;
if (obc%segnum_v(i,j) /= obc_none)
then 2383 if (obc%segment(obc%segnum_v(i,j))%specified)
then 2384 vhbt(i,j) = bt_obc%vhbt(i,j)
2385 vbt(i,j) = bt_obc%vbt_outer(i,j)
2386 vel_trans = vbt(i,j)
2387 elseif (obc%segment(obc%segnum_v(i,j))%Flather)
then 2388 if (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_n)
then 2389 cfl = dtbt * bt_obc%Cg_v(i,j) * g%IdyCv(i,j)
2390 v_inlet = cfl*vbt_old(i,j-1) + (1.0-cfl)*vbt_old(i,j)
2392 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i,j-1))
2394 h_v = bt_obc%H_v(i,j)
2396 vbt(i,j) = 0.5*((v_inlet+bt_obc%vbt_outer(i,j)) + &
2397 (bt_obc%Cg_v(i,j)/h_v) * (h_in-bt_obc%eta_outer_v(i,j)))
2399 vel_trans = (1.0-bebt)*vel_prev + bebt*vbt(i,j)
2400 elseif (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_s)
then 2401 cfl = dtbt * bt_obc%Cg_v(i,j) * g%IdyCv(i,j)
2402 v_inlet = cfl*vbt_old(i,j+1) + (1.0-cfl)*vbt_old(i,j)
2404 h_in = eta(i,j+1) + (0.5-cfl)*(eta(i,j+1)-eta(i,j+2))
2406 h_v = bt_obc%H_v(i,j)
2408 vbt(i,j) = 0.5*((v_inlet+bt_obc%vbt_outer(i,j)) + &
2409 (bt_obc%Cg_v(i,j)/h_v) * (bt_obc%eta_outer_v(i,j)-h_in))
2411 vel_trans = (1.0-bebt)*vel_prev + bebt*vbt(i,j)
2412 elseif (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_e)
then 2413 if ((ubt(i-1,j)+ubt(i-1,j+1)) > 0.0)
then 2414 vbt(i,j) = 2.0*vbt(i-1,j)-vbt(i-2,j)
2416 vbt(i,j) = bt_obc%vbt_outer(i,j)
2418 vel_trans = vbt(i,j)
2423 elseif (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_w)
then 2424 if ((ubt(i,j)+ubt(i,j+1)) < 0.0)
then 2425 vbt(i,j) = 2.0*vbt(i+1,j)-vbt(i+2,j)
2427 vbt(i,j) = bt_obc%vbt_outer(i,j)
2429 vel_trans = vbt(i,j)
2437 if (obc%segnum_v(i,j) /= obc_simple)
then 2438 if (use_bt_cont)
then 2439 vhbt(i,j) =
find_vhbt(vel_trans,btcl_v(i,j)) + vhbt0(i,j)
2441 vhbt(i,j) = vel_trans*datv(i,j) + vhbt0(i,j)
2445 vbt_trans(i,j) = vel_trans
2446 endif ;
enddo ;
enddo 2453 subroutine apply_eta_obcs(OBC, eta, ubt, vbt, BT_OBC, G, MS, halo, dtbt)
2454 type(ocean_obc_type),
pointer :: OBC
2458 real,
dimension(SZIW_(MS),SZJW_(MS)),
intent(inout) :: eta
2460 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: ubt
2462 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: vbt
2467 type(ocean_grid_type),
intent(inout) :: G
2468 integer,
intent(in) :: halo
2469 real,
intent(in) :: dtbt
2489 integer :: i, j, is, ie, js, je
2490 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
2492 if ((obc%Flather_u_BCs_exist_globally) .and.
apply_u_obcs)
then 2493 do j=js,je ;
do i=is-1,ie ;
if (obc%segnum_u(i,j) /= obc_none)
then 2494 if (obc%segment(obc%segnum_u(i,j))%Flather)
then 2495 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then 2496 cfl = dtbt * bt_obc%Cg_u(i,j) * g%IdxCu(i,j)
2497 u_inlet = cfl*ubt(i-1,j) + (1.0-cfl)*ubt(i,j)
2499 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i-1,j))
2501 h_u = bt_obc%H_u(i,j)
2502 eta(i+1,j) = 2.0 * 0.5*((bt_obc%eta_outer_u(i,j)+h_in) + &
2503 (h_u/bt_obc%Cg_u(i,j))*(u_inlet-bt_obc%ubt_outer(i,j))) - eta(i,j)
2504 elseif (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_w)
then 2505 cfl = dtbt*bt_obc%Cg_u(i,j)*g%IdxCu(i,j)
2506 u_inlet = cfl*ubt(i+1,j) + (1.0-cfl)*ubt(i,j)
2508 h_in = eta(i+1,j) + (0.5-cfl)*(eta(i+1,j)-eta(i+2,j))
2510 h_u = bt_obc%H_u(i,j)
2511 eta(i,j) = 2.0 * 0.5*((bt_obc%eta_outer_u(i,j)+h_in) + &
2512 (h_u/bt_obc%Cg_u(i,j))*(bt_obc%ubt_outer(i,j)-u_inlet)) - eta(i+1,j)
2515 endif ;
enddo ;
enddo 2518 if ((obc%Flather_v_BCs_exist_globally) .and.
apply_v_obcs)
then 2519 do j=js-1,je ;
do i=is,ie ;
if (obc%segnum_v(i,j) /= obc_none)
then 2520 if (obc%segment(obc%segnum_v(i,j))%Flather)
then 2521 if (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_n)
then 2522 cfl = dtbt*bt_obc%Cg_v(i,j)*g%IdyCv(i,j)
2523 v_inlet = cfl*vbt(i,j-1) + (1.0-cfl)*vbt(i,j)
2525 h_in = eta(i,j) + (0.5-cfl)*(eta(i,j)-eta(i,j-1))
2527 h_v = bt_obc%H_v(i,j)
2528 eta(i,j+1) = 2.0 * 0.5*((bt_obc%eta_outer_v(i,j)+h_in) + &
2529 (h_v/bt_obc%Cg_v(i,j))*(v_inlet-bt_obc%vbt_outer(i,j))) - eta(i,j)
2530 elseif (obc%segment(obc%segnum_v(i,j))%direction == obc_direction_s)
then 2531 cfl = dtbt*bt_obc%Cg_v(i,j)*g%IdyCv(i,j)
2532 v_inlet = cfl*vbt(i,j+1) + (1.0-cfl)*vbt(i,j)
2534 h_in = eta(i,j+1) + (0.5-cfl)*(eta(i,j+1)-eta(i,j+2))
2536 h_v = bt_obc%H_v(i,j)
2537 eta(i,j) = 2.0 * 0.5*((bt_obc%eta_outer_v(i,j)+h_in) + &
2538 (h_v/bt_obc%Cg_v(i,j))*(bt_obc%vbt_outer(i,j)-v_inlet)) - eta(i,j+1)
2541 endif ;
enddo ;
enddo 2547 subroutine set_up_bt_obc(OBC, eta, BT_OBC, G, GV, MS, halo, use_BT_cont, Datu, Datv, BTCL_u, BTCL_v)
2548 type(ocean_obc_type),
pointer :: OBC
2552 real,
dimension(SZIW_(MS),SZJW_(MS)),
intent(in) :: eta
2557 type(ocean_grid_type),
intent(inout) :: G
2558 type(verticalgrid_type),
intent(in) :: GV
2560 integer,
intent(in) :: halo
2561 logical,
intent(in) :: use_BT_cont
2563 real,
dimension(SZIBW_(MS),SZJW_(MS)),
intent(in) :: Datu
2565 real,
dimension(SZIW_(MS),SZJBW_(MS)),
intent(in) :: Datv
2568 intent(in) :: BTCL_u
2571 intent(in) :: BTCL_v
2592 integer :: i, j, k, is, ie, js, je, nz, Isq, Ieq, Jsq, Jeq, n
2593 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
2594 integer :: isdw, iedw, jsdw, jedw
2596 type(obc_segment_type),
pointer :: segment
2598 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
2599 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
2600 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
2601 isdw = ms%isdw ; iedw = ms%iedw ; jsdw = ms%jsdw ; jedw = ms%jedw
2603 if ((isdw < isd) .or. (jsdw < jsd))
then 2604 call mom_error(fatal,
"set_up_BT_OBC: Open boundary conditions are not "//&
2605 "yet fully implemented with wide barotropic halos.")
2608 allocate(bt_obc%Cg_u(isdw-1:iedw,jsdw:jedw)) ; bt_obc%Cg_u(:,:) = 0.0
2609 allocate(bt_obc%H_u(isdw-1:iedw,jsdw:jedw)) ; bt_obc%H_u(:,:) = 0.0
2610 allocate(bt_obc%uhbt(isdw-1:iedw,jsdw:jedw)) ; bt_obc%uhbt(:,:) = 0.0
2611 allocate(bt_obc%ubt_outer(isdw-1:iedw,jsdw:jedw)) ; bt_obc%ubt_outer(:,:) = 0.0
2612 allocate(bt_obc%eta_outer_u(isdw-1:iedw,jsdw:jedw)) ; bt_obc%eta_outer_u(:,:) = 0.0
2614 allocate(bt_obc%Cg_v(isdw:iedw,jsdw-1:jedw)) ; bt_obc%Cg_v(:,:) = 0.0
2615 allocate(bt_obc%H_v(isdw:iedw,jsdw-1:jedw)) ; bt_obc%H_v(:,:) = 0.0
2616 allocate(bt_obc%vhbt(isdw:iedw,jsdw-1:jedw)) ; bt_obc%vhbt(:,:) = 0.0
2617 allocate(bt_obc%vbt_outer(isdw:iedw,jsdw-1:jedw)) ; bt_obc%vbt_outer(:,:) = 0.0
2618 allocate(bt_obc%eta_outer_v(isdw:iedw,jsdw-1:jedw)) ; bt_obc%eta_outer_v(:,:)=0.0
2621 if (obc%specified_u_BCs_exist_globally)
then 2622 do n = 1, obc%number_of_segments
2623 segment => obc%segment(n)
2624 if (segment%is_E_or_W .and. segment%specified)
then 2625 do k=1,nz ;
do j=segment%HI%jsd,segment%HI%jed ;
do i=segment%HI%IsdB,segment%HI%IedB
2626 bt_obc%uhbt(i,j) = bt_obc%uhbt(i,j) + segment%normal_trans(i,j,k)
2627 enddo ;
enddo ;
enddo 2631 do j=js,je ;
do i=is-1,ie ;
if (obc%segnum_u(i,j) /= obc_none)
then 2632 if (obc%segment(obc%segnum_u(i,j))%specified)
then 2633 if (use_bt_cont)
then 2634 bt_obc%ubt_outer(i,j) =
uhbt_to_ubt(bt_obc%uhbt(i,j),btcl_u(i,j))
2636 if (datu(i,j) > 0.0) bt_obc%ubt_outer(i,j) = bt_obc%uhbt(i,j) / datu(i,j)
2639 bt_obc%Cg_u(i,j) = sqrt(gv%g_prime(1)*(0.5* &
2640 (g%bathyT(i,j) + g%bathyT(i+1,j))))
2641 if (gv%Boussinesq)
then 2642 bt_obc%H_u(i,j) = 0.5*((g%bathyT(i,j) + eta(i,j)) + &
2643 (g%bathyT(i+1,j) + eta(i+1,j)))
2645 bt_obc%H_u(i,j) = 0.5*(eta(i,j) + eta(i+1,j))
2648 endif ;
enddo ;
enddo 2649 if (obc%Flather_u_BCs_exist_globally)
then 2650 do n = 1, obc%number_of_segments
2651 segment => obc%segment(n)
2652 if (segment%is_E_or_W .and. segment%Flather)
then 2653 do j=segment%HI%jsd,segment%HI%jed ;
do i=segment%HI%IsdB,segment%HI%IedB
2654 bt_obc%ubt_outer(i,j) = segment%normal_vel_bt(i,j)
2655 bt_obc%eta_outer_u(i,j) = segment%eta(i,j)
2662 if (obc%specified_v_BCs_exist_globally)
then 2663 do n = 1, obc%number_of_segments
2664 segment => obc%segment(n)
2665 if (segment%is_N_or_S .and. segment%specified)
then 2666 do k=1,nz ;
do j=segment%HI%JsdB,segment%HI%JedB ;
do i=segment%HI%isd,segment%HI%ied
2667 bt_obc%vhbt(i,j) = bt_obc%vhbt(i,j) + segment%normal_trans(i,j,k)
2668 enddo ;
enddo ;
enddo 2673 do j=js-1,je ;
do i=is,ie ;
if (obc%segnum_v(i,j) /= obc_none)
then 2674 if (obc%segnum_v(i,j) == obc_simple)
then 2675 if (use_bt_cont)
then 2676 bt_obc%vbt_outer(i,j) =
vhbt_to_vbt(bt_obc%vhbt(i,j),btcl_v(i,j))
2678 if (datv(i,j) > 0.0) bt_obc%vbt_outer(i,j) = bt_obc%vhbt(i,j) / datv(i,j)
2681 bt_obc%Cg_v(i,j) = sqrt(gv%g_prime(1)*(0.5* &
2682 (g%bathyT(i,j) + g%bathyT(i,j+1))))
2683 if (gv%Boussinesq)
then 2684 bt_obc%H_v(i,j) = 0.5*((g%bathyT(i,j) + eta(i,j)) + &
2685 (g%bathyT(i,j+1) + eta(i,j+1)))
2687 bt_obc%H_v(i,j) = 0.5*(eta(i,j) + eta(i,j+1))
2690 endif ;
enddo ;
enddo 2691 if (obc%Flather_v_BCs_exist_globally)
then 2692 do n = 1, obc%number_of_segments
2693 segment => obc%segment(n)
2694 if (segment%is_N_or_S .and. segment%Flather)
then 2695 do j=segment%HI%JsdB,segment%HI%JedB ;
do i=segment%HI%isd,segment%HI%ied
2696 bt_obc%vbt_outer(i,j) = segment%normal_vel_bt(i,j)
2697 bt_obc%eta_outer_v(i,j) = segment%eta(i,j)
2708 deallocate(bt_obc%Cg_u)
2709 deallocate(bt_obc%H_u)
2710 deallocate(bt_obc%uhbt)
2711 deallocate(bt_obc%ubt_outer)
2712 deallocate(bt_obc%eta_outer_u)
2714 deallocate(bt_obc%Cg_v)
2715 deallocate(bt_obc%H_v)
2716 deallocate(bt_obc%vhbt)
2717 deallocate(bt_obc%vbt_outer)
2718 deallocate(bt_obc%eta_outer_v)
2726 subroutine legacy_btcalc(h, G, GV, CS, h_u, h_v, may_use_default)
2727 type(ocean_grid_type),
intent(inout) :: G
2728 type(verticalgrid_type),
intent(in) :: GV
2730 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
2734 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
2735 intent(in),
optional :: h_u
2737 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
2738 intent(in),
optional :: h_v
2740 logical,
intent(in),
optional :: may_use_default
2755 real :: hatutot(szib_(g))
2756 real :: hatvtot(szi_(g))
2757 real :: Ihatutot(szib_(g))
2758 real :: Ihatvtot(szi_(g))
2767 real :: htot(szi_(g),szj_(g))
2768 real :: e_u(szib_(g),szk_(g)+1)
2769 real :: e_v(szi_(g),szk_(g)+1)
2770 real :: D_shallow_u(szi_(g))
2771 real :: D_shallow_v(szib_(g))
2773 logical :: use_default, test_dflt
2774 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, i, j, k
2778 if (.not.
associated(cs))
call mom_error(fatal, &
2779 "legacy_btcalc: Module MOM_legacy_barotropic must be initialized before it is used.")
2780 if (.not.cs%split)
return 2782 use_default = .false.
2783 test_dflt = .false. ;
if (
present(may_use_default)) test_dflt = may_use_default
2786 if (.not.((
present(h_u) .and.
present(h_v)) .or. &
2787 (cs%hvel_scheme ==
harmonic) .or. (cs%hvel_scheme ==
hybrid) .or.&
2788 (cs%hvel_scheme ==
arithmetic))) use_default = .true.
2790 if (.not.((
present(h_u) .and.
present(h_v)) .or. &
2791 (cs%hvel_scheme ==
harmonic) .or. (cs%hvel_scheme ==
hybrid) .or.&
2792 (cs%hvel_scheme ==
arithmetic)))
call mom_error(fatal, &
2793 "legacy_btcalc: Inconsistent settings of optional arguments and hvel_scheme.")
2796 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
2797 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
2798 h_neglect = gv%H_subroundoff
2805 if (
present(h_u))
then 2806 do i=is-2,ie+1 ; hatutot(i) = h_u(i,j,1) ;
enddo 2807 do k=2,nz ;
do i=is-2,ie+1
2808 hatutot(i) = hatutot(i) + h_u(i,j,k)
2810 do i=is-2,ie+1 ; ihatutot(i) = 1.0 / (hatutot(i) + h_neglect) ;
enddo 2811 do k=1,nz ;
do i=is-2,ie+1
2812 cs%frhatu(i,j,k) = h_u(i,j,k) * ihatutot(i)
2817 cs%frhatu(i,j,1) = 0.5 * (h(i+1,j,1) + h(i,j,1))
2818 hatutot(i) = cs%frhatu(i,j,1)
2820 do k=2,nz ;
do i=is-2,ie+1
2821 cs%frhatu(i,j,k) = 0.5 * (h(i+1,j,k) + h(i,j,k))
2822 hatutot(i) = hatutot(i) + cs%frhatu(i,j,k)
2824 elseif (cs%hvel_scheme ==
hybrid .or. use_default)
then 2826 e_u(i,nz+1) = -0.5 * gv%m_to_H * (g%bathyT(i+1,j) + g%bathyT(i,j))
2827 d_shallow_u(i) = -gv%m_to_H * min(g%bathyT(i+1,j), g%bathyT(i,j))
2830 do k=nz,1,-1 ;
do i=is-2,ie+1
2831 e_u(i,k) = e_u(i,k+1) + 0.5 * (h(i+1,j,k) + h(i,j,k))
2832 h_arith = 0.5 * (h(i+1,j,k) + h(i,j,k))
2833 if (e_u(i,k+1) >= d_shallow_u(i))
then 2834 cs%frhatu(i,j,k) = h_arith
2836 h_harm = (h(i+1,j,k) * h(i,j,k)) / (h_arith + h_neglect)
2837 if (e_u(i,k) <= d_shallow_u(i))
then 2838 cs%frhatu(i,j,k) = h_harm
2840 wt_arith = (e_u(i,k) - d_shallow_u(i)) / (h_arith + h_neglect)
2841 cs%frhatu(i,j,k) = wt_arith*h_arith + (1.0-wt_arith)*h_harm
2844 hatutot(i) = hatutot(i) + cs%frhatu(i,j,k)
2846 elseif (cs%hvel_scheme ==
harmonic)
then 2848 cs%frhatu(i,j,1) = 2.0*(h(i+1,j,1) * h(i,j,1)) / &
2849 ((h(i+1,j,1) + h(i,j,1)) + h_neglect)
2850 hatutot(i) = cs%frhatu(i,j,1)
2852 do k=2,nz ;
do i=is-2,ie+1
2853 cs%frhatu(i,j,k) = 2.0*(h(i+1,j,k) * h(i,j,k)) / &
2854 ((h(i+1,j,k) + h(i,j,k)) + h_neglect)
2855 hatutot(i) = hatutot(i) + cs%frhatu(i,j,k)
2858 do i=is-2,ie+1 ; ihatutot(i) = 1.0 / (hatutot(i) + h_neglect) ;
enddo 2859 do k=1,nz ;
do i=is-2,ie+1
2860 cs%frhatu(i,j,k) = cs%frhatu(i,j,k) * ihatutot(i)
2868 if (
present(h_v))
then 2869 do i=is-1,ie+1 ; hatvtot(i) = h_v(i,j,1) ;
enddo 2870 do k=2,nz ;
do i=is-1,ie+1
2871 hatvtot(i) = hatvtot(i) + h_v(i,j,k)
2873 do i=is-1,ie+1 ; ihatvtot(i) = 1.0 / (hatvtot(i) + h_neglect) ;
enddo 2874 do k=1,nz ;
do i=is-1,ie+1
2875 cs%frhatv(i,j,k) = h_v(i,j,k) * ihatvtot(i)
2880 cs%frhatv(i,j,1) = 0.5 * (h(i,j+1,1) + h(i,j,1))
2881 hatvtot(i) = cs%frhatv(i,j,1)
2883 do k=2,nz ;
do i=is-1,ie+1
2884 cs%frhatv(i,j,k) = 0.5 * (h(i,j+1,k) + h(i,j,k))
2885 hatvtot(i) = hatvtot(i) + cs%frhatv(i,j,k)
2887 elseif (cs%hvel_scheme ==
hybrid .or. use_default)
then 2889 e_v(i,nz+1) = -0.5 * gv%m_to_H * (g%bathyT(i,j+1) + g%bathyT(i,j))
2890 d_shallow_v(i) = -gv%m_to_H * min(g%bathyT(i,j+1), g%bathyT(i,j))
2893 do k=nz,1,-1 ;
do i=is-1,ie+1
2894 e_v(i,k) = e_v(i,k+1) + 0.5 * (h(i,j+1,k) + h(i,j,k))
2895 h_arith = 0.5 * (h(i,j+1,k) + h(i,j,k))
2896 if (e_v(i,k+1) >= d_shallow_v(i))
then 2897 cs%frhatv(i,j,k) = h_arith
2899 h_harm = (h(i,j+1,k) * h(i,j,k)) / (h_arith + h_neglect)
2900 if (e_v(i,k) <= d_shallow_v(i))
then 2901 cs%frhatv(i,j,k) = h_harm
2903 wt_arith = (e_v(i,k) - d_shallow_v(i)) / (h_arith + h_neglect)
2904 cs%frhatv(i,j,k) = wt_arith*h_arith + (1.0-wt_arith)*h_harm
2907 hatvtot(i) = hatvtot(i) + cs%frhatv(i,j,k)
2909 elseif (cs%hvel_scheme ==
harmonic)
then 2911 cs%frhatv(i,j,1) = 2.0*(h(i,j+1,1) * h(i,j,1)) / &
2912 ((h(i,j+1,1) + h(i,j,1)) + h_neglect)
2913 hatvtot(i) = cs%frhatv(i,j,1)
2915 do k=2,nz ;
do i=is-1,ie+1
2916 cs%frhatv(i,j,k) = 2.0*(h(i,j+1,k) * h(i,j,k)) / &
2917 ((h(i,j+1,k) + h(i,j,k)) + h_neglect)
2918 hatvtot(i) = hatvtot(i) + cs%frhatv(i,j,k)
2921 do i=is-1,ie+1 ; ihatvtot(i) = 1.0 / (hatvtot(i) + h_neglect) ;
enddo 2922 do k=1,nz ;
do i=is-1,ie+1
2923 cs%frhatv(i,j,k) = cs%frhatv(i,j,k) * ihatvtot(i)
2928 if (cs%rescale_D_bt)
then 2929 do j=js-2,je+2 ;
do i=is-2,ie+2 ; htot(i,j) = 0.0 ;
enddo ;
enddo 2930 do k=1,nz ;
do j=js-2,je+2 ;
do i=is-2,ie+2
2931 htot(i,j) = htot(i,j) + h(i,j,k)
2932 enddo ;
enddo ;
enddo 2937 do i=is-2,ie+1 ; hatutot(i) = 0.0 ;
enddo 2938 do k=1,nz ;
do i=is-2,ie+1
2939 h_harm = 2.0*(h(i+1,j,k) * h(i,j,k)) / &
2940 ((h(i+1,j,k) + h(i,j,k)) + h_neglect)
2941 hatutot(i) = hatutot(i) + h_harm
2944 rh = hatutot(i) * (htot(i+1,j) + htot(i,j)) / &
2945 (2.0*(htot(i+1,j) * htot(i,j) + h_neglect**2))
2946 cs%Datu_res(i,j) = 1.0
2948 if (rh < 0.5) cs%Datu_res(i,j) = rh * ((4.0-7.0*rh) / (2.0-3.0*rh)**2)
2955 do i=is-1,ie+1 ; hatvtot(i) = 0.0 ;
enddo 2956 do k=1,nz ;
do i=is-1,ie+1
2957 h_harm = 2.0*(h(i,j+1,k) * h(i,j,k)) / &
2958 ((h(i,j+1,k) + h(i,j,k)) + h_neglect)
2959 hatvtot(i) = hatvtot(i) + h_harm
2962 rh = hatvtot(i) * (htot(i,j+1) + htot(i,j)) / &
2963 (2.0*(htot(i,j+1) * htot(i,j) + h_neglect**2))
2964 cs%Datv_res(i,j) = 1.0
2966 if (rh < 0.5) cs%Datv_res(i,j) = rh * ((4.0-7.0*rh) / (2.0-3.0*rh)**2)
2972 call uvchksum(
"btcalc frhat[uv]", cs%frhatu, cs%frhatv, g%HI, haloshift=1)
2973 call hchksum(h,
"btcalc h", g%HI, haloshift=1, scale=gv%H_to_m)
2979 real,
intent(in) :: u
2986 elseif (u < btc%uBT_EE)
then 2987 uhbt = (u - btc%uBT_EE) * btc%FA_u_EE + btc%uh_EE
2988 elseif (u < 0.0)
then 2989 uhbt = u * (btc%FA_u_E0 + btc%uh_crvE * u**2)
2990 elseif (u <= btc%uBT_WW)
then 2991 uhbt = u * (btc%FA_u_W0 + btc%uh_crvW * u**2)
2993 uhbt = (u - btc%uBT_WW) * btc%FA_u_WW + btc%uh_WW
2997 function uhbt_to_ubt(uhbt, BTC, guess)
result(ubt)
2998 real,
intent(in) :: uhbt
3003 real,
optional,
intent(in) :: guess
3020 real :: ubt_min, ubt_max, uhbt_err, derr_du
3021 real :: uherr_min, uherr_max
3022 real,
parameter :: tol = 1.0e-10
3024 real,
parameter :: vs1 = 1.25
3025 real,
parameter :: vs2 = 2.0
3027 integer :: itt, max_itt = 20
3030 if (uhbt == 0.0)
then 3032 elseif (uhbt < btc%uh_EE)
then 3033 ubt = btc%uBT_EE + (uhbt - btc%uh_EE) / btc%FA_u_EE
3034 elseif (uhbt < 0.0)
then 3037 ubt_min = btc%uBT_EE ; uherr_min = btc%uh_EE - uhbt
3038 ubt_max = 0.0 ; uherr_max = -uhbt
3040 ubt = btc%uBT_EE * (uhbt / btc%uh_EE)
3042 uhbt_err = ubt * (btc%FA_u_E0 + btc%uh_crvE * ubt**2) - uhbt
3044 if (abs(uhbt_err) < tol*abs(uhbt))
exit 3045 if (uhbt_err > 0.0)
then ; ubt_max = ubt ; uherr_max = uhbt_err ;
endif 3046 if (uhbt_err < 0.0)
then ; ubt_min = ubt ; uherr_min = uhbt_err ;
endif 3048 derr_du = btc%FA_u_E0 + 3.0 * btc%uh_crvE * ubt**2
3049 if ((uhbt_err >= derr_du*(ubt - ubt_min)) .or. &
3050 (-uhbt_err >= derr_du*(ubt_max - ubt)) .or. (derr_du <= 0.0))
then 3052 ubt = ubt_max + (ubt_min-ubt_max) * (uherr_max / (uherr_max-uherr_min))
3054 ubt = ubt - uhbt_err / derr_du
3055 if (abs(uhbt_err) < (0.01*tol)*abs(ubt_min*derr_du))
exit 3058 elseif (uhbt <= btc%uh_WW)
then 3060 ubt_min = 0.0 ; uherr_min = -uhbt
3061 ubt_max = btc%uBT_WW ; uherr_max = btc%uh_WW - uhbt
3063 ubt = btc%uBT_WW * (uhbt / btc%uh_WW)
3065 uhbt_err = ubt * (btc%FA_u_W0 + btc%uh_crvW * ubt**2) - uhbt
3067 if (abs(uhbt_err) < tol*abs(uhbt))
exit 3068 if (uhbt_err > 0.0)
then ; ubt_max = ubt ; uherr_max = uhbt_err ;
endif 3069 if (uhbt_err < 0.0)
then ; ubt_min = ubt ; uherr_min = uhbt_err ;
endif 3071 derr_du = btc%FA_u_W0 + 3.0 * btc%uh_crvW * ubt**2
3072 if ((uhbt_err >= derr_du*(ubt - ubt_min)) .or. &
3073 (-uhbt_err >= derr_du*(ubt_max - ubt)) .or. (derr_du <= 0.0))
then 3075 ubt = ubt_min + (ubt_max-ubt_min) * (-uherr_min / (uherr_max-uherr_min))
3077 ubt = ubt - uhbt_err / derr_du
3078 if (abs(uhbt_err) < (0.01*tol)*(ubt_max*derr_du))
exit 3082 ubt = btc%uBT_WW + (uhbt - btc%uh_WW) / btc%FA_u_WW
3085 if (
present(guess))
then 3086 dvel = abs(ubt) - vs1*abs(guess)
3087 if (dvel > 0.0)
then 3088 if (dvel < 40.0 * (abs(guess)*(vs2-vs1)) )
then 3089 vsr = vs2 - (vs2-vs1) * exp(-dvel / (abs(guess)*(vs2-vs1)))
3093 ubt = sign(vsr * guess, ubt)
3100 real,
intent(in) :: v
3107 elseif (v < btc%vBT_NN)
then 3108 vhbt = (v - btc%vBT_NN) * btc%FA_v_NN + btc%vh_NN
3109 elseif (v < 0.0)
then 3110 vhbt = v * (btc%FA_v_N0 + btc%vh_crvN * v**2)
3111 elseif (v <= btc%vBT_SS)
then 3112 vhbt = v * (btc%FA_v_S0 + btc%vh_crvS * v**2)
3114 vhbt = (v - btc%vBT_SS) * btc%FA_v_SS + btc%vh_SS
3118 function vhbt_to_vbt(vhbt, BTC, guess)
result(vbt)
3119 real,
intent(in) :: vhbt
3123 real,
optional,
intent(in) :: guess
3141 real :: vbt_min, vbt_max, vhbt_err, derr_dv
3142 real :: vherr_min, vherr_max
3143 real,
parameter :: tol = 1.0e-10
3145 real,
parameter :: vs1 = 1.25
3146 real,
parameter :: vs2 = 2.0
3148 integer :: itt, max_itt = 20
3151 if (vhbt == 0.0)
then 3153 elseif (vhbt < btc%vh_NN)
then 3154 vbt = btc%vBT_NN + (vhbt - btc%vh_NN) / btc%FA_v_NN
3155 elseif (vhbt < 0.0)
then 3158 vbt_min = btc%vBT_NN ; vherr_min = btc%vh_NN - vhbt
3159 vbt_max = 0.0 ; vherr_max = -vhbt
3161 vbt = btc%vBT_NN * (vhbt / btc%vh_NN)
3163 vhbt_err = vbt * (btc%FA_v_N0 + btc%vh_crvN * vbt**2) - vhbt
3165 if (abs(vhbt_err) < tol*abs(vhbt))
exit 3166 if (vhbt_err > 0.0)
then ; vbt_max = vbt ; vherr_max = vhbt_err ;
endif 3167 if (vhbt_err < 0.0)
then ; vbt_min = vbt ; vherr_min = vhbt_err ;
endif 3169 derr_dv = btc%FA_v_N0 + 3.0 * btc%vh_crvN * vbt**2
3170 if ((vhbt_err >= derr_dv*(vbt - vbt_min)) .or. &
3171 (-vhbt_err >= derr_dv*(vbt_max - vbt)) .or. (derr_dv <= 0.0))
then 3173 vbt = vbt_max + (vbt_min-vbt_max) * (vherr_max / (vherr_max-vherr_min))
3175 vbt = vbt - vhbt_err / derr_dv
3176 if (abs(vhbt_err) < (0.01*tol)*abs(derr_dv*vbt_min))
exit 3179 elseif (vhbt <= btc%vh_SS)
then 3181 vbt_min = 0.0 ; vherr_min = -vhbt
3182 vbt_max = btc%vBT_SS ; vherr_max = btc%vh_SS - vhbt
3184 vbt = btc%vBT_SS * (vhbt / btc%vh_SS)
3186 vhbt_err = vbt * (btc%FA_v_S0 + btc%vh_crvS * vbt**2) - vhbt
3188 if (abs(vhbt_err) < tol*abs(vhbt))
exit 3189 if (vhbt_err > 0.0)
then ; vbt_max = vbt ; vherr_max = vhbt_err ;
endif 3190 if (vhbt_err < 0.0)
then ; vbt_min = vbt ; vherr_min = vhbt_err ;
endif 3192 derr_dv = btc%FA_v_S0 + 3.0 * btc%vh_crvS * vbt**2
3193 if ((vhbt_err >= derr_dv*(vbt - vbt_min)) .or. &
3194 (-vhbt_err >= derr_dv*(vbt_max - vbt)) .or. (derr_dv <= 0.0))
then 3196 vbt = vbt_min + (vbt_max-vbt_min) * (-vherr_min / (vherr_max-vherr_min))
3198 vbt = vbt - vhbt_err / derr_dv
3199 if (abs(vhbt_err) < (0.01*tol)*(vbt_max*derr_dv))
exit 3203 vbt = btc%vBT_SS + (vhbt - btc%vh_SS) / btc%FA_v_SS
3206 if (
present(guess))
then 3207 dvel = abs(vbt) - vs1*abs(guess)
3208 if (dvel > 0.0)
then 3209 if (dvel < 40.0 * (abs(guess)*(vs2-vs1)) )
then 3210 vsr = vs2 - (vs2-vs1) * exp(-dvel / (abs(guess)*(vs2-vs1)))
3214 vbt = sign(guess * vsr, vbt)
3222 type(bt_cont_type),
intent(inout) :: BT_cont
3227 intent(out) :: BTCL_u
3230 intent(out) :: BTCL_v
3232 type(ocean_grid_type),
intent(inout) :: G
3233 type(mom_domain_type),
intent(inout) :: BT_Domain
3235 integer,
optional,
intent(in) :: halo
3247 real,
dimension(SZIBW_(MS),SZJW_(MS)) :: &
3248 u_polarity, uBT_EE, uBT_WW, FA_u_EE, FA_u_E0, FA_u_W0, FA_u_WW
3249 real,
dimension(SZIW_(MS),SZJBW_(MS)) :: &
3250 v_polarity, vBT_NN, vBT_SS, FA_v_NN, FA_v_N0, FA_v_S0, FA_v_SS
3251 real,
parameter :: C1_3 = 1.0/3.0
3252 integer :: i, j, is, ie, js, je, hs
3253 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3254 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3257 u_polarity(:,:) = 1.0
3258 ubt_ee(:,:) = 0.0 ; ubt_ww(:,:) = 0.0
3259 fa_u_ee(:,:) = 0.0 ; fa_u_e0(:,:) = 0.0 ; fa_u_w0(:,:) = 0.0 ; fa_u_ww(:,:) = 0.0
3260 do i=is-1,ie ;
do j=js,je
3261 ubt_ee(i,j) = bt_cont%uBT_EE(i,j) ; ubt_ww(i,j) = bt_cont%uBT_WW(i,j)
3262 fa_u_ee(i,j) = bt_cont%FA_u_EE(i,j) ; fa_u_e0(i,j) = bt_cont%FA_u_E0(i,j)
3263 fa_u_w0(i,j) = bt_cont%FA_u_W0(i,j) ; fa_u_ww(i,j) = bt_cont%FA_u_WW(i,j)
3266 v_polarity(:,:) = 1.0
3267 vbt_nn(:,:) = 0.0 ; vbt_ss(:,:) = 0.0
3268 fa_v_nn(:,:) = 0.0 ; fa_v_n0(:,:) = 0.0 ; fa_v_s0(:,:) = 0.0 ; fa_v_ss(:,:) = 0.0
3269 do i=is,ie ;
do j=js-1,je
3270 vbt_nn(i,j) = bt_cont%vBT_NN(i,j) ; vbt_ss(i,j) = bt_cont%vBT_SS(i,j)
3271 fa_v_nn(i,j) = bt_cont%FA_v_NN(i,j) ; fa_v_n0(i,j) = bt_cont%FA_v_N0(i,j)
3272 fa_v_s0(i,j) = bt_cont%FA_v_S0(i,j) ; fa_v_ss(i,j) = bt_cont%FA_v_SS(i,j)
3278 call pass_vector(u_polarity, v_polarity, bt_domain, complete=.false.)
3279 call pass_vector(ubt_ee, vbt_nn, bt_domain, complete=.false.)
3280 call pass_vector(ubt_ww, vbt_ss, bt_domain, complete=.true.)
3282 call pass_vector(fa_u_ee, fa_v_nn, bt_domain, to_all+scalar_pair, complete=.false.)
3283 call pass_vector(fa_u_e0, fa_v_n0, bt_domain, to_all+scalar_pair, complete=.false.)
3284 call pass_vector(fa_u_w0, fa_v_s0, bt_domain, to_all+scalar_pair, complete=.false.)
3285 call pass_vector(fa_u_ww, fa_v_ss, bt_domain, to_all+scalar_pair, complete=.true.)
3289 do j=js-hs,je+hs ;
do i=is-hs-1,ie+hs
3290 btcl_u(i,j)%FA_u_EE = fa_u_ee(i,j) ; btcl_u(i,j)%FA_u_E0 = fa_u_e0(i,j)
3291 btcl_u(i,j)%FA_u_W0 = fa_u_w0(i,j) ; btcl_u(i,j)%FA_u_WW = fa_u_ww(i,j)
3292 btcl_u(i,j)%uBT_EE = ubt_ee(i,j) ; btcl_u(i,j)%uBT_WW = ubt_ww(i,j)
3294 if (u_polarity(i,j) < 0.0)
then 3295 call swap(btcl_u(i,j)%FA_u_EE, btcl_u(i,j)%FA_u_WW)
3296 call swap(btcl_u(i,j)%FA_u_E0, btcl_u(i,j)%FA_u_W0)
3297 call swap(btcl_u(i,j)%uBT_EE, btcl_u(i,j)%uBT_WW)
3300 btcl_u(i,j)%uh_EE = btcl_u(i,j)%uBT_EE * &
3301 (c1_3 * (2.0*btcl_u(i,j)%FA_u_E0 + btcl_u(i,j)%FA_u_EE))
3302 btcl_u(i,j)%uh_WW = btcl_u(i,j)%uBT_WW * &
3303 (c1_3 * (2.0*btcl_u(i,j)%FA_u_W0 + btcl_u(i,j)%FA_u_WW))
3305 btcl_u(i,j)%uh_crvE = 0.0 ; btcl_u(i,j)%uh_crvW = 0.0
3306 if (abs(btcl_u(i,j)%uBT_WW) > 0.0) btcl_u(i,j)%uh_crvW = &
3307 (c1_3 * (btcl_u(i,j)%FA_u_WW - btcl_u(i,j)%FA_u_W0)) / btcl_u(i,j)%uBT_WW**2
3308 if (abs(btcl_u(i,j)%uBT_EE) > 0.0) btcl_u(i,j)%uh_crvE = &
3309 (c1_3 * (btcl_u(i,j)%FA_u_EE - btcl_u(i,j)%FA_u_E0)) / btcl_u(i,j)%uBT_EE**2
3312 do j=js-hs-1,je+hs ;
do i=is-hs,ie+hs
3313 btcl_v(i,j)%FA_v_NN = fa_v_nn(i,j) ; btcl_v(i,j)%FA_v_N0 = fa_v_n0(i,j)
3314 btcl_v(i,j)%FA_v_S0 = fa_v_s0(i,j) ; btcl_v(i,j)%FA_v_SS = fa_v_ss(i,j)
3315 btcl_v(i,j)%vBT_NN = vbt_nn(i,j) ; btcl_v(i,j)%vBT_SS = vbt_ss(i,j)
3317 if (v_polarity(i,j) < 0.0)
then 3318 call swap(btcl_v(i,j)%FA_v_NN, btcl_v(i,j)%FA_v_SS)
3319 call swap(btcl_v(i,j)%FA_v_N0, btcl_v(i,j)%FA_v_S0)
3320 call swap(btcl_v(i,j)%vBT_NN, btcl_v(i,j)%vBT_SS)
3323 btcl_v(i,j)%vh_NN = btcl_v(i,j)%vBT_NN * &
3324 (c1_3 * (2.0*btcl_v(i,j)%FA_v_N0 + btcl_v(i,j)%FA_v_NN))
3325 btcl_v(i,j)%vh_SS = btcl_v(i,j)%vBT_SS * &
3326 (c1_3 * (2.0*btcl_v(i,j)%FA_v_S0 + btcl_v(i,j)%FA_v_SS))
3328 btcl_v(i,j)%vh_crvN = 0.0 ; btcl_v(i,j)%vh_crvS = 0.0
3329 if (abs(btcl_v(i,j)%vBT_SS) > 0.0) btcl_v(i,j)%vh_crvS = &
3330 (c1_3 * (btcl_v(i,j)%FA_v_SS - btcl_v(i,j)%FA_v_S0)) / btcl_v(i,j)%vBT_SS**2
3331 if (abs(btcl_v(i,j)%vBT_NN) > 0.0) btcl_v(i,j)%vh_crvN = &
3332 (c1_3 * (btcl_v(i,j)%FA_v_NN - btcl_v(i,j)%FA_v_N0)) / btcl_v(i,j)%vBT_NN**2
3338 type(bt_cont_type),
intent(inout) :: BT_cont
3342 real,
dimension(MS%isdw-1:MS%iedw,MS%jsdw:MS%jedw), &
3345 real,
dimension(MS%isdw:MS%iedw,MS%jsdw-1:MS%jedw), &
3348 type(ocean_grid_type),
intent(in) :: G
3349 integer,
optional,
intent(in) :: halo
3351 logical,
optional,
intent(in) :: maximize
3355 integer :: i, j, is, ie, js, je, hs
3356 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3357 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3358 find_max = .false. ;
if (
present(maximize)) find_max = maximize
3361 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3362 datu(i,j) = max(bt_cont%FA_u_EE(i,j), bt_cont%FA_u_E0(i,j), &
3363 bt_cont%FA_u_W0(i,j), bt_cont%FA_u_WW(i,j))
3365 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3366 datv(i,j) = max(bt_cont%FA_v_NN(i,j), bt_cont%FA_v_N0(i,j), &
3367 bt_cont%FA_v_S0(i,j), bt_cont%FA_v_SS(i,j))
3370 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3371 datu(i,j) = 0.5 * (bt_cont%FA_u_E0(i,j) + bt_cont%FA_u_W0(i,j))
3373 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3374 datv(i,j) = 0.5 * (bt_cont%FA_v_N0(i,j) + bt_cont%FA_v_S0(i,j))
3379 subroutine swap(a,b)
3380 real,
intent(inout) :: a, b
3382 tmp = a ; a = b ; b = tmp
3385 subroutine find_face_areas(Datu, Datv, G, GV, CS, MS, rescale_faces, eta, halo, add_max)
3388 real,
dimension(MS%isdw-1:MS%iedw,MS%jsdw:MS%jedw), &
3391 real,
dimension(MS%isdw:MS%iedw,MS%jsdw-1:MS%jedw), &
3394 type(ocean_grid_type),
intent(in) :: G
3395 type(verticalgrid_type),
intent(in) :: GV
3398 logical,
optional,
intent(in) :: rescale_faces
3400 real,
dimension(MS%isdw:MS%iedw,MS%jsdw:MS%jedw), &
3401 optional,
intent(in) :: eta
3403 integer,
optional,
intent(in) :: halo
3404 real,
optional,
intent(in) :: add_max
3425 integer :: i, j, is, ie, js, je, hs
3426 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
3427 hs = 1 ;
if (
present(halo)) hs = max(halo,0)
3428 rescale = .false. ;
if (
present(rescale_faces)) rescale = rescale_faces
3432 if (
present(eta))
then 3434 if (gv%Boussinesq)
then 3436 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3437 h1 = cs%bathyT(i,j) + eta(i,j) ; h2 = cs%bathyT(i+1,j) + eta(i+1,j)
3438 datu(i,j) = 0.0 ;
if ((h1 > 0.0) .and. (h2 > 0.0)) &
3439 datu(i,j) = cs%dy_Cu(i,j) * (2.0 * h1 * h2) / (h1 + h2)
3443 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3444 h1 = cs%bathyT(i,j) + eta(i,j) ; h2 = cs%bathyT(i,j+1) + eta(i,j+1)
3445 datv(i,j) = 0.0 ;
if ((h1 > 0.0) .and. (h2 > 0.0)) &
3446 datv(i,j) = cs%dx_Cv(i,j) * (2.0 * h1 * h2) / (h1 + h2)
3451 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3452 datu(i,j) = 0.0 ;
if ((eta(i,j) > 0.0) .and. (eta(i+1,j) > 0.0)) &
3453 datu(i,j) = cs%dy_Cu(i,j) * (2.0 * eta(i,j) * eta(i+1,j)) / &
3454 (eta(i,j) + eta(i+1,j))
3458 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3459 datv(i,j) = 0.0 ;
if ((eta(i,j) > 0.0) .and. (eta(i,j+1) > 0.0)) &
3460 datv(i,j) = cs%dx_Cv(i,j) * (2.0 * eta(i,j) * eta(i,j+1)) / &
3461 (eta(i,j) + eta(i,j+1))
3465 elseif (
present(add_max))
then 3467 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3468 datu(i,j) = cs%dy_Cu(i,j) * gv%m_to_H * &
3469 (max(cs%bathyT(i+1,j), cs%bathyT(i,j)) + add_max)
3472 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3473 datv(i,j) = cs%dx_Cv(i,j) * gv%m_to_H * &
3474 (max(cs%bathyT(i,j+1), cs%bathyT(i,j)) + add_max)
3478 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3479 datu(i,j) = 2.0*cs%dy_Cu(i,j) * gv%m_to_H * &
3480 (cs%bathyT(i+1,j) * cs%bathyT(i,j)) / &
3481 (cs%bathyT(i+1,j) + cs%bathyT(i,j))
3484 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3485 datv(i,j) = 2.0*cs%dx_Cv(i,j) * gv%m_to_H * &
3486 (cs%bathyT(i,j+1) * cs%bathyT(i,j)) / &
3487 (cs%bathyT(i,j+1) + cs%bathyT(i,j))
3493 do j=js-hs,je+hs ;
do i=is-1-hs,ie+hs
3494 datu(i,j) = datu(i,j) * cs%Datu_res(i,j)
3497 do j=js-1-hs,je+hs ;
do i=is-hs,ie+hs
3498 datv(i,j) = datv(i,j) * cs%Datv_res(i,j)
3506 dt_since_therm, G, GV, CS)
3507 type(ocean_grid_type),
intent(in) :: G
3508 type(verticalgrid_type),
intent(in) :: GV
3509 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
3512 real,
dimension(SZI_(G),SZJ_(G)), &
3515 type(forcing),
intent(in) :: fluxes
3518 logical,
intent(in) :: set_cor
3521 real,
intent(in) :: dt_therm
3522 real,
intent(in) :: dt_since_therm
3545 real :: h_tot(szi_(g))
3546 real :: eta_h(szi_(g))
3552 integer :: is, ie, js, je, nz, i, j, k
3553 real,
parameter :: frac_cor = 0.25
3554 real,
parameter :: slow_rate = 0.125
3556 if (.not.
associated(cs))
call mom_error(fatal,
"bt_mass_source: "// &
3557 "Module MOM_barotropic must be initialized before it is used.")
3558 if (.not.cs%split)
return 3560 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3566 do i=is,ie ; h_tot(i) = h(i,j,1) ;
enddo 3567 if (gv%Boussinesq)
then 3568 do i=is,ie ; eta_h(i) = h(i,j,1) - g%bathyT(i,j) ;
enddo 3570 do i=is,ie ; eta_h(i) = h(i,j,1) ;
enddo 3572 do k=2,nz ;
do i=is,ie
3573 eta_h(i) = eta_h(i) + h(i,j,k)
3574 h_tot(i) = h_tot(i) + h(i,j,k)
3578 do i=is,ie ; cs%eta_source(i,j) = 0.0 ;
enddo 3579 if (cs%eta_source_limit > 0.0)
then 3580 limit_dt = cs%eta_source_limit/dt_therm
3581 if (
associated(fluxes%lprec))
then ;
do i=is,ie
3582 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%lprec(i,j)
3584 if (
associated(fluxes%fprec))
then ;
do i=is,ie
3585 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%fprec(i,j)
3587 if (
associated(fluxes%vprec))
then ;
do i=is,ie
3588 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%vprec(i,j)
3590 if (
associated(fluxes%lrunoff))
then ;
do i=is,ie
3591 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%lrunoff(i,j)
3593 if (
associated(fluxes%frunoff))
then ;
do i=is,ie
3594 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%frunoff(i,j)
3596 if (
associated(fluxes%evap))
then ;
do i=is,ie
3597 cs%eta_source(i,j) = cs%eta_source(i,j) + fluxes%evap(i,j)
3600 cs%eta_source(i,j) = cs%eta_source(i,j)*gv%kg_m2_to_H
3601 if (abs(cs%eta_source(i,j)) > limit_dt * h_tot(i))
then 3602 cs%eta_source(i,j) = sign(limit_dt * h_tot(i), cs%eta_source(i,j))
3610 d_eta = eta_h(i) - (eta(i,j) - dt_since_therm*cs%eta_source(i,j))
3611 cs%eta_cor(i,j) = d_eta
3615 d_eta = eta_h(i) - (eta(i,j) - dt_since_therm*cs%eta_source(i,j))
3616 cs%eta_cor(i,j) = cs%eta_cor(i,j) + d_eta
3623 subroutine legacy_barotropic_init(u, v, h, eta, Time, G, GV, param_file, diag, CS, &
3624 restart_CS, BT_cont, tides_CSp)
3625 type(ocean_grid_type),
intent(inout) :: G
3626 type(verticalgrid_type),
intent(in) :: GV
3628 real,
intent(in),
dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u
3629 real,
intent(in),
dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v
3631 real,
intent(in),
dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h
3633 real,
intent(in),
dimension(SZI_(G),SZJ_(G)) :: eta
3635 type(time_type),
target,
intent(in) :: Time
3636 type(param_file_type),
intent(in) :: param_file
3638 type(diag_ctrl),
target,
intent(inout) :: diag
3643 type(mom_restart_cs),
pointer :: restart_CS
3645 type(bt_cont_type),
optional,
pointer :: BT_cont
3648 type(tidal_forcing_cs),
optional,
pointer :: tides_CSp
3671 #include "version_variable.h" 3672 character(len=40) :: mdl =
"MOM_barotropic" 3673 real :: Datu(szibs_(g),szj_(g)), Datv(szi_(g),szjbs_(g))
3674 real :: gtot_estimate
3679 logical :: apply_bt_drag, use_BT_cont_type
3680 character(len=48) :: thickness_units, flux_units
3681 character*(40) :: hvel_str
3682 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
3683 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
3684 integer :: isdw, iedw, jsdw, jedw
3686 integer :: wd_halos(2), bt_halo_sz
3687 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3688 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
3689 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
3690 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
3691 ms%isdw = g%isd ; ms%iedw = g%ied ; ms%jsdw = g%jsd ; ms%jedw = g%jed
3693 if (cs%module_is_initialized)
then 3694 call mom_error(warning,
"barotropic_init called with a control structure "// &
3695 "that has already been initialized.")
3698 cs%module_is_initialized = .true.
3700 cs%diag => diag ; cs%Time => time
3701 if (
present(tides_csp))
then 3702 if (
associated(tides_csp)) cs%tides_CSp => tides_csp
3706 call log_version(param_file, mdl, version,
"")
3707 call get_param(param_file, mdl,
"SPLIT", cs%split, &
3708 "Use the split time stepping if true.", default=.true.)
3709 if (.not.cs%split)
return 3712 call get_param(param_file, mdl,
"BOUND_BT_CORRECTION", cs%bound_BT_corr, &
3713 "If true, the corrective pseudo mass-fluxes into the \n"//&
3714 "barotropic solver are limited to values that require \n"//&
3715 "less than 0.1*MAXVEL to be accommodated.",default=.false.)
3716 call get_param(param_file, mdl,
"GRADUAL_BT_ICS", cs%gradual_BT_ICs, &
3717 "If true, adjust the initial conditions for the \n"//&
3718 "barotropic solver to the values from the layered \n"//&
3719 "solution over a whole timestep instead of instantly. \n"//&
3720 "This is a decent approximation to the inclusion of \n"//&
3721 "sum(u dh_dt) while also correcting for truncation errors.", &
3723 call get_param(param_file, mdl,
"BT_USE_WIDE_HALOS", cs%use_wide_halos, &
3724 "If true, use wide halos and march in during the \n"//&
3725 "barotropic time stepping for efficiency.", default=.true., &
3727 call get_param(param_file, mdl,
"BTHALO", bt_halo_sz, &
3728 "The minimum halo size for the barotropic solver.", default=0, &
3730 #ifdef STATIC_MEMORY_ 3731 if ((bt_halo_sz > 0) .and. (bt_halo_sz /= bthalo_))
call mom_error(fatal, &
3732 "barotropic_init: Run-time values of BTHALO must agree with the \n"//&
3733 "macro BTHALO_ with STATIC_MEMORY_.")
3734 wd_halos(1) = whaloi_+nihalo_ ; wd_halos(2) = whaloj_+njhalo_
3736 wd_halos(1) = bt_halo_sz; wd_halos(2) = bt_halo_sz
3738 call log_param(param_file, mdl,
"!BT x-halo", wd_halos(1), &
3739 "The barotropic x-halo size that is actually used.", &
3741 call log_param(param_file, mdl,
"!BT y-halo", wd_halos(2), &
3742 "The barotropic y-halo size that is actually used.", &
3745 call get_param(param_file, mdl,
"USE_BT_CONT_TYPE", use_bt_cont_type, &
3746 "If true, use a structure with elements that describe \n"//&
3747 "effective face areas from the summed continuity solver \n"//&
3748 "as a function the barotropic flow in coupling between \n"//&
3749 "the barotropic and baroclinic flow. This is only used \n"//&
3750 "if SPLIT is true. \n", default=.true.)
3751 call get_param(param_file, mdl,
"NONLINEAR_BT_CONTINUITY", &
3752 cs%Nonlinear_continuity, &
3753 "If true, use nonlinear transports in the barotropic \n"//&
3754 "continuity equation. This does not apply if \n"//&
3755 "USE_BT_CONT_TYPE is true.", default=.false.)
3756 cs%Nonlin_cont_update_period = 1
3757 if (cs%Nonlinear_continuity) &
3758 call get_param(param_file, mdl,
"NONLIN_BT_CONT_UPDATE_PERIOD", &
3759 cs%Nonlin_cont_update_period, &
3760 "If NONLINEAR_BT_CONTINUITY is true, this is the number \n"//&
3761 "of barotropic time steps between updates to the face \n"//&
3762 "areas, or 0 to update only before the barotropic stepping.",&
3763 units=
"nondim", default=1)
3764 call get_param(param_file, mdl,
"RESCALE_BT_FACE_AREAS", cs%rescale_D_bt, &
3765 "If true, the face areas used by the barotropic solver \n"//&
3766 "are rescaled to approximately reflect the open face \n"//&
3767 "areas of the interior layers. This probably requires \n"//&
3768 "FLUX_BT_COUPLING to work, and should not be used with \n"//&
3769 "USE_BT_CONT_TYPE.", default=.false.)
3770 call get_param(param_file, mdl,
"BT_MASS_SOURCE_LIMIT", cs%eta_source_limit, &
3771 "The fraction of the initial depth of the ocean that can \n"//&
3772 "be added to or removed from the bartropic solution \n"//&
3773 "within a thermodynamic time step. By default this is 0 \n"//&
3774 "for no correction.", units=
"nondim", default=0.0)
3775 call get_param(param_file, mdl,
"BT_PROJECT_VELOCITY", cs%BT_project_velocity,&
3776 "If true, step the barotropic velocity first and project \n"//&
3777 "out the velocity tendancy by 1+BEBT when calculating the \n"//&
3778 "transport. The default (false) is to use a predictor \n"//&
3779 "continuity step to find the pressure field, and then \n"//&
3780 "to do a corrector continuity step using a weighted \n"//&
3781 "average of the old and new velocities, with weights \n"//&
3782 "of (1-BEBT) and BEBT.", default=.false.)
3784 call get_param(param_file, mdl,
"DYNAMIC_SURFACE_PRESSURE", cs%dynamic_psurf, &
3785 "If true, add a dynamic pressure due to a viscous ice \n"//&
3786 "shelf, for instance.", default=.false.)
3787 if (cs%dynamic_psurf)
then 3788 call get_param(param_file, mdl,
"ICE_LENGTH_DYN_PSURF", cs%ice_strength_length, &
3789 "The length scale at which the Rayleigh damping rate due \n"//&
3790 "to the ice strength should be the same as if a Laplacian \n"//&
3791 "were applied, if DYNAMIC_SURFACE_PRESSURE is true.", &
3792 units=
"m", default=1.0e4)
3793 call get_param(param_file, mdl,
"DEPTH_MIN_DYN_PSURF", cs%Dmin_dyn_psurf, &
3794 "The minimum depth to use in limiting the size of the \n"//&
3795 "dynamic surface pressure for stability, if \n"//&
3796 "DYNAMIC_SURFACE_PRESSURE is true..", units=
"m", &
3798 call get_param(param_file, mdl,
"CONST_DYN_PSURF", cs%const_dyn_psurf, &
3799 "The constant that scales the dynamic surface pressure, \n"//&
3800 "if DYNAMIC_SURFACE_PRESSURE is true. Stable values \n"//&
3801 "are < ~1.0.", units=
"nondim", default=0.9)
3804 call get_param(param_file, mdl,
"TIDES", cs%tides, &
3805 "If true, apply tidal momentum forcing.", default=.false.)
3806 call get_param(param_file, mdl,
"SADOURNY", cs%Sadourny, &
3807 "If true, the Coriolis terms are discretized with the \n"//&
3808 "Sadourny (1975) energy conserving scheme, otherwise \n"//&
3809 "the Arakawa & Hsu scheme is used. If the internal \n"//&
3810 "deformation radius is not resolved, the Sadourny scheme \n"//&
3811 "should probably be used.", default=.true.)
3813 call get_param(param_file, mdl,
"BT_THICK_SCHEME", hvel_str, &
3814 "A string describing the scheme that is used to set the \n"//&
3815 "open face areas used for barotropic transport and the \n"//&
3816 "relative weights of the accelerations. Valid values are:\n"//&
3817 "\t ARITHMETIC - arithmetic mean layer thicknesses \n"//&
3818 "\t HARMONIC - harmonic mean layer thicknesses \n"//&
3819 "\t HYBRID (the default) - use arithmetic means for \n"//&
3820 "\t layers above the shallowest bottom, the harmonic \n"//&
3821 "\t mean for layers below, and a weighted average for \n"//&
3822 "\t layers that straddle that depth \n"//&
3823 "\t FROM_BT_CONT - use the average thicknesses kept \n"//&
3824 "\t in the h_u and h_v fields of the BT_cont_type", &
3826 select case (hvel_str)
3832 call mom_mesg(
'barotropic_init: BT_THICK_SCHEME ="'//trim(hvel_str)//
'"', 0)
3833 call mom_error(fatal,
"barotropic_init: Unrecognized setting "// &
3834 "#define BT_THICK_SCHEME "//trim(hvel_str)//
" found in input file.")
3836 if ((cs%hvel_scheme ==
from_bt_cont) .and. .not.use_bt_cont_type) &
3837 call mom_error(fatal,
"barotropic_init: BT_THICK_SCHEME FROM_BT_CONT "//&
3838 "can only be used if USE_BT_CONT_TYPE is defined.")
3840 call get_param(param_file, mdl,
"APPLY_BT_DRAG", apply_bt_drag, &
3841 "If defined, bottom drag is applied within the \n"//&
3842 "barotropic solver.", default=.true.)
3843 call get_param(param_file, mdl,
"BT_STRONG_DRAG", cs%strong_drag, &
3844 "If true, use a stronger estimate of the retarding \n"//&
3845 "effects of strong bottom drag, by making it implicit \n"//&
3846 "with the barotropic time-step instead of implicit with \n"//&
3847 "the baroclinic time-step and dividing by the number of \n"//&
3848 "barotropic steps.", default=.true.)
3850 call get_param(param_file, mdl,
"CLIP_BT_VELOCITY", cs%clip_velocity, &
3851 "If true, limit any velocity components that exceed \n"//&
3852 "MAXVEL. This should only be used as a desperate \n"//&
3853 "debugging measure.", default=.false.)
3854 call get_param(param_file, mdl,
"MAXVEL", cs%maxvel, &
3855 "The maximum velocity allowed before the velocity \n"//&
3856 "components are truncated.", units=
"m s-1", default=3.0e8, &
3857 do_not_log=.not.cs%clip_velocity)
3858 call get_param(param_file, mdl,
"MAXCFL_BT_CONT", cs%maxCFL_BT_cont, &
3859 "The maximum permitted CFL number associated with the \n"//&
3860 "barotropic accelerations from the summed velocities \n"//&
3861 "times the time-derivatives of thicknesses.", units=
"nondim", &
3864 call get_param(param_file, mdl,
"DT_BT_FILTER", cs%dt_bt_filter, &
3865 "A time-scale over which the barotropic mode solutions \n"//&
3866 "are filtered, in seconds if positive, or as a fraction \n"//&
3867 "of DT if negative. When used this can never be taken to \n"//&
3868 "be longer than 2*dt. Set this to 0 to apply no filtering.", &
3869 units=
"sec or nondim", default=-0.25)
3870 call get_param(param_file, mdl,
"G_BT_EXTRA", cs%G_extra, &
3871 "A nondimensional factor by which gtot is enhanced.", &
3872 units=
"nondim", default=0.0)
3873 call get_param(param_file, mdl,
"SSH_EXTRA", ssh_extra, &
3874 "An estimate of how much higher SSH might get, for use \n"//&
3875 "in calculating the safe external wave speed. The \n"//&
3876 "default is the minimum of 10 m or 5% of MAXIMUM_DEPTH.", &
3877 units=
"m", default=min(10.0,0.05*g%max_depth))
3879 call get_param(param_file, mdl,
"DEBUG", cs%debug, &
3880 "If true, write out verbose debugging data.", default=.false.)
3881 call get_param(param_file, mdl,
"DEBUG_BT", cs%debug_bt, &
3882 "If true, write out verbose debugging data within the \n"//&
3883 "barotropic time-stepping loop. The data volume can be \n"//&
3884 "quite large if this is true.", default=cs%debug)
3886 cs%linearized_BT_PV = .true.
3887 call get_param(param_file, mdl,
"BEBT", cs%bebt, &
3888 "BEBT determines whether the barotropic time stepping \n"//&
3889 "uses the forward-backward time-stepping scheme or a \n"//&
3890 "backward Euler scheme. BEBT is valid in the range from \n"//&
3891 "0 (for a forward-backward treatment of nonrotating \n"//&
3892 "gravity waves) to 1 (for a backward Euler treatment). \n"//&
3893 "In practice, BEBT must be greater than about 0.05.", &
3894 units=
"nondim", default=0.1)
3895 call get_param(param_file, mdl,
"DTBT", cs%dtbt, &
3896 "The barotropic time step, in s. DTBT is only used with \n"//&
3897 "the split explicit time stepping. To set the time step \n"//&
3898 "automatically based the maximum stable value use 0, or \n"//&
3899 "a negative value gives the fraction of the stable value. \n"//&
3900 "Setting DTBT to 0 is the same as setting it to -0.98. \n"//&
3901 "The value of DTBT that will actually be used is an \n"//&
3902 "integer fraction of DT, rounding down.", units=
"s or nondim",&
3906 if (apply_bt_drag)
then ; cs%drag_amp = 1.0 ;
else ; cs%drag_amp = 0.0 ;
endif 3909 call clone_mom_domain(g%Domain, cs%BT_Domain, min_halo=wd_halos, symmetric=.true.)
3910 #ifdef STATIC_MEMORY_ 3911 if (wd_halos(1) /= whaloi_+nihalo_)
call mom_error(fatal,
"barotropic_init: "//&
3912 "Barotropic x-halo sizes are incorrectly resized with STATIC_MEMORY_.")
3913 if (wd_halos(2) /= whaloj_+njhalo_)
call mom_error(fatal,
"barotropic_init: "//&
3914 "Barotropic y-halo sizes are incorrectly resized with STATIC_MEMORY_.")
3916 if (bt_halo_sz > 0)
then 3917 if (wd_halos(1) > bt_halo_sz) &
3918 call mom_mesg(
"barotropic_init: barotropic x-halo size increased.", 3)
3919 if (wd_halos(2) > bt_halo_sz) &
3920 call mom_mesg(
"barotropic_init: barotropic y-halo size increased.", 3)
3924 cs%isdw = g%isc-wd_halos(1) ; cs%iedw = g%iec+wd_halos(1)
3925 cs%jsdw = g%jsc-wd_halos(2) ; cs%jedw = g%jec+wd_halos(2)
3926 isdw = cs%isdw ; iedw = cs%iedw ; jsdw = cs%jsdw ; jedw = cs%jedw
3928 alloc_(cs%frhatu(isdb:iedb,jsd:jed,nz)) ; alloc_(cs%frhatv(isd:ied,jsdb:jedb,nz))
3929 alloc_(cs%eta_source(isd:ied,jsd:jed)) ; alloc_(cs%eta_cor(isd:ied,jsd:jed))
3930 if (cs%bound_BT_corr)
then 3931 alloc_(cs%eta_cor_bound(isd:ied,jsd:jed)) ; cs%eta_cor_bound(:,:) = 0.0
3933 alloc_(cs%IDatu(isdb:iedb,jsd:jed)) ; alloc_(cs%IDatv(isd:ied,jsdb:jedb))
3935 alloc_(cs%Datu_res(isdw-1:iedw,jsdw:jedw))
3936 alloc_(cs%Datv_res(isdw:iedw,jsdw-1:jedw))
3937 alloc_(cs%ua_polarity(isdw:iedw,jsdw:jedw))
3938 alloc_(cs%va_polarity(isdw:iedw,jsdw:jedw))
3940 cs%frhatu(:,:,:) = 0.0 ; cs%frhatv(:,:,:) = 0.0
3941 cs%eta_source(:,:) = 0.0 ; cs%eta_cor(:,:) = 0.0
3942 cs%IDatu(:,:) = 0.0 ; cs%IDatv(:,:) = 0.0
3943 cs%Datu_res(:,:) = 1.0 ; cs%Datv_res(:,:) = 1.0
3945 cs%ua_polarity(:,:) = 1.0 ; cs%va_polarity(:,:) = 1.0
3946 call pass_vector(cs%ua_polarity, cs%va_polarity, cs%BT_domain, to_all, agrid)
3948 if (use_bt_cont_type) &
3949 call alloc_bt_cont_type(bt_cont, g, (cs%hvel_scheme ==
from_bt_cont))
3952 allocate(cs%debug_BT_HI)
3953 cs%debug_BT_HI%isc=g%isc
3954 cs%debug_BT_HI%iec=g%iec
3955 cs%debug_BT_HI%jsc=g%jsc
3956 cs%debug_BT_HI%jec=g%jec
3957 cs%debug_BT_HI%IscB=g%isc-1
3958 cs%debug_BT_HI%IecB=g%iec
3959 cs%debug_BT_HI%JscB=g%jsc-1
3960 cs%debug_BT_HI%JecB=g%jec
3961 cs%debug_BT_HI%isd=cs%isdw
3962 cs%debug_BT_HI%ied=cs%iedw
3963 cs%debug_BT_HI%jsd=cs%jsdw
3964 cs%debug_BT_HI%jed=cs%jedw
3965 cs%debug_BT_HI%IsdB=cs%isdw-1
3966 cs%debug_BT_HI%IedB=cs%iedw
3967 cs%debug_BT_HI%JsdB=cs%jsdw-1
3968 cs%debug_BT_HI%JedB=cs%jedw
3973 alloc_(cs%IareaT(cs%isdw:cs%iedw,cs%jsdw:cs%jedw)) ; cs%IareaT(:,:) = 0.0
3974 alloc_(cs%bathyT(cs%isdw:cs%iedw,cs%jsdw:cs%jedw)) ; cs%bathyT(:,:) = gv%Angstrom_z
3975 alloc_(cs%IdxCu(cs%isdw-1:cs%iedw,cs%jsdw:cs%jedw)) ; cs%IdxCu(:,:) = 0.0
3976 alloc_(cs%IdyCv(cs%isdw:cs%iedw,cs%jsdw-1:cs%jedw)) ; cs%IdyCv(:,:) = 0.0
3977 alloc_(cs%dy_Cu(cs%isdw-1:cs%iedw,cs%jsdw:cs%jedw)) ; cs%dy_Cu(:,:) = 0.0
3978 alloc_(cs%dx_Cv(cs%isdw:cs%iedw,cs%jsdw-1:cs%jedw)) ; cs%dx_Cv(:,:) = 0.0
3979 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
3980 cs%IareaT(i,j) = g%IareaT(i,j)
3981 cs%bathyT(i,j) = g%bathyT(i,j)
3985 do j=g%jsd,g%jed ;
do i=g%IsdB,g%IedB
3986 cs%IdxCu(i,j) = g%IdxCu(i,j) ; cs%dy_Cu(i,j) = g%dy_Cu(i,j)
3988 do j=g%JsdB,g%JedB ;
do i=g%isd,g%ied
3989 cs%IdyCv(i,j) = g%IdyCv(i,j) ; cs%dx_Cv(i,j) = g%dx_Cv(i,j)
3991 call pass_var(cs%IareaT, cs%BT_domain, to_all)
3992 call pass_var(cs%bathyT, cs%BT_domain, to_all)
3993 call pass_vector(cs%IdxCu, cs%IdyCv, cs%BT_domain, to_all+scalar_pair)
3994 call pass_vector(cs%dy_Cu, cs%dx_Cv, cs%BT_domain, to_all+scalar_pair)
3996 if (cs%linearized_BT_PV)
then 3997 alloc_(cs%q_D(cs%isdw-1:cs%iedw,cs%jsdw-1:cs%jedw))
3998 alloc_(cs%D_u_Cor(cs%isdw-1:cs%iedw,cs%jsdw:cs%jedw))
3999 alloc_(cs%D_v_Cor(cs%isdw:cs%iedw,cs%jsdw-1:cs%jedw))
4000 cs%q_D(:,:) = 0.0 ; cs%D_u_Cor(:,:) = 0.0 ; cs%D_v_Cor(:,:) = 0.0
4001 do j=js,je ;
do i=is-1,ie
4002 cs%D_u_Cor(i,j) = 0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j))
4004 do j=js-1,je ;
do i=is,ie
4005 cs%D_v_Cor(i,j) = 0.5 * (g%bathyT(i,j+1) + g%bathyT(i,j))
4007 do j=js-1,je ;
do i=is-1,ie
4008 cs%q_D(i,j) = 0.25 * g%CoriolisBu(i,j) * &
4009 ((g%areaT(i,j) + g%areaT(i+1,j+1)) + (g%areaT(i+1,j) + g%areaT(i,j+1))) / &
4010 ((g%areaT(i,j) * g%bathyT(i,j) + g%areaT(i+1,j+1) * g%bathyT(i+1,j+1)) + &
4011 (g%areaT(i+1,j) * g%bathyT(i+1,j) + g%areaT(i,j+1) * g%bathyT(i,j+1)))
4015 call pass_var(cs%q_D, cs%BT_Domain, to_all, position=corner)
4016 call pass_vector(cs%D_u_Cor, cs%D_v_Cor, cs%BT_Domain, to_all+scalar_pair)
4020 dtbt_input = cs%dtbt
4021 cs%dtbt_fraction = 0.98 ;
if (cs%dtbt < 0.0) cs%dtbt_fraction = -cs%dtbt
4023 do k=1,g%ke ; gtot_estimate = gtot_estimate + gv%g_prime(k) ;
enddo 4024 call legacy_set_dtbt(g, gv, cs, gtot_est = gtot_estimate, ssh_add = ssh_extra)
4025 if (dtbt_input > 0.0) cs%dtbt = dtbt_input
4027 call log_param(param_file, mdl,
"!DTBT as used", cs%dtbt)
4028 call log_param(param_file, mdl,
"!estimated maximum DTBT", cs%dtbt_max)
4033 if (gv%Boussinesq)
then 4034 thickness_units =
"meter" ; flux_units =
"meter3 second-1" 4036 thickness_units =
"kilogram meter-2" ; flux_units =
"kilogram second-1" 4039 cs%id_PFu_bt = register_diag_field(
'ocean_model',
'PFuBT', diag%axesCu1, time, &
4040 'Zonal Anomalous Barotropic Pressure Force Force Acceleration',
'meter second-2')
4041 cs%id_PFv_bt = register_diag_field(
'ocean_model',
'PFvBT', diag%axesCv1, time, &
4042 'Meridional Anomalous Barotropic Pressure Force Acceleration',
'meter second-2')
4043 cs%id_Coru_bt = register_diag_field(
'ocean_model',
'CoruBT', diag%axesCu1, time, &
4044 'Zonal Barotropic Coriolis Acceleration',
'meter second-2')
4045 cs%id_Corv_bt = register_diag_field(
'ocean_model',
'CorvBT', diag%axesCv1, time, &
4046 'Meridional Barotropic Coriolis Acceleration',
'meter second-2')
4047 cs%id_uaccel = register_diag_field(
'ocean_model',
'u_accel_bt', diag%axesCu1, time, &
4048 'Barotropic zonal acceleration',
'meter second-2')
4049 cs%id_vaccel = register_diag_field(
'ocean_model',
'v_accel_bt', diag%axesCv1, time, &
4050 'Barotropic meridional acceleration',
'meter second-2')
4051 cs%id_ubtforce = register_diag_field(
'ocean_model',
'ubtforce', diag%axesCu1, time, &
4052 'Barotropic zonal acceleration from baroclinic terms',
'meter second-2')
4053 cs%id_vbtforce = register_diag_field(
'ocean_model',
'vbtforce', diag%axesCv1, time, &
4054 'Barotropic meridional acceleration from baroclinic terms',
'meter second-2')
4056 cs%id_eta_bt = register_diag_field(
'ocean_model',
'eta_bt', diag%axesT1, time, &
4057 'Barotropic end SSH', thickness_units)
4058 cs%id_ubt = register_diag_field(
'ocean_model',
'ubt', diag%axesCu1, time, &
4059 'Barotropic end zonal velocity',
'meter second-1')
4060 cs%id_vbt = register_diag_field(
'ocean_model',
'vbt', diag%axesCv1, time, &
4061 'Barotropic end meridional velocity',
'meter second-1')
4062 cs%id_eta_st = register_diag_field(
'ocean_model',
'eta_st', diag%axesT1, time, &
4063 'Barotropic start SSH', thickness_units)
4064 cs%id_ubt_st = register_diag_field(
'ocean_model',
'ubt_st', diag%axesCu1, time, &
4065 'Barotropic start zonal velocity',
'meter second-1')
4066 cs%id_vbt_st = register_diag_field(
'ocean_model',
'vbt_st', diag%axesCv1, time, &
4067 'Barotropic start meridional velocity',
'meter second-1')
4068 cs%id_ubtav = register_diag_field(
'ocean_model',
'ubtav', diag%axesCu1, time, &
4069 'Barotropic time-average zonal velocity',
'meter second-1')
4070 cs%id_vbtav = register_diag_field(
'ocean_model',
'vbtav', diag%axesCv1, time, &
4071 'Barotropic time-average meridional velocity',
'meter second-1')
4072 cs%id_eta_cor = register_diag_field(
'ocean_model',
'eta_cor', diag%axesT1, time, &
4073 'Corrective mass flux',
'meter second-1')
4074 cs%id_visc_rem_u = register_diag_field(
'ocean_model',
'visc_rem_u', diag%axesCuL, time, &
4075 'Viscous remnant at u',
'Nondim')
4076 cs%id_visc_rem_v = register_diag_field(
'ocean_model',
'visc_rem_v', diag%axesCvL, time, &
4077 'Viscous remnant at v',
'Nondim')
4078 cs%id_gtotn = register_diag_field(
'ocean_model',
'gtot_n', diag%axesT1, time, &
4079 'gtot to North',
'm s-2')
4080 cs%id_gtots = register_diag_field(
'ocean_model',
'gtot_s', diag%axesT1, time, &
4081 'gtot to South',
'm s-2')
4082 cs%id_gtote = register_diag_field(
'ocean_model',
'gtot_e', diag%axesT1, time, &
4083 'gtot to East',
'm s-2')
4084 cs%id_gtotw = register_diag_field(
'ocean_model',
'gtot_w', diag%axesT1, time, &
4085 'gtot to West',
'm s-2')
4086 cs%id_eta_hifreq = register_diag_field(
'ocean_model',
'eta_hifreq', diag%axesT1, time, &
4087 'High Frequency Barotropic SSH', thickness_units)
4088 cs%id_ubt_hifreq = register_diag_field(
'ocean_model',
'ubt_hifreq', diag%axesCu1, time, &
4089 'High Frequency Barotropic zonal velocity',
'meter second-1')
4090 cs%id_vbt_hifreq = register_diag_field(
'ocean_model',
'vbt_hifreq', diag%axesCv1, time, &
4091 'High Frequency Barotropic meridional velocity',
'meter second-1')
4092 cs%id_eta_pred_hifreq = register_diag_field(
'ocean_model',
'eta_pred_hifreq', diag%axesT1, time, &
4093 'High Frequency Predictor Barotropic SSH', thickness_units)
4094 cs%id_uhbt_hifreq = register_diag_field(
'ocean_model',
'uhbt_hifreq', diag%axesCu1, time, &
4095 'High Frequency Barotropic zonal transport',
'meter3 second-1')
4096 cs%id_vhbt_hifreq = register_diag_field(
'ocean_model',
'vhbt_hifreq', diag%axesCv1, time, &
4097 'High Frequency Barotropic meridional transport',
'meter3 second-1')
4098 if (cs%rescale_D_bt)
then 4099 cs%id_Datu_res = register_diag_field(
'ocean_model',
'Datu_res', diag%axesCu1, time, &
4100 'Rescaling for zonal face area in barotropic continuity',
'Nondimensional')
4101 cs%id_Datv_res = register_diag_field(
'ocean_model',
'Datv_res', diag%axesCv1, time, &
4102 'Rescaling for meridional face area in barotropic continuity',
'Nondimensional')
4104 cs%id_frhatu = register_diag_field(
'ocean_model',
'frhatu', diag%axesCuL, time, &
4105 'Fractional thickness of layers in u-columns',
'Nondim')
4106 cs%id_frhatv = register_diag_field(
'ocean_model',
'frhatv', diag%axesCvL, time, &
4107 'Fractional thickness of layers in v-columns',
'Nondim')
4108 cs%id_frhatu1 = register_diag_field(
'ocean_model',
'frhatu1', diag%axesCuL, time, &
4109 'Predictor Fractional thickness of layers in u-columns',
'Nondim')
4110 cs%id_frhatv1 = register_diag_field(
'ocean_model',
'frhatv1', diag%axesCvL, time, &
4111 'Predictor Fractional thickness of layers in v-columns',
'Nondim')
4112 cs%id_uhbt = register_diag_field(
'ocean_model',
'uhbt', diag%axesCu1, time, &
4113 'Barotropic zonal transport averaged over a baroclinic step',
'meter3 second-1')
4114 cs%id_vhbt = register_diag_field(
'ocean_model',
'vhbt', diag%axesCv1, time, &
4115 'Barotropic meridional transport averaged over a baroclinic step',
'meter3 second-1')
4117 if (cs%id_frhatu1 > 0)
call safe_alloc_ptr(cs%frhatu1, isdb,iedb,jsd,jed,nz)
4118 if (cs%id_frhatv1 > 0)
call safe_alloc_ptr(cs%frhatv1, isd,ied,jsdb,jedb,nz)
4120 if (.NOT.query_initialized(cs%ubtav,
"ubtav",restart_cs) .or. &
4121 .NOT.query_initialized(cs%vbtav,
"vbtav",restart_cs))
then 4123 do j=js-1,je+1 ;
do i=is-1,ie+1
4124 cs%ubtav(i,j) = 0.0 ; cs%vbtav(i,j) = 0.0
4126 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie+1
4127 cs%ubtav(i,j) = cs%ubtav(i,j) + cs%frhatu(i,j,k) * u(i,j,k)
4128 cs%vbtav(i,j) = cs%vbtav(i,j) + cs%frhatv(i,j,k) * v(i,j,k)
4129 enddo ;
enddo ;
enddo 4132 if (.NOT.query_initialized(cs%ubt_IC,
"ubt_IC",restart_cs) .or. &
4133 .NOT.query_initialized(cs%vbt_IC,
"vbt_IC",restart_cs))
then 4134 do j=js,je ;
do i=is-1,ie ; cs%ubt_IC(i,j) = cs%ubtav(i,j) ;
enddo ;
enddo 4135 do j=js-1,je ;
do i=is,ie ; cs%vbt_IC(i,j) = cs%vbtav(i,j) ;
enddo ;
enddo 4142 do j=js,je ;
do i=is-1,ie
4143 cs%IDatu(i,j) = g%mask2dCu(i,j) * 2.0 / (g%bathyT(i+1,j) + g%bathyT(i,j))
4145 do j=js-1,je ;
do i=is,ie
4146 cs%IDatv(i,j) = g%mask2dCv(i,j) * 2.0 / (g%bathyT(i,j+1) + g%bathyT(i,j))
4158 if (cs%bound_BT_corr)
then 4159 do j=js,je ;
do i=is,ie
4160 cs%eta_cor_bound(i,j) = gv%m_to_H * g%IareaT(i,j) * 0.1 * cs%maxvel * &
4161 ((datu(i-1,j) + datu(i,j)) + (datv(i,j) + datv(i,j-1)))
4165 if (.NOT.query_initialized(cs%uhbt_IC,
"uhbt_IC",restart_cs) .or. &
4166 .NOT.query_initialized(cs%vhbt_IC,
"vhbt_IC",restart_cs))
then 4167 do j=js,je ;
do i=is-1,ie ; cs%uhbt_IC(i,j) = cs%ubtav(i,j) * datu(i,j) ;
enddo ;
enddo 4168 do j=js-1,je ;
do i=is,ie ; cs%vhbt_IC(i,j) = cs%vbtav(i,j) * datv(i,j) ;
enddo ;
enddo 4171 call pass_vector(cs%ubt_IC, cs%vbt_IC, g%Domain, complete=.false.)
4172 call pass_vector(cs%uhbt_IC, cs%vhbt_IC, g%Domain, complete=.false.)
4173 call pass_vector(cs%ubtav, cs%vbtav, g%Domain)
4177 id_clock_calc_pre = cpu_clock_id(
'(Ocean BT pre-calcs only)', grain=clock_routine)
4178 id_clock_pass_pre = cpu_clock_id(
'(Ocean BT pre-step halo updates)', grain=clock_routine)
4179 id_clock_calc = cpu_clock_id(
'(Ocean BT stepping calcs only)', grain=clock_routine)
4180 id_clock_pass_step = cpu_clock_id(
'(Ocean BT stepping halo updates)', grain=clock_routine)
4182 id_clock_pass_post = cpu_clock_id(
'(Ocean BT post-step halo updates)', grain=clock_routine)
4183 if (dtbt_input <= 0.0) &
4184 id_clock_sync = cpu_clock_id(
'(Ocean BT global synch)', grain=clock_routine)
4190 dealloc_(cs%frhatu) ; dealloc_(cs%frhatv)
4191 dealloc_(cs%IDatu) ; dealloc_(cs%IDatv)
4192 dealloc_(cs%Datu_res) ; dealloc_(cs%Datv_res)
4193 dealloc_(cs%ubtav) ; dealloc_(cs%vbtav)
4194 dealloc_(cs%eta_cor) ; dealloc_(cs%eta_source)
4195 dealloc_(cs%ua_polarity) ; dealloc_(cs%va_polarity)
4196 if (cs%bound_BT_corr)
then 4197 dealloc_(cs%eta_cor_bound)
4206 type(hor_index_type),
intent(in) :: HI
4207 type(verticalgrid_type),
intent(in) :: GV
4208 type(param_file_type),
intent(in) :: param_file
4211 type(mom_restart_cs),
pointer :: restart_CS
4219 type(vardesc) :: vd(3)
4221 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
4222 isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed
4223 isdb = hi%IsdB ; iedb = hi%IedB ; jsdb = hi%JsdB ; jedb = hi%JedB
4225 if (
associated(cs))
then 4226 call mom_error(warning,
"register_barotropic_restarts called with an associated "// &
4227 "control structure.")
4232 alloc_(cs%ubtav(isdb:iedb,jsd:jed)) ; cs%ubtav(:,:) = 0.0
4233 alloc_(cs%vbtav(isd:ied,jsdb:jedb)) ; cs%vbtav(:,:) = 0.0
4234 alloc_(cs%ubt_IC(isdb:iedb,jsd:jed)) ; cs%ubt_IC(:,:) = 0.0
4235 alloc_(cs%vbt_IC(isd:ied,jsdb:jedb)) ; cs%vbt_IC(:,:) = 0.0
4236 alloc_(cs%uhbt_IC(isdb:iedb,jsd:jed)) ; cs%uhbt_IC(:,:) = 0.0
4237 alloc_(cs%vhbt_IC(isd:ied,jsdb:jedb)) ; cs%vhbt_IC(:,:) = 0.0
4239 vd(2) = var_desc(
"ubtav",
"meter second-1",
"Time mean barotropic zonal velocity", &
4240 hor_grid=
'u', z_grid=
'1')
4241 vd(3) = var_desc(
"vbtav",
"meter second-1",
"Time mean barotropic meridional velocity",&
4242 hor_grid=
'v', z_grid=
'1')
4243 call register_restart_field(cs%ubtav, vd(2), .false., restart_cs)
4244 call register_restart_field(cs%vbtav, vd(3), .false., restart_cs)
4246 vd(2) = var_desc(
"ubt_IC",
"meter second-1", &
4247 longname=
"Next initial condition for the barotropic zonal velocity", &
4248 hor_grid=
'u', z_grid=
'1')
4249 vd(3) = var_desc(
"vbt_IC",
"meter second-1", &
4250 longname=
"Next initial condition for the barotropic meridional velocity",&
4251 hor_grid=
'v', z_grid=
'1')
4252 call register_restart_field(cs%ubt_IC, vd(2), .false., restart_cs)
4253 call register_restart_field(cs%vbt_IC, vd(3), .false., restart_cs)
4255 if (gv%Boussinesq)
then 4256 vd(2) = var_desc(
"uhbt_IC",
"meter3 second-1", &
4257 longname=
"Next initial condition for the barotropic zonal transport", &
4258 hor_grid=
'u', z_grid=
'1')
4259 vd(3) = var_desc(
"vhbt_IC",
"meter3 second-1", &
4260 longname=
"Next initial condition for the barotropic meridional transport",&
4261 hor_grid=
'v', z_grid=
'1')
4263 vd(2) = var_desc(
"uhbt_IC",
"kg second-1", &
4264 longname=
"Next initial condition for the barotropic zonal transport", &
4265 hor_grid=
'u', z_grid=
'1')
4266 vd(3) = var_desc(
"vhbt_IC",
"kg second-1", &
4267 longname=
"Next initial condition for the barotropic meridional transport",&
4268 hor_grid=
'v', z_grid=
'1')
4270 call register_restart_field(cs%uhbt_IC, vd(2), .false., restart_cs)
4271 call register_restart_field(cs%vhbt_IC, vd(3), .false., restart_cs)
real function find_uhbt(u, BTC)
integer, parameter, public obc_direction_s
Indicates the boundary is an effective southern boundary.
real function find_vhbt(v, BTC)
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, 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...
subroutine, public legacy_bt_mass_source(h, eta, fluxes, set_cor, dt_therm, dt_since_therm, G, GV, CS)
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...
character *(20), parameter bt_cont_string
This module implements boundary forcing for MOM6.
integer, parameter, public to_all
character *(20), parameter arithmetic_string
Ocean grid type. See mom_grid for details.
subroutine destroy_bt_obc(BT_OBC)
character *(20), parameter hybrid_string
subroutine, public register_legacy_barotropic_restarts(HI, GV, param_file, CS, restart_CS)
This subroutine is used to register any fields from MOM_barotropic.F90 that should be written to or r...
integer, parameter arithmetic
subroutine find_face_areas(Datu, Datv, G, GV, CS, MS, rescale_faces, eta, halo, add_max)
Provides the ocean grid type.
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.
subroutine set_local_bt_cont_types(BT_cont, BTCL_u, BTCL_v, G, MS, BT_Domain, halo)
Container for horizontal index ranges for data, computational and global domains. ...
subroutine, public legacy_barotropic_end(CS)
integer, parameter, public obc_simple
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.
integer id_clock_calc_pre
The BT_cont_type structure contains information about the summed layer transports and how they will v...
integer, parameter, public obc_flather
integer, parameter hybrid
character *(20), parameter harmonic_string
logical function, public is_root_pe()
integer, parameter hybrid_bt_cont
integer id_clock_pass_step
integer id_clock_pass_post
subroutine, public legacy_barotropic_init(u, v, h, eta, Time, G, GV, param_file, diag, CS, restart_CS, BT_cont, tides_CSp)
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine, public 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.
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)
This subroutine applies the open boundary conditions on barotropic velocities and mass transports...
subroutine, public legacy_set_dtbt(G, GV, CS, eta, pbce, BT_cont, gtot_est, SSH_add)
The MOM_domain_type contains information about the domain decompositoin.
real function uhbt_to_ubt(uhbt, BTC, guess)
integer id_clock_pass_pre
subroutine, public legacy_btstep(use_fluxes, U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, fluxes, pbce, eta_PF_in, U_Cor, V_Cor, accel_layer_u, accel_layer_v, eta_out, uhbtav, vhbtav, G, GV, CS, visc_rem_u, visc_rem_v, etaav, uhbt_out, vhbt_out, OBC, BT_cont, eta_PF_start, taux_bot, tauy_bot, uh0, vh0, u_uh0, v_vh0)
subroutine bt_cont_to_face_areas(BT_cont, Datu, Datv, G, MS, halo, maximize)
integer, parameter, public obc_none
integer id_clock_calc_post
real function vhbt_to_vbt(vhbt, BTC, guess)
Controls where open boundary conditions are applied.
subroutine, public mom_error(level, message, all_print)
integer, parameter harmonic
subroutine, public legacy_btcalc(h, G, GV, CS, h_u, h_v, may_use_default)
This subroutine calculates the barotropic velocities from the full velocity and thickness fields...
integer, parameter from_bt_cont