25 implicit none ;
private
27 #include <MOM_memory.h>
52 logical :: cfl_based_trunc
64 logical :: cflrampingisactivated = .false.
65 type(time_type) :: rampstarttime
67 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NK_INTERFACE_) :: &
69 real allocable_,
dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: &
71 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NK_INTERFACE_) :: &
73 real allocable_,
dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: &
75 real,
pointer,
dimension(:,:) :: a1_shelf_u => null()
77 real,
pointer,
dimension(:,:) :: a1_shelf_v => null()
81 logical :: bottomdraglaw
86 logical :: channel_drag
89 logical :: harmonic_visc
97 logical :: direct_stress
99 logical :: dynamic_viscous_ml
103 logical :: answers_2018
109 integer,
pointer :: ntrunc
111 character(len=200) :: u_trunc_file
113 character(len=200) :: v_trunc_file
115 logical :: stokesmixing
123 integer :: id_du_dt_visc = -1, id_dv_dt_visc = -1, id_au_vv = -1, id_av_vv = -1
124 integer :: id_h_u = -1, id_h_v = -1, id_hml_u = -1 , id_hml_v = -1
125 integer :: id_ray_u = -1, id_ray_v = -1, id_taux_bot = -1, id_tauy_bot = -1
126 integer :: id_kv_slow = -1, id_kv_u = -1, id_kv_v = -1
149 subroutine vertvisc(u, v, h, forces, visc, dt, OBC, ADp, CDp, G, GV, US, CS, &
150 taux_bot, tauy_bot, Waves)
154 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
156 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
158 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
162 real,
intent(in) :: dt
168 real,
dimension(SZIB_(G),SZJ_(G)), &
169 optional,
intent(out) :: taux_bot
171 real,
dimension(SZI_(G),SZJB_(G)), &
172 optional,
intent(out) :: tauy_bot
175 optional,
pointer :: waves
184 real :: c1(szib_(g),szk_(g))
186 real :: ray(szib_(g),szk_(g))
201 real :: zds, hfr, h_a
202 real :: surface_stress(szib_(g))
205 logical :: do_i(szib_(g))
206 logical :: dostokesmixing
208 integer :: i, j, k, is, ie, isq, ieq, jsq, jeq, nz, n
209 is = g%isc ; ie = g%iec
210 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB ; nz = g%ke
212 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_vert_friction(visc): "// &
213 "Module must be initialized before it is used.")
215 if (cs%direct_stress)
then
216 hmix = cs%Hmix_stress
219 dt_rho0 = dt / gv%H_to_RZ
220 dt_z_to_h = dt*gv%Z_to_H
221 h_neglect = gv%H_subroundoff
225 dostokesmixing=.false.
226 if (cs%StokesMixing)
then
227 if (
present(waves)) dostokesmixing =
associated(waves)
228 if (.not. dostokesmixing) &
229 call mom_error(fatal,
"Stokes Mixing called without allocated"//&
230 "Waves Control Structure")
233 do k=1,nz ;
do i=isq,ieq ; ray(i,k) = 0.0 ;
enddo ;
enddo
242 do i=isq,ieq ; do_i(i) = (g%mask2dCu(i,j) > 0) ;
enddo
245 if (dostokesmixing)
then ;
do k=1,nz ;
do i=isq,ieq
246 if (do_i(i)) u(i,j,k) = u(i,j,k) + us%m_s_to_L_T*waves%Us_x(i,j,k)
247 enddo ;
enddo ;
endif
249 if (
associated(adp%du_dt_visc))
then ;
do k=1,nz ;
do i=isq,ieq
250 adp%du_dt_visc(i,j,k) = u(i,j,k)
251 enddo ;
enddo ;
endif
256 if (cs%direct_stress)
then
257 do i=isq,ieq ;
if (do_i(i))
then
258 surface_stress(i) = 0.0
260 stress = dt_rho0 * forces%taux(i,j)
262 h_a = 0.5 * (h(i,j,k) + h(i+1,j,k)) + h_neglect
263 hfr = 1.0 ;
if ((zds+h_a) > hmix) hfr = (hmix - zds) / h_a
264 u(i,j,k) = u(i,j,k) + i_hmix * hfr * stress
265 zds = zds + h_a ;
if (zds >= hmix)
exit
269 surface_stress(i) = dt_rho0 * (g%mask2dCu(i,j)*forces%taux(i,j))
272 if (cs%Channel_drag)
then ;
do k=1,nz ;
do i=isq,ieq
273 ray(i,k) = visc%Ray_u(i,j,k)
274 enddo ;
enddo ;
endif
299 do i=isq,ieq ;
if (do_i(i))
then
300 b_denom_1 = cs%h_u(i,j,1) + dt_z_to_h * (ray(i,1) + cs%a_u(i,j,1))
301 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h*cs%a_u(i,j,2))
302 d1(i) = b_denom_1 * b1(i)
303 u(i,j,1) = b1(i) * (cs%h_u(i,j,1) * u(i,j,1) + surface_stress(i))
305 do k=2,nz ;
do i=isq,ieq ;
if (do_i(i))
then
306 c1(i,k) = dt_z_to_h * cs%a_u(i,j,k) * b1(i)
307 b_denom_1 = cs%h_u(i,j,k) + dt_z_to_h * (ray(i,k) + cs%a_u(i,j,k)*d1(i))
308 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h * cs%a_u(i,j,k+1))
309 d1(i) = b_denom_1 * b1(i)
310 u(i,j,k) = (cs%h_u(i,j,k) * u(i,j,k) + &
311 dt_z_to_h * cs%a_u(i,j,k) * u(i,j,k-1)) * b1(i)
312 endif ;
enddo ;
enddo
316 do k=nz-1,1,-1 ;
do i=isq,ieq ;
if (do_i(i))
then
317 u(i,j,k) = u(i,j,k) + c1(i,k+1) * u(i,j,k+1)
318 endif ;
enddo ;
enddo
320 if (
associated(adp%du_dt_visc))
then ;
do k=1,nz ;
do i=isq,ieq
321 adp%du_dt_visc(i,j,k) = (u(i,j,k) - adp%du_dt_visc(i,j,k))*idt
322 enddo ;
enddo ;
endif
324 if (
associated(visc%taux_shelf))
then ;
do i=isq,ieq
325 visc%taux_shelf(i,j) = -gv%Rho0*cs%a1_shelf_u(i,j)*u(i,j,1)
328 if (
PRESENT(taux_bot))
then
330 taux_bot(i,j) = gv%Rho0 * (u(i,j,nz)*cs%a_u(i,j,nz+1))
332 if (cs%Channel_drag)
then ;
do k=1,nz ;
do i=isq,ieq
333 taux_bot(i,j) = taux_bot(i,j) + gv%Rho0 * (ray(i,k)*u(i,j,k))
334 enddo ;
enddo ;
endif
338 if (dostokesmixing)
then ;
do k=1,nz ;
do i=isq,ieq
339 if (do_i(i)) u(i,j,k) = u(i,j,k) - us%m_s_to_L_T*waves%Us_x(i,j,k)
340 enddo ;
enddo ;
endif
350 do i=is,ie ; do_i(i) = (g%mask2dCv(i,j) > 0) ;
enddo
353 if (dostokesmixing)
then ;
do k=1,nz ;
do i=is,ie
354 if (do_i(i)) v(i,j,k) = v(i,j,k) + us%m_s_to_L_T*waves%Us_y(i,j,k)
355 enddo ;
enddo ;
endif
357 if (
associated(adp%dv_dt_visc))
then ;
do k=1,nz ;
do i=is,ie
358 adp%dv_dt_visc(i,j,k) = v(i,j,k)
359 enddo ;
enddo ;
endif
364 if (cs%direct_stress)
then
365 do i=is,ie ;
if (do_i(i))
then
366 surface_stress(i) = 0.0
368 stress = dt_rho0 * forces%tauy(i,j)
370 h_a = 0.5 * (h(i,j,k) + h(i,j+1,k)) + h_neglect
371 hfr = 1.0 ;
if ((zds+h_a) > hmix) hfr = (hmix - zds) / h_a
372 v(i,j,k) = v(i,j,k) + i_hmix * hfr * stress
373 zds = zds + h_a ;
if (zds >= hmix)
exit
377 surface_stress(i) = dt_rho0 * (g%mask2dCv(i,j)*forces%tauy(i,j))
380 if (cs%Channel_drag)
then ;
do k=1,nz ;
do i=is,ie
381 ray(i,k) = visc%Ray_v(i,j,k)
382 enddo ;
enddo ;
endif
384 do i=is,ie ;
if (do_i(i))
then
385 b_denom_1 = cs%h_v(i,j,1) + dt_z_to_h * (ray(i,1) + cs%a_v(i,j,1))
386 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h*cs%a_v(i,j,2))
387 d1(i) = b_denom_1 * b1(i)
388 v(i,j,1) = b1(i) * (cs%h_v(i,j,1) * v(i,j,1) + surface_stress(i))
390 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
391 c1(i,k) = dt_z_to_h * cs%a_v(i,j,k) * b1(i)
392 b_denom_1 = cs%h_v(i,j,k) + dt_z_to_h * (ray(i,k) + cs%a_v(i,j,k)*d1(i))
393 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h * cs%a_v(i,j,k+1))
394 d1(i) = b_denom_1 * b1(i)
395 v(i,j,k) = (cs%h_v(i,j,k) * v(i,j,k) + dt_z_to_h * cs%a_v(i,j,k) * v(i,j,k-1)) * b1(i)
396 endif ;
enddo ;
enddo
397 do k=nz-1,1,-1 ;
do i=is,ie ;
if (do_i(i))
then
398 v(i,j,k) = v(i,j,k) + c1(i,k+1) * v(i,j,k+1)
399 endif ;
enddo ;
enddo
401 if (
associated(adp%dv_dt_visc))
then ;
do k=1,nz ;
do i=is,ie
402 adp%dv_dt_visc(i,j,k) = (v(i,j,k) - adp%dv_dt_visc(i,j,k))*idt
403 enddo ;
enddo ;
endif
405 if (
associated(visc%tauy_shelf))
then ;
do i=is,ie
406 visc%tauy_shelf(i,j) = -gv%Rho0*cs%a1_shelf_v(i,j)*v(i,j,1)
409 if (
present(tauy_bot))
then
411 tauy_bot(i,j) = gv%Rho0 * (v(i,j,nz)*cs%a_v(i,j,nz+1))
413 if (cs%Channel_drag)
then ;
do k=1,nz ;
do i=is,ie
414 tauy_bot(i,j) = tauy_bot(i,j) + gv%Rho0 * (ray(i,k)*v(i,j,k))
415 enddo ;
enddo ;
endif
419 if (dostokesmixing)
then ;
do k=1,nz ;
do i=is,ie
420 if (do_i(i)) v(i,j,k) = v(i,j,k) - us%m_s_to_L_T*waves%Us_y(i,j,k)
421 enddo ;
enddo ;
endif
425 call vertvisc_limit_vel(u, v, h, adp, cdp, forces, visc, dt, g, gv, us, cs)
428 if (
associated(obc))
then
429 do n=1,obc%number_of_segments
430 if (obc%segment(n)%specified)
then
431 if (obc%segment(n)%is_N_or_S)
then
432 j = obc%segment(n)%HI%JsdB
433 do k=1,nz ;
do i=obc%segment(n)%HI%isd,obc%segment(n)%HI%ied
434 v(i,j,k) = obc%segment(n)%normal_vel(i,j,k)
436 elseif (obc%segment(n)%is_E_or_W)
then
437 i = obc%segment(n)%HI%IsdB
438 do k=1,nz ;
do j=obc%segment(n)%HI%jsd,obc%segment(n)%HI%jed
439 u(i,j,k) = obc%segment(n)%normal_vel(i,j,k)
447 if (cs%id_du_dt_visc > 0) &
448 call post_data(cs%id_du_dt_visc, adp%du_dt_visc, cs%diag)
449 if (cs%id_dv_dt_visc > 0) &
450 call post_data(cs%id_dv_dt_visc, adp%dv_dt_visc, cs%diag)
451 if (
present(taux_bot) .and. (cs%id_taux_bot > 0)) &
452 call post_data(cs%id_taux_bot, taux_bot, cs%diag)
453 if (
present(tauy_bot) .and. (cs%id_tauy_bot > 0)) &
454 call post_data(cs%id_tauy_bot, tauy_bot, cs%diag)
462 subroutine vertvisc_remnant(visc, visc_rem_u, visc_rem_v, dt, G, GV, US, CS)
466 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
467 intent(inout) :: visc_rem_u
470 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
471 intent(inout) :: visc_rem_v
474 real,
intent(in) :: dt
481 real :: c1(szib_(g),szk_(g))
483 real :: ray(szib_(g),szk_(g))
487 logical :: do_i(szib_(g))
489 integer :: i, j, k, is, ie, isq, ieq, jsq, jeq, nz
490 is = g%isc ; ie = g%iec
491 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB ; nz = g%ke
493 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_vert_friction(visc): "// &
494 "Module must be initialized before it is used.")
496 dt_z_to_h = dt*gv%Z_to_H
498 do k=1,nz ;
do i=isq,ieq ; ray(i,k) = 0.0 ;
enddo ;
enddo
505 do i=isq,ieq ; do_i(i) = (g%mask2dCu(i,j) > 0) ;
enddo
507 if (cs%Channel_drag)
then ;
do k=1,nz ;
do i=isq,ieq
508 ray(i,k) = visc%Ray_u(i,j,k)
509 enddo ;
enddo ;
endif
511 do i=isq,ieq ;
if (do_i(i))
then
512 b_denom_1 = cs%h_u(i,j,1) + dt_z_to_h * (ray(i,1) + cs%a_u(i,j,1))
513 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h*cs%a_u(i,j,2))
514 d1(i) = b_denom_1 * b1(i)
515 visc_rem_u(i,j,1) = b1(i) * cs%h_u(i,j,1)
517 do k=2,nz ;
do i=isq,ieq ;
if (do_i(i))
then
518 c1(i,k) = dt_z_to_h * cs%a_u(i,j,k)*b1(i)
519 b_denom_1 = cs%h_u(i,j,k) + dt_z_to_h * (ray(i,k) + cs%a_u(i,j,k)*d1(i))
520 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h * cs%a_u(i,j,k+1))
521 d1(i) = b_denom_1 * b1(i)
522 visc_rem_u(i,j,k) = (cs%h_u(i,j,k) + dt_z_to_h * cs%a_u(i,j,k) * visc_rem_u(i,j,k-1)) * b1(i)
523 endif ;
enddo ;
enddo
524 do k=nz-1,1,-1 ;
do i=isq,ieq ;
if (do_i(i))
then
525 visc_rem_u(i,j,k) = visc_rem_u(i,j,k) + c1(i,k+1)*visc_rem_u(i,j,k+1)
527 endif ;
enddo ;
enddo
536 do i=is,ie ; do_i(i) = (g%mask2dCv(i,j) > 0) ;
enddo
538 if (cs%Channel_drag)
then ;
do k=1,nz ;
do i=is,ie
539 ray(i,k) = visc%Ray_v(i,j,k)
540 enddo ;
enddo ;
endif
542 do i=is,ie ;
if (do_i(i))
then
543 b_denom_1 = cs%h_v(i,j,1) + dt_z_to_h * (ray(i,1) + cs%a_v(i,j,1))
544 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h*cs%a_v(i,j,2))
545 d1(i) = b_denom_1 * b1(i)
546 visc_rem_v(i,j,1) = b1(i) * cs%h_v(i,j,1)
548 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
549 c1(i,k) = dt_z_to_h * cs%a_v(i,j,k)*b1(i)
550 b_denom_1 = cs%h_v(i,j,k) + dt_z_to_h * (ray(i,k) + cs%a_v(i,j,k)*d1(i))
551 b1(i) = 1.0 / (b_denom_1 + dt_z_to_h * cs%a_v(i,j,k+1))
552 d1(i) = b_denom_1 * b1(i)
553 visc_rem_v(i,j,k) = (cs%h_v(i,j,k) + dt_z_to_h * cs%a_v(i,j,k) * visc_rem_v(i,j,k-1)) * b1(i)
554 endif ;
enddo ;
enddo
555 do k=nz-1,1,-1 ;
do i=is,ie ;
if (do_i(i))
then
556 visc_rem_v(i,j,k) = visc_rem_v(i,j,k) + c1(i,k+1)*visc_rem_v(i,j,k+1)
557 endif ;
enddo ;
enddo
561 call uvchksum(
"visc_rem_[uv]", visc_rem_u, visc_rem_v, g%HI,haloshift=0)
570 subroutine vertvisc_coef(u, v, h, forces, visc, dt, G, GV, US, CS, OBC)
574 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
576 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
578 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
582 real,
intent(in) :: dt
592 real,
dimension(SZIB_(G),SZK_(G)) :: &
599 real,
dimension(SZIB_(G),SZK_(G)+1) :: &
606 real,
dimension(SZIB_(G)) :: &
619 real,
allocatable,
dimension(:,:) :: hml_u
620 real,
allocatable,
dimension(:,:) :: hml_v
621 real,
allocatable,
dimension(:,:,:) :: kv_u
622 real,
allocatable,
dimension(:,:,:) :: kv_v
623 real :: zcol(szi_(g))
637 logical,
dimension(SZIB_(G)) :: do_i, do_i_shelf
638 logical :: do_any_shelf
639 integer,
dimension(SZIB_(G)) :: &
642 integer :: i, j, k, is, ie, js, je, isq, ieq, jsq, jeq, nz
643 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
644 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB ; nz = g%ke
646 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_vert_friction(coef): "// &
647 "Module must be initialized before it is used.")
649 h_neglect = gv%H_subroundoff
650 i_hbbl(:) = 1.0 / (cs%Hbbl + h_neglect)
651 i_valbl = 0.0 ;
if (cs%harm_BL_val > 0.0) i_valbl = 1.0 / cs%harm_BL_val
653 if (cs%id_Kv_u > 0)
then
654 allocate(kv_u(g%IsdB:g%IedB,g%jsd:g%jed,g%ke)) ; kv_u(:,:,:) = 0.0
657 if (cs%id_Kv_v > 0)
then
658 allocate(kv_v(g%isd:g%ied,g%JsdB:g%JedB,g%ke)) ; kv_v(:,:,:) = 0.0
661 if (cs%debug .or. (cs%id_hML_u > 0))
then
662 allocate(hml_u(g%IsdB:g%IedB,g%jsd:g%jed)) ; hml_u(:,:) = 0.0
664 if (cs%debug .or. (cs%id_hML_v > 0))
then
665 allocate(hml_v(g%isd:g%ied,g%JsdB:g%JedB)) ; hml_v(:,:) = 0.0
668 if ((
associated(visc%taux_shelf) .or.
associated(forces%frac_shelf_u)) .and. &
669 .not.
associated(cs%a1_shelf_u))
then
670 allocate(cs%a1_shelf_u(g%IsdB:g%IedB,g%jsd:g%jed)) ; cs%a1_shelf_u(:,:)=0.0
672 if ((
associated(visc%tauy_shelf) .or.
associated(forces%frac_shelf_v)) .and. &
673 .not.
associated(cs%a1_shelf_v))
then
674 allocate(cs%a1_shelf_v(g%isd:g%ied,g%JsdB:g%JedB)) ; cs%a1_shelf_v(:,:)=0.0
681 do i=isq,ieq ; do_i(i) = (g%mask2dCu(i,j) > 0) ;
enddo
683 if (cs%bottomdraglaw)
then ;
do i=isq,ieq
684 kv_bbl(i) = visc%Kv_bbl_u(i,j)
685 bbl_thick(i) = visc%bbl_thick_u(i,j) * gv%Z_to_H + h_neglect
686 if (do_i(i)) i_hbbl(i) = 1.0 / bbl_thick(i)
689 do k=1,nz ;
do i=isq,ieq ;
if (do_i(i))
then
690 h_harm(i,k) = 2.0*h(i,j,k)*h(i+1,j,k) / (h(i,j,k)+h(i+1,j,k)+h_neglect)
691 h_arith(i,k) = 0.5*(h(i+1,j,k)+h(i,j,k))
692 h_delta(i,k) = h(i+1,j,k) - h(i,j,k)
693 endif ;
enddo ;
enddo
695 dmin(i) = min(g%bathyT(i,j), g%bathyT(i+1,j)) * gv%Z_to_H
700 if (
associated(obc))
then ;
if (obc%number_of_segments > 0)
then
701 do i=isq,ieq ;
if (do_i(i) .and. (obc%segnum_u(i,j) /= obc_none))
then
702 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then
703 do k=1,nz ; h_harm(i,k) = h(i,j,k) ; h_arith(i,k) = h(i,j,k) ; h_delta(i,k) = 0. ;
enddo
704 dmin(i) = g%bathyT(i,j) * gv%Z_to_H
706 elseif (obc%segment(obc%segnum_u(i,j))%direction ==
obc_direction_w)
then
707 do k=1,nz ; h_harm(i,k) = h(i+1,j,k) ; h_arith(i,k) = h(i+1,j,k) ; h_delta(i,k) = 0. ;
enddo
708 dmin(i) = g%bathyT(i+1,j) * gv%Z_to_H
719 if (cs%harmonic_visc)
then
720 do i=isq,ieq ; z_i(i,nz+1) = 0.0 ;
enddo
721 do k=nz,1,-1 ;
do i=isq,ieq ;
if (do_i(i))
then
722 hvel(i,k) = h_harm(i,k)
723 if (u(i,j,k) * h_delta(i,k) < 0)
then
724 z2 = z_i(i,k+1) ; botfn = 1.0 / (1.0 + 0.09*z2*z2*z2*z2*z2*z2)
725 hvel(i,k) = (1.0-botfn)*h_harm(i,k) + botfn*h_arith(i,k)
727 z_i(i,k) = z_i(i,k+1) + h_harm(i,k)*i_hbbl(i)
728 endif ;
enddo ;
enddo
730 do i=isq,ieq ; zh(i) = 0.0 ; z_i(i,nz+1) = 0.0 ;
enddo
731 do i=isq,ieq+1 ; zcol(i) = -g%bathyT(i,j) * gv%Z_to_H ;
enddo
733 do i=isq,ieq+1 ; zcol(i) = zcol(i) + h(i,j,k) ;
enddo
734 do i=isq,ieq ;
if (do_i(i))
then
735 zh(i) = zh(i) + h_harm(i,k)
737 z_clear = max(zcol(i),zcol(i+1)) + dmin(i)
738 if (zi_dir(i) < 0) z_clear = zcol(i) + dmin(i)
739 if (zi_dir(i) > 0) z_clear = zcol(i+1) + dmin(i)
741 z_i(i,k) = max(zh(i), z_clear) * i_hbbl(i)
743 hvel(i,k) = h_arith(i,k)
744 if (u(i,j,k) * h_delta(i,k) > 0)
then
745 if (zh(i) * i_hbbl(i) < cs%harm_BL_val)
then
746 hvel(i,k) = h_harm(i,k)
748 z2_wt = 1.0 ;
if (zh(i) * i_hbbl(i) < 2.0*cs%harm_BL_val) &
749 z2_wt = max(0.0, min(1.0, zh(i) * i_hbbl(i) * i_valbl - 1.0))
750 z2 = z2_wt * (max(zh(i), z_clear) * i_hbbl(i))
751 botfn = 1.0 / (1.0 + 0.09*z2*z2*z2*z2*z2*z2)
752 hvel(i,k) = (1.0-botfn)*h_arith(i,k) + botfn*h_harm(i,k)
761 dt, j, g, gv, us, cs, visc, forces, work_on_u=.true., obc=obc)
762 if (
allocated(hml_u))
then
763 do i=isq,ieq ;
if (do_i(i))
then ; hml_u(i,j) = h_ml(i) ;
endif ;
enddo
766 do_any_shelf = .false.
767 if (
associated(forces%frac_shelf_u))
then
769 cs%a1_shelf_u(i,j) = 0.0
770 do_i_shelf(i) = (do_i(i) .and. forces%frac_shelf_u(i,j) > 0.0)
771 if (do_i_shelf(i)) do_any_shelf = .true.
773 if (do_any_shelf)
then
774 if (cs%harmonic_visc)
then
776 kv_bbl, z_i, h_ml, dt, j, g, gv, us, cs, &
777 visc, forces, work_on_u=.true., obc=obc, shelf=.true.)
780 do i=isq,ieq ;
if (do_i_shelf(i))
then
781 zh(i) = 0.0 ; ztop_min(i) = min(zcol(i), zcol(i+1))
782 i_htbl(i) = 1.0 / (visc%tbl_thick_shelf_u(i,j)*gv%Z_to_H + h_neglect)
785 do i=isq,ieq+1 ; zcol(i) = zcol(i) - h(i,j,k) ;
enddo
786 do i=isq,ieq ;
if (do_i_shelf(i))
then
787 zh(i) = zh(i) + h_harm(i,k)
789 hvel_shelf(i,k) = hvel(i,k)
790 if (u(i,j,k) * h_delta(i,k) > 0)
then
791 if (zh(i) * i_htbl(i) < cs%harm_BL_val)
then
792 hvel_shelf(i,k) = min(hvel(i,k), h_harm(i,k))
794 z2_wt = 1.0 ;
if (zh(i) * i_htbl(i) < 2.0*cs%harm_BL_val) &
795 z2_wt = max(0.0, min(1.0, zh(i) * i_htbl(i) * i_valbl - 1.0))
796 z2 = z2_wt * (max(zh(i), ztop_min(i) - min(zcol(i),zcol(i+1))) * i_htbl(i))
797 topfn = 1.0 / (1.0 + 0.09*z2**6)
798 hvel_shelf(i,k) = min(hvel(i,k), (1.0-topfn)*h_arith(i,k) + topfn*h_harm(i,k))
804 bbl_thick, kv_bbl, z_i, h_ml, dt, j, g, gv, us, cs, &
805 visc, forces, work_on_u=.true., obc=obc, shelf=.true.)
807 do i=isq,ieq ;
if (do_i_shelf(i)) cs%a1_shelf_u(i,j) = a_shelf(i,1) ;
enddo
811 if (do_any_shelf)
then
812 do k=1,nz+1 ;
do i=isq,ieq ;
if (do_i_shelf(i))
then
813 cs%a_u(i,j,k) = forces%frac_shelf_u(i,j) * a_shelf(i,k) + &
814 (1.0-forces%frac_shelf_u(i,j)) * a_cpl(i,k)
818 elseif (do_i(i))
then
819 cs%a_u(i,j,k) = a_cpl(i,k)
820 endif ;
enddo ;
enddo
821 do k=1,nz ;
do i=isq,ieq ;
if (do_i_shelf(i))
then
823 cs%h_u(i,j,k) = forces%frac_shelf_u(i,j) * hvel_shelf(i,k) + &
824 (1.0-forces%frac_shelf_u(i,j)) * hvel(i,k)
825 elseif (do_i(i))
then
826 cs%h_u(i,j,k) = hvel(i,k)
827 endif ;
enddo ;
enddo
829 do k=1,nz+1 ;
do i=isq,ieq ;
if (do_i(i)) cs%a_u(i,j,k) = a_cpl(i,k) ;
enddo ;
enddo
830 do k=1,nz ;
do i=isq,ieq ;
if (do_i(i)) cs%h_u(i,j,k) = hvel(i,k) ;
enddo ;
enddo
834 if (cs%id_Kv_u > 0)
then
835 do k=1,nz ;
do i=isq,ieq
836 if (do_i(i)) kv_u(i,j,k) = 0.5 * gv%H_to_Z*(cs%a_u(i,j,k)+cs%a_u(i,j,k+1)) * cs%h_u(i,j,k)
848 do i=is,ie ; do_i(i) = (g%mask2dCv(i,j) > 0) ;
enddo
850 if (cs%bottomdraglaw)
then ;
do i=is,ie
851 kv_bbl(i) = visc%Kv_bbl_v(i,j)
852 bbl_thick(i) = visc%bbl_thick_v(i,j) * gv%Z_to_H + h_neglect
853 if (do_i(i)) i_hbbl(i) = 1.0 / bbl_thick(i)
856 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then
857 h_harm(i,k) = 2.0*h(i,j,k)*h(i,j+1,k) / (h(i,j,k)+h(i,j+1,k)+h_neglect)
858 h_arith(i,k) = 0.5*(h(i,j+1,k)+h(i,j,k))
859 h_delta(i,k) = h(i,j+1,k) - h(i,j,k)
860 endif ;
enddo ;
enddo
862 dmin(i) = min(g%bathyT(i,j), g%bathyT(i,j+1)) * gv%Z_to_H
867 if (
associated(obc))
then ;
if (obc%number_of_segments > 0)
then
868 do i=is,ie ;
if (do_i(i) .and. (obc%segnum_v(i,j) /= obc_none))
then
870 do k=1,nz ; h_harm(i,k) = h(i,j,k) ; h_arith(i,k) = h(i,j,k) ; h_delta(i,k) = 0. ;
enddo
871 dmin(i) = g%bathyT(i,j) * gv%Z_to_H
873 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then
874 do k=1,nz ; h_harm(i,k) = h(i,j+1,k) ; h_arith(i,k) = h(i,j+1,k) ; h_delta(i,k) = 0. ;
enddo
875 dmin(i) = g%bathyT(i,j+1) * gv%Z_to_H
886 if (cs%harmonic_visc)
then
887 do i=is,ie ; z_i(i,nz+1) = 0.0 ;
enddo
889 do k=nz,1,-1 ;
do i=is,ie ;
if (do_i(i))
then
890 hvel(i,k) = h_harm(i,k)
891 if (v(i,j,k) * h_delta(i,k) < 0)
then
892 z2 = z_i(i,k+1) ; botfn = 1.0 / (1.0 + 0.09*z2*z2*z2*z2*z2*z2)
893 hvel(i,k) = (1.0-botfn)*h_harm(i,k) + botfn*h_arith(i,k)
895 z_i(i,k) = z_i(i,k+1) + h_harm(i,k)*i_hbbl(i)
896 endif ;
enddo ;
enddo
899 zh(i) = 0.0 ; z_i(i,nz+1) = 0.0
900 zcol1(i) = -g%bathyT(i,j) * gv%Z_to_H
901 zcol2(i) = -g%bathyT(i,j+1) * gv%Z_to_H
903 do k=nz,1,-1 ;
do i=is,ie ;
if (do_i(i))
then
904 zh(i) = zh(i) + h_harm(i,k)
905 zcol1(i) = zcol1(i) + h(i,j,k) ; zcol2(i) = zcol2(i) + h(i,j+1,k)
907 z_clear = max(zcol1(i),zcol2(i)) + dmin(i)
908 if (zi_dir(i) < 0) z_clear = zcol1(i) + dmin(i)
909 if (zi_dir(i) > 0) z_clear = zcol2(i) + dmin(i)
911 z_i(i,k) = max(zh(i), z_clear) * i_hbbl(i)
913 hvel(i,k) = h_arith(i,k)
914 if (v(i,j,k) * h_delta(i,k) > 0)
then
915 if (zh(i) * i_hbbl(i) < cs%harm_BL_val)
then
916 hvel(i,k) = h_harm(i,k)
918 z2_wt = 1.0 ;
if (zh(i) * i_hbbl(i) < 2.0*cs%harm_BL_val) &
919 z2_wt = max(0.0, min(1.0, zh(i) * i_hbbl(i) * i_valbl - 1.0))
920 z2 = z2_wt * (max(zh(i), max(zcol1(i),zcol2(i)) + dmin(i)) * i_hbbl(i))
921 botfn = 1.0 / (1.0 + 0.09*z2*z2*z2*z2*z2*z2)
922 hvel(i,k) = (1.0-botfn)*h_arith(i,k) + botfn*h_harm(i,k)
926 endif ;
enddo ;
enddo
930 dt, j, g, gv, us, cs, visc, forces, work_on_u=.false., obc=obc)
931 if (
allocated(hml_v))
then
932 do i=is,ie ;
if (do_i(i))
then ; hml_v(i,j) = h_ml(i) ;
endif ;
enddo
934 do_any_shelf = .false.
935 if (
associated(forces%frac_shelf_v))
then
937 cs%a1_shelf_v(i,j) = 0.0
938 do_i_shelf(i) = (do_i(i) .and. forces%frac_shelf_v(i,j) > 0.0)
939 if (do_i_shelf(i)) do_any_shelf = .true.
941 if (do_any_shelf)
then
942 if (cs%harmonic_visc)
then
944 kv_bbl, z_i, h_ml, dt, j, g, gv, us, cs, visc, &
945 forces, work_on_u=.false., obc=obc, shelf=.true.)
948 do i=is,ie ;
if (do_i_shelf(i))
then
949 zh(i) = 0.0 ; ztop_min(i) = min(zcol1(i), zcol2(i))
950 i_htbl(i) = 1.0 / (visc%tbl_thick_shelf_v(i,j)*gv%Z_to_H + h_neglect)
953 do i=is,ie ;
if (do_i_shelf(i))
then
954 zcol1(i) = zcol1(i) - h(i,j,k) ; zcol2(i) = zcol2(i) - h(i,j+1,k)
955 zh(i) = zh(i) + h_harm(i,k)
957 hvel_shelf(i,k) = hvel(i,k)
958 if (v(i,j,k) * h_delta(i,k) > 0)
then
959 if (zh(i) * i_htbl(i) < cs%harm_BL_val)
then
960 hvel_shelf(i,k) = min(hvel(i,k), h_harm(i,k))
962 z2_wt = 1.0 ;
if (zh(i) * i_htbl(i) < 2.0*cs%harm_BL_val) &
963 z2_wt = max(0.0, min(1.0, zh(i) * i_htbl(i) * i_valbl - 1.0))
964 z2 = z2_wt * (max(zh(i), ztop_min(i) - min(zcol1(i),zcol2(i))) * i_htbl(i))
965 topfn = 1.0 / (1.0 + 0.09*z2**6)
966 hvel_shelf(i,k) = min(hvel(i,k), (1.0-topfn)*h_arith(i,k) + topfn*h_harm(i,k))
972 bbl_thick, kv_bbl, z_i, h_ml, dt, j, g, gv, us, cs, &
973 visc, forces, work_on_u=.false., obc=obc, shelf=.true.)
975 do i=is,ie ;
if (do_i_shelf(i)) cs%a1_shelf_v(i,j) = a_shelf(i,1) ;
enddo
979 if (do_any_shelf)
then
980 do k=1,nz+1 ;
do i=is,ie ;
if (do_i_shelf(i))
then
981 cs%a_v(i,j,k) = forces%frac_shelf_v(i,j) * a_shelf(i,k) + &
982 (1.0-forces%frac_shelf_v(i,j)) * a_cpl(i,k)
986 elseif (do_i(i))
then
987 cs%a_v(i,j,k) = a_cpl(i,k)
988 endif ;
enddo ;
enddo
989 do k=1,nz ;
do i=is,ie ;
if (do_i_shelf(i))
then
991 cs%h_v(i,j,k) = forces%frac_shelf_v(i,j) * hvel_shelf(i,k) + &
992 (1.0-forces%frac_shelf_v(i,j)) * hvel(i,k)
993 elseif (do_i(i))
then
994 cs%h_v(i,j,k) = hvel(i,k)
995 endif ;
enddo ;
enddo
997 do k=1,nz+1 ;
do i=is,ie ;
if (do_i(i)) cs%a_v(i,j,k) = a_cpl(i,k) ;
enddo ;
enddo
998 do k=1,nz ;
do i=is,ie ;
if (do_i(i)) cs%h_v(i,j,k) = hvel(i,k) ;
enddo ;
enddo
1002 if (cs%id_Kv_v > 0)
then
1003 do k=1,nz ;
do i=is,ie
1004 if (do_i(i)) kv_v(i,j,k) = 0.5 * gv%H_to_Z*(cs%a_v(i,j,k)+cs%a_v(i,j,k+1)) * cs%h_v(i,j,k)
1011 call uvchksum(
"vertvisc_coef h_[uv]", cs%h_u, cs%h_v, g%HI, haloshift=0, scale=gv%H_to_m)
1012 call uvchksum(
"vertvisc_coef a_[uv]", cs%a_u, cs%a_v, g%HI, haloshift=0, scale=us%Z_to_m*us%s_to_T)
1013 if (
allocated(hml_u) .and.
allocated(hml_v)) &
1014 call uvchksum(
"vertvisc_coef hML_[uv]", hml_u, hml_v, g%HI, haloshift=0, scale=gv%H_to_m)
1018 if (
associated(visc%Kv_slow) .and. (cs%id_Kv_slow > 0)) &
1019 call post_data(cs%id_Kv_slow, visc%Kv_slow, cs%diag)
1020 if (cs%id_Kv_u > 0)
call post_data(cs%id_Kv_u, kv_u, cs%diag)
1021 if (cs%id_Kv_v > 0)
call post_data(cs%id_Kv_v, kv_v, cs%diag)
1022 if (cs%id_au_vv > 0)
call post_data(cs%id_au_vv, cs%a_u, cs%diag)
1023 if (cs%id_av_vv > 0)
call post_data(cs%id_av_vv, cs%a_v, cs%diag)
1024 if (cs%id_h_u > 0)
call post_data(cs%id_h_u, cs%h_u, cs%diag)
1025 if (cs%id_h_v > 0)
call post_data(cs%id_h_v, cs%h_v, cs%diag)
1026 if (cs%id_hML_u > 0)
call post_data(cs%id_hML_u, hml_u, cs%diag)
1027 if (cs%id_hML_v > 0)
call post_data(cs%id_hML_v, hml_v, cs%diag)
1029 if (
allocated(hml_u))
deallocate(hml_u)
1030 if (
allocated(hml_v))
deallocate(hml_v)
1037 subroutine find_coupling_coef(a_cpl, hvel, do_i, h_harm, bbl_thick, kv_bbl, z_i, h_ml, &
1038 dt, j, G, GV, US, CS, visc, forces, work_on_u, OBC, shelf)
1042 real,
dimension(SZIB_(G),SZK_(GV)+1), &
1043 intent(out) :: a_cpl
1044 real,
dimension(SZIB_(G),SZK_(GV)), &
1046 logical,
dimension(SZIB_(G)), &
1048 real,
dimension(SZIB_(G),SZK_(GV)), &
1049 intent(in) :: h_harm
1051 real,
dimension(SZIB_(G)),
intent(in) :: bbl_thick
1052 real,
dimension(SZIB_(G)),
intent(in) :: kv_bbl
1053 real,
dimension(SZIB_(G),SZK_(GV)+1), &
1056 real,
dimension(SZIB_(G)),
intent(out) :: h_ml
1057 integer,
intent(in) :: j
1058 real,
intent(in) :: dt
1062 logical,
intent(in) :: work_on_u
1065 logical,
optional,
intent(in) :: shelf
1070 real,
dimension(SZIB_(G)) :: &
1079 real,
dimension(SZIB_(G),SZK_(GV)+1) :: &
1095 logical :: do_shelf, do_OBCs
1096 integer :: i, k, is, ie, max_nk
1103 if (work_on_u)
then ; is = g%IscB ; ie = g%IecB
1104 else ; is = g%isc ; ie = g%iec ;
endif
1106 h_neglect = gv%H_subroundoff
1111 if (cs%answers_2018)
then
1112 i_amax = (1.0e-10*us%Z_to_m) * dt
1117 do_shelf = .false. ;
if (
present(shelf)) do_shelf = shelf
1119 if (
associated(obc))
then ; do_obcs = (obc%number_of_segments > 0) ;
endif
1124 do i=is,ie ; kv_tot(i,1) = 0.0 ;
enddo
1125 if ((gv%nkml>0) .or. do_shelf)
then ;
do k=2,nz ;
do i=is,ie
1126 if (do_i(i)) kv_tot(i,k) = cs%Kv
1127 enddo ;
enddo ;
else
1128 i_hmix = 1.0 / (cs%Hmix + h_neglect)
1129 do i=is,ie ; z_t(i) = h_neglect*i_hmix ;
enddo
1130 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1131 z_t(i) = z_t(i) + h_harm(i,k-1)*i_hmix
1132 kv_tot(i,k) = cs%Kv + cs%Kvml / ((z_t(i)*z_t(i)) * &
1133 (1.0 + 0.09*z_t(i)*z_t(i)*z_t(i)*z_t(i)*z_t(i)*z_t(i)))
1134 endif ;
enddo ;
enddo
1137 do i=is,ie ;
if (do_i(i))
then
1138 if (cs%bottomdraglaw)
then
1140 if (r < bbl_thick(i))
then
1141 a_cpl(i,nz+1) = kv_bbl(i) / (i_amax*kv_bbl(i) + (r+h_neglect)*gv%H_to_Z)
1143 a_cpl(i,nz+1) = kv_bbl(i) / (i_amax*kv_bbl(i) + (bbl_thick(i)+h_neglect)*gv%H_to_Z)
1146 a_cpl(i,nz+1) = cs%Kvbbl / ((0.5*hvel(i,nz)+h_neglect)*gv%H_to_Z + i_amax*cs%Kvbbl)
1150 if (
associated(visc%Kv_shear))
then
1153 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1154 kv_add(i,k) = 0.5*(visc%Kv_shear(i,j,k) + visc%Kv_shear(i+1,j,k))
1155 endif ;
enddo ;
enddo
1157 do i=is,ie ;
if (do_i(i) .and. (obc%segnum_u(i,j) /= obc_none))
then
1158 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e)
then
1159 do k=2,nz ; kv_add(i,k) = visc%Kv_shear(i,j,k) ;
enddo
1160 elseif (obc%segment(obc%segnum_u(i,j))%direction ==
obc_direction_w)
then
1161 do k=2,nz ; kv_add(i,k) = visc%Kv_shear(i+1,j,k) ;
enddo
1165 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1166 kv_tot(i,k) = kv_tot(i,k) + kv_add(i,k)
1167 endif ;
enddo ;
enddo
1169 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1170 kv_add(i,k) = 0.5*(visc%Kv_shear(i,j,k) + visc%Kv_shear(i,j+1,k))
1171 endif ;
enddo ;
enddo
1173 do i=is,ie ;
if (do_i(i) .and. (obc%segnum_v(i,j) /= obc_none))
then
1175 do k=2,nz ; kv_add(i,k) = visc%Kv_shear(i,j,k) ;
enddo
1176 elseif (obc%segment(obc%segnum_v(i,j))%direction ==
obc_direction_s)
then
1177 do k=2,nz ; kv_add(i,k) = visc%Kv_shear(i,j+1,k) ;
enddo
1181 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1182 kv_tot(i,k) = kv_tot(i,k) + kv_add(i,k)
1183 endif ;
enddo ;
enddo
1187 if (
associated(visc%Kv_shear_Bu))
then
1189 do k=2,nz ;
do i=is,ie ;
If (do_i(i))
then
1190 kv_tot(i,k) = kv_tot(i,k) + (0.5)*(visc%Kv_shear_Bu(i,j-1,k) + visc%Kv_shear_Bu(i,j,k))
1191 endif ;
enddo ;
enddo
1193 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1194 kv_tot(i,k) = kv_tot(i,k) + (0.5)*(visc%Kv_shear_Bu(i-1,j,k) + visc%Kv_shear_Bu(i,j,k))
1195 endif ;
enddo ;
enddo
1199 do k=nz,2,-1 ;
do i=is,ie ;
if (do_i(i))
then
1203 botfn = 1.0 / (1.0 + 0.09*z2*z2*z2*z2*z2*z2)
1205 if (cs%bottomdraglaw)
then
1206 kv_tot(i,k) = kv_tot(i,k) + (kv_bbl(i) - cs%Kv)*botfn
1207 r = 0.5*(hvel(i,k) + hvel(i,k-1))
1208 if (r > bbl_thick(i))
then
1209 h_shear = ((1.0 - botfn) * r + botfn*bbl_thick(i)) + h_neglect
1211 h_shear = r + h_neglect
1214 kv_tot(i,k) = kv_tot(i,k) + (cs%Kvbbl-cs%Kv)*botfn
1215 h_shear = 0.5*(hvel(i,k) + hvel(i,k-1) + h_neglect)
1219 a_cpl(i,k) = kv_tot(i,k) / (h_shear*gv%H_to_Z + i_amax*kv_tot(i,k))
1220 endif ;
enddo ;
enddo
1224 do i=is,ie ;
if (do_i(i))
then
1226 kv_tbl(i) = visc%Kv_tbl_shelf_u(i,j)
1227 tbl_thick(i) = visc%tbl_thick_shelf_u(i,j) * gv%Z_to_H + h_neglect
1229 kv_tbl(i) = visc%Kv_tbl_shelf_v(i,j)
1230 tbl_thick(i) = visc%tbl_thick_shelf_v(i,j) * gv%Z_to_H + h_neglect
1235 if (0.5*hvel(i,1) > tbl_thick(i))
then
1236 a_cpl(i,1) = kv_tbl(i) / (tbl_thick(i)*gv%H_to_Z + i_amax*kv_tbl(i))
1238 a_cpl(i,1) = kv_tbl(i) / ((0.5*hvel(i,1)+h_neglect)*gv%H_to_Z + i_amax*kv_tbl(i))
1242 do k=2,nz ;
do i=is,ie ;
if (do_i(i))
then
1243 z_t(i) = z_t(i) + hvel(i,k-1) / tbl_thick(i)
1244 topfn = 1.0 / (1.0 + 0.09 * z_t(i)**6)
1246 r = 0.5*(hvel(i,k)+hvel(i,k-1))
1247 if (r > tbl_thick(i))
then
1248 h_shear = ((1.0 - topfn) * r + topfn*tbl_thick(i)) + h_neglect
1250 h_shear = r + h_neglect
1253 kv_top = topfn * kv_tbl(i)
1254 a_cpl(i,k) = a_cpl(i,k) + kv_top / (h_shear*gv%H_to_Z + i_amax*kv_top)
1255 endif ;
enddo ;
enddo
1256 elseif (cs%dynamic_viscous_ML .or. (gv%nkml>0))
then
1258 do i=is,ie ;
if (do_i(i))
then
1259 if (gv%nkml>0) nk_visc(i) = real(gv%nkml+1)
1261 u_star(i) = 0.5*(forces%ustar(i,j) + forces%ustar(i+1,j))
1262 absf(i) = 0.5*(abs(g%CoriolisBu(i,j-1)) + abs(g%CoriolisBu(i,j)))
1263 if (cs%dynamic_viscous_ML) nk_visc(i) = visc%nkml_visc_u(i,j) + 1
1265 u_star(i) = 0.5*(forces%ustar(i,j) + forces%ustar(i,j+1))
1266 absf(i) = 0.5*(abs(g%CoriolisBu(i-1,j)) + abs(g%CoriolisBu(i,j)))
1267 if (cs%dynamic_viscous_ML) nk_visc(i) = visc%nkml_visc_v(i,j) + 1
1269 h_ml(i) = h_neglect ; z_t(i) = 0.0
1270 max_nk = max(max_nk,ceiling(nk_visc(i) - 1.0))
1273 if (do_obcs)
then ;
if (work_on_u)
then
1274 do i=is,ie ;
if (do_i(i) .and. (obc%segnum_u(i,j) /= obc_none))
then
1275 if (obc%segment(obc%segnum_u(i,j))%direction == obc_direction_e) &
1276 u_star(i) = forces%ustar(i,j)
1278 u_star(i) = forces%ustar(i+1,j)
1281 do i=is,ie ;
if (do_i(i) .and. (obc%segnum_v(i,j) /= obc_none))
then
1283 u_star(i) = forces%ustar(i,j)
1285 u_star(i) = forces%ustar(i,j+1)
1289 do k=1,max_nk ;
do i=is,ie ;
if (do_i(i))
then
1290 if (k+1 <= nk_visc(i))
then
1291 h_ml(i) = h_ml(i) + hvel(i,k)
1292 elseif (k < nk_visc(i))
then
1293 h_ml(i) = h_ml(i) + (nk_visc(i) - k) * hvel(i,k)
1295 endif ;
enddo ;
enddo
1297 do k=2,max_nk ;
do i=is,ie ;
if (do_i(i))
then ;
if (k < nk_visc(i))
then
1299 z_t(i) = z_t(i) + hvel(i,k-1)
1300 temp1 = (z_t(i)*h_ml(i) - z_t(i)*z_t(i))*gv%H_to_Z
1303 visc_ml = u_star(i) * 0.41 * (temp1*u_star(i)) / (absf(i)*temp1 + (h_ml(i)+h_neglect)*u_star(i))
1304 a_ml = visc_ml / (0.25*(hvel(i,k)+hvel(i,k-1) + h_neglect) * gv%H_to_Z + 0.5*i_amax*visc_ml)
1306 if (a_ml > a_cpl(i,k)) a_cpl(i,k) = a_ml
1307 endif ;
endif ;
enddo ;
enddo
1315 subroutine vertvisc_limit_vel(u, v, h, ADp, CDp, forces, visc, dt, G, GV, US, CS)
1319 real,
dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
1321 real,
dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
1323 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1329 real,
intent(in) :: dt
1339 real :: vel_report(szib_(g),szjb_(g))
1340 real :: u_old(szib_(g),szj_(g),szk_(g))
1341 real :: v_old(szi_(g),szjb_(g),szk_(g))
1342 logical :: trunc_any, dowrite(szib_(g),szjb_(g))
1343 integer :: i, j, k, is, ie, js, je, isq, ieq, jsq, jeq, nz
1344 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1345 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
1348 truncvel = 0.9*maxvel
1349 h_report = 6.0 * gv%Angstrom_H
1350 dt_rho0 = (us%L_T_to_m_s*us%Z_to_m) * dt / gv%Rho0
1352 if (len_trim(cs%u_trunc_file) > 0)
then
1356 do i=isq,ieq ; dowrite(i,j) = .false. ;
enddo
1357 if (cs%CFL_based_trunc)
then
1358 do i=isq,ieq ; vel_report(i,j) = 3.0e8*us%m_s_to_L_T ;
enddo
1359 do k=1,nz ;
do i=isq,ieq
1360 if (abs(u(i,j,k)) < cs%vel_underflow) u(i,j,k) = 0.0
1361 if (u(i,j,k) < 0.0)
then
1362 cfl = (-u(i,j,k) * dt) * (g%dy_Cu(i,j) * g%IareaT(i+1,j))
1364 cfl = (u(i,j,k) * dt) * (g%dy_Cu(i,j) * g%IareaT(i,j))
1366 if (cfl > cs%CFL_trunc) trunc_any = .true.
1367 if (cfl > cs%CFL_report)
then
1368 dowrite(i,j) = .true.
1369 vel_report(i,j) = min(vel_report(i,j), abs(u(i,j,k)))
1373 do i=isq,ieq; vel_report(i,j) = maxvel;
enddo
1374 do k=1,nz ;
do i=isq,ieq
1375 if (abs(u(i,j,k)) < cs%vel_underflow)
then ; u(i,j,k) = 0.0
1376 elseif (abs(u(i,j,k)) > maxvel)
then
1377 dowrite(i,j) = .true. ; trunc_any = .true.
1382 do i=isq,ieq ;
if (dowrite(i,j))
then
1383 u_old(i,j,:) = u(i,j,:)
1386 if (trunc_any)
then ;
if (cs%CFL_based_trunc)
then
1387 do k=1,nz ;
do i=isq,ieq
1388 if ((u(i,j,k) * (dt * g%dy_Cu(i,j))) * g%IareaT(i+1,j) < -cs%CFL_trunc)
then
1389 u(i,j,k) = (-0.9*cs%CFL_trunc) * (g%areaT(i+1,j) / (dt * g%dy_Cu(i,j)))
1390 if (h(i,j,k) + h(i+1,j,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1391 elseif ((u(i,j,k) * (dt * g%dy_Cu(i,j))) * g%IareaT(i,j) > cs%CFL_trunc)
then
1392 u(i,j,k) = (0.9*cs%CFL_trunc) * (g%areaT(i,j) / (dt * g%dy_Cu(i,j)))
1393 if (h(i,j,k) + h(i+1,j,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1397 do k=1,nz ;
do i=isq,ieq ;
if (abs(u(i,j,k)) > maxvel)
then
1398 u(i,j,k) = sign(truncvel,u(i,j,k))
1399 if (h(i,j,k) + h(i+1,j,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1400 endif ;
enddo ;
enddo
1404 if (cs%CFL_based_trunc)
then
1406 do k=1,nz ;
do j=js,je ;
do i=isq,ieq
1407 if (abs(u(i,j,k)) < cs%vel_underflow)
then ; u(i,j,k) = 0.0
1408 elseif ((u(i,j,k) * (dt * g%dy_Cu(i,j))) * g%IareaT(i+1,j) < -cs%CFL_trunc)
then
1409 u(i,j,k) = (-0.9*cs%CFL_trunc) * (g%areaT(i+1,j) / (dt * g%dy_Cu(i,j)))
1410 if (h(i,j,k) + h(i+1,j,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1411 elseif ((u(i,j,k) * (dt * g%dy_Cu(i,j))) * g%IareaT(i,j) > cs%CFL_trunc)
then
1412 u(i,j,k) = (0.9*cs%CFL_trunc) * (g%areaT(i,j) / (dt * g%dy_Cu(i,j)))
1413 if (h(i,j,k) + h(i+1,j,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1415 enddo ;
enddo ;
enddo
1418 do k=1,nz ;
do j=js,je ;
do i=isq,ieq
1419 if (abs(u(i,j,k)) < cs%vel_underflow)
then ; u(i,j,k) = 0.0
1420 elseif (abs(u(i,j,k)) > maxvel)
then
1421 u(i,j,k) = sign(truncvel, u(i,j,k))
1422 if (h(i,j,k) + h(i+1,j,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1424 enddo ;
enddo ;
enddo
1428 if (len_trim(cs%u_trunc_file) > 0)
then
1429 do j=js,je;
do i=isq,ieq ;
if (dowrite(i,j))
then
1432 call write_u_accel(i, j, u_old, h, adp, cdp, dt, g, gv, us, cs%PointAccel_CSp, &
1433 vel_report(i,j), forces%taux(i,j)*dt_rho0, a=cs%a_u, hv=cs%h_u)
1434 endif ;
enddo ;
enddo
1437 if (len_trim(cs%v_trunc_file) > 0)
then
1441 do i=is,ie ; dowrite(i,j) = .false. ;
enddo
1442 if (cs%CFL_based_trunc)
then
1443 do i=is,ie ; vel_report(i,j) = 3.0e8*us%m_s_to_L_T ;
enddo
1444 do k=1,nz ;
do i=is,ie
1445 if (abs(v(i,j,k)) < cs%vel_underflow) v(i,j,k) = 0.0
1446 if (v(i,j,k) < 0.0)
then
1447 cfl = (-v(i,j,k) * dt) * (g%dx_Cv(i,j) * g%IareaT(i,j+1))
1449 cfl = (v(i,j,k) * dt) * (g%dx_Cv(i,j) * g%IareaT(i,j))
1451 if (cfl > cs%CFL_trunc) trunc_any = .true.
1452 if (cfl > cs%CFL_report)
then
1453 dowrite(i,j) = .true.
1454 vel_report(i,j) = min(vel_report(i,j), abs(v(i,j,k)))
1458 do i=is,ie ; vel_report(i,j) = maxvel ;
enddo
1459 do k=1,nz ;
do i=is,ie
1460 if (abs(v(i,j,k)) < cs%vel_underflow)
then ; v(i,j,k) = 0.0
1461 elseif (abs(v(i,j,k)) > maxvel)
then
1462 dowrite(i,j) = .true. ; trunc_any = .true.
1467 do i=is,ie ;
if (dowrite(i,j))
then
1468 v_old(i,j,:) = v(i,j,:)
1471 if (trunc_any)
then ;
if (cs%CFL_based_trunc)
then
1472 do k=1,nz;
do i=is,ie
1473 if ((v(i,j,k) * (dt * g%dx_Cv(i,j))) * g%IareaT(i,j+1) < -cs%CFL_trunc)
then
1474 v(i,j,k) = (-0.9*cs%CFL_trunc) * (g%areaT(i,j+1) / (dt * g%dx_Cv(i,j)))
1475 if (h(i,j,k) + h(i,j+1,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1476 elseif ((v(i,j,k) * (dt * g%dx_Cv(i,j))) * g%IareaT(i,j) > cs%CFL_trunc)
then
1477 v(i,j,k) = (0.9*cs%CFL_trunc) * (g%areaT(i,j) / (dt * g%dx_Cv(i,j)))
1478 if (h(i,j,k) + h(i,j+1,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1482 do k=1,nz ;
do i=is,ie ;
if (abs(v(i,j,k)) > maxvel)
then
1483 v(i,j,k) = sign(truncvel,v(i,j,k))
1484 if (h(i,j,k) + h(i,j+1,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1485 endif ;
enddo ;
enddo
1489 if (cs%CFL_based_trunc)
then
1491 do k=1,nz ;
do j=jsq,jeq ;
do i=is,ie
1492 if (abs(v(i,j,k)) < cs%vel_underflow)
then ; v(i,j,k) = 0.0
1493 elseif ((v(i,j,k) * (dt * g%dx_Cv(i,j))) * g%IareaT(i,j+1) < -cs%CFL_trunc)
then
1494 v(i,j,k) = (-0.9*cs%CFL_trunc) * (g%areaT(i,j+1) / (dt * g%dx_Cv(i,j)))
1495 if (h(i,j,k) + h(i,j+1,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1496 elseif ((v(i,j,k) * (dt * g%dx_Cv(i,j))) * g%IareaT(i,j) > cs%CFL_trunc)
then
1497 v(i,j,k) = (0.9*cs%CFL_trunc) * (g%areaT(i,j) / (dt * g%dx_Cv(i,j)))
1498 if (h(i,j,k) + h(i,j+1,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1500 enddo ;
enddo ;
enddo
1503 do k=1,nz ;
do j=jsq,jeq ;
do i=is,ie
1504 if (abs(v(i,j,k)) < cs%vel_underflow)
then ; v(i,j,k) = 0.0
1505 elseif (abs(v(i,j,k)) > maxvel)
then
1506 v(i,j,k) = sign(truncvel, v(i,j,k))
1507 if (h(i,j,k) + h(i,j+1,k) > h_report) cs%ntrunc = cs%ntrunc + 1
1509 enddo ;
enddo ;
enddo
1513 if (len_trim(cs%v_trunc_file) > 0)
then
1514 do j=jsq,jeq;
do i=is,ie ;
if (dowrite(i,j))
then
1517 call write_v_accel(i, j, v_old, h, adp, cdp, dt, g, gv, us, cs%PointAccel_CSp, &
1518 vel_report(i,j), forces%tauy(i,j)*dt_rho0, a=cs%a_v, hv=cs%h_v)
1519 endif ;
enddo ;
enddo
1525 subroutine vertvisc_init(MIS, Time, G, GV, US, param_file, diag, ADp, dirs, &
1528 target,
intent(in) :: mis
1531 type(time_type),
target,
intent(in) :: time
1536 type(
diag_ctrl),
target,
intent(inout) :: diag
1539 integer,
target,
intent(inout) :: ntrunc
1544 real :: hmix_str_dflt
1547 logical :: default_2018_answers
1548 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb, nz
1550 #include "version_variable.h"
1551 character(len=40) :: mdl =
"MOM_vert_friction"
1552 character(len=40) :: thickness_units
1554 if (
associated(cs))
then
1555 call mom_error(warning,
"vertvisc_init called with an associated "// &
1556 "control structure.")
1561 if (gv%Boussinesq) then; thickness_units =
"m"
1562 else; thickness_units =
"kg m-2";
endif
1564 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
1565 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
1567 cs%diag => diag ; cs%ntrunc => ntrunc ; ntrunc = 0
1571 call get_param(param_file, mdl,
"DEFAULT_2018_ANSWERS", default_2018_answers, &
1572 "This sets the default value for the various _2018_ANSWERS parameters.", &
1574 call get_param(param_file, mdl,
"VERT_FRICTION_2018_ANSWERS", cs%answers_2018, &
1575 "If true, use the order of arithmetic and expressions that recover the answers "//&
1576 "from the end of 2018. Otherwise, use expressions that do not use an arbitary "//&
1577 "and hard-coded maximum viscous coupling coefficient between layers.", &
1578 default=default_2018_answers)
1579 call get_param(param_file, mdl,
"BOTTOMDRAGLAW", cs%bottomdraglaw, &
1580 "If true, the bottom stress is calculated with a drag "//&
1581 "law of the form c_drag*|u|*u. The velocity magnitude "//&
1582 "may be an assumed value or it may be based on the "//&
1583 "actual velocity in the bottommost HBBL, depending on "//&
1584 "LINEAR_DRAG.", default=.true.)
1585 call get_param(param_file, mdl,
"CHANNEL_DRAG", cs%Channel_drag, &
1586 "If true, the bottom drag is exerted directly on each "//&
1587 "layer proportional to the fraction of the bottom it "//&
1588 "overlies.", default=.false.)
1589 call get_param(param_file, mdl,
"DIRECT_STRESS", cs%direct_stress, &
1590 "If true, the wind stress is distributed over the "//&
1591 "topmost HMIX_STRESS of fluid (like in HYCOM), and KVML "//&
1592 "may be set to a very small value.", default=.false.)
1593 call get_param(param_file, mdl,
"DYNAMIC_VISCOUS_ML", cs%dynamic_viscous_ML, &
1594 "If true, use a bulk Richardson number criterion to "//&
1595 "determine the mixed layer thickness for viscosity.", &
1597 call get_param(param_file, mdl,
"U_TRUNC_FILE", cs%u_trunc_file, &
1598 "The absolute path to a file into which the accelerations "//&
1599 "leading to zonal velocity truncations are written. "//&
1600 "Undefine this for efficiency if this diagnostic is not "//&
1601 "needed.", default=
" ", debuggingparam=.true.)
1602 call get_param(param_file, mdl,
"V_TRUNC_FILE", cs%v_trunc_file, &
1603 "The absolute path to a file into which the accelerations "//&
1604 "leading to meridional velocity truncations are written. "//&
1605 "Undefine this for efficiency if this diagnostic is not "//&
1606 "needed.", default=
" ", debuggingparam=.true.)
1607 call get_param(param_file, mdl,
"HARMONIC_VISC", cs%harmonic_visc, &
1608 "If true, use the harmonic mean thicknesses for "//&
1609 "calculating the vertical viscosity.", default=.false.)
1610 call get_param(param_file, mdl,
"HARMONIC_BL_SCALE", cs%harm_BL_val, &
1611 "A scale to determine when water is in the boundary "//&
1612 "layers based solely on harmonic mean thicknesses for "//&
1613 "the purpose of determining the extent to which the "//&
1614 "thicknesses used in the viscosities are upwinded.", &
1615 default=0.0, units=
"nondim")
1616 call get_param(param_file, mdl,
"DEBUG", cs%debug, default=.false.)
1619 call get_param(param_file, mdl,
"HMIX_FIXED", cs%Hmix, &
1620 "The prescribed depth over which the near-surface "//&
1621 "viscosity and diffusivity are elevated when the bulk "//&
1622 "mixed layer is not used.", units=
"m", scale=gv%m_to_H, &
1623 unscaled=hmix_m, fail_if_missing=.true.)
1624 if (cs%direct_stress)
then
1625 if (gv%nkml < 1)
then
1626 call get_param(param_file, mdl,
"HMIX_STRESS", cs%Hmix_stress, &
1627 "The depth over which the wind stress is applied if "//&
1628 "DIRECT_STRESS is true.", units=
"m", default=hmix_m, scale=gv%m_to_H)
1630 call get_param(param_file, mdl,
"HMIX_STRESS", cs%Hmix_stress, &
1631 "The depth over which the wind stress is applied if "//&
1632 "DIRECT_STRESS is true.", units=
"m", fail_if_missing=.true., scale=gv%m_to_H)
1634 if (cs%Hmix_stress <= 0.0)
call mom_error(fatal,
"vertvisc_init: " // &
1635 "HMIX_STRESS must be set to a positive value if DIRECT_STRESS is true.")
1637 call get_param(param_file, mdl,
"KV", cs%Kv, &
1638 "The background kinematic viscosity in the interior. "//&
1639 "The molecular value, ~1e-6 m2 s-1, may be used.", &
1640 units=
"m2 s-1", fail_if_missing=.true., scale=us%m2_s_to_Z2_T, unscaled=kv_dflt)
1642 if (gv%nkml < 1)
call get_param(param_file, mdl,
"KVML", cs%Kvml, &
1643 "The kinematic viscosity in the mixed layer. A typical "//&
1644 "value is ~1e-2 m2 s-1. KVML is not used if "//&
1645 "BULKMIXEDLAYER is true. The default is set by KV.", &
1646 units=
"m2 s-1", default=kv_dflt, scale=us%m2_s_to_Z2_T)
1647 if (.not.cs%bottomdraglaw)
call get_param(param_file, mdl,
"KVBBL", cs%Kvbbl, &
1648 "The kinematic viscosity in the benthic boundary layer. "//&
1649 "A typical value is ~1e-2 m2 s-1. KVBBL is not used if "//&
1650 "BOTTOMDRAGLAW is true. The default is set by KV.", &
1651 units=
"m2 s-1", default=kv_dflt, scale=us%m2_s_to_Z2_T)
1652 call get_param(param_file, mdl,
"HBBL", cs%Hbbl, &
1653 "The thickness of a bottom boundary layer with a "//&
1654 "viscosity of KVBBL if BOTTOMDRAGLAW is not defined, or "//&
1655 "the thickness over which near-bottom velocities are "//&
1656 "averaged for the drag law if BOTTOMDRAGLAW is defined "//&
1657 "but LINEAR_DRAG is not.", units=
"m", fail_if_missing=.true., scale=gv%m_to_H)
1658 call get_param(param_file, mdl,
"MAXVEL", cs%maxvel, &
1659 "The maximum velocity allowed before the velocity "//&
1660 "components are truncated.", units=
"m s-1", default=3.0e8, scale=us%m_s_to_L_T)
1661 call get_param(param_file, mdl,
"CFL_BASED_TRUNCATIONS", cs%CFL_based_trunc, &
1662 "If true, base truncations on the CFL number, and not an "//&
1663 "absolute speed.", default=.true.)
1664 call get_param(param_file, mdl,
"CFL_TRUNCATE", cs%CFL_trunc, &
1665 "The value of the CFL number that will cause velocity "//&
1666 "components to be truncated; instability can occur past 0.5.", &
1667 units=
"nondim", default=0.5)
1668 call get_param(param_file, mdl,
"CFL_REPORT", cs%CFL_report, &
1669 "The value of the CFL number that causes accelerations "//&
1670 "to be reported; the default is CFL_TRUNCATE.", &
1671 units=
"nondim", default=cs%CFL_trunc)
1672 call get_param(param_file, mdl,
"CFL_TRUNCATE_RAMP_TIME", cs%truncRampTime, &
1673 "The time over which the CFL truncation value is ramped "//&
1674 "up at the beginning of the run.", &
1675 units=
"s", default=0.)
1676 cs%CFL_truncE = cs%CFL_trunc
1677 call get_param(param_file, mdl,
"CFL_TRUNCATE_START", cs%CFL_truncS, &
1678 "The start value of the truncation CFL number used when "//&
1679 "ramping up CFL_TRUNC.", &
1680 units=
"nondim", default=0.)
1681 call get_param(param_file, mdl,
"STOKES_MIXING_COMBINED", cs%StokesMixing, &
1682 "Flag to use Stokes drift Mixing via the Lagrangian "//&
1683 " current (Eulerian plus Stokes drift). "//&
1684 " Still needs work and testing, so not recommended for use.",&
1695 if (cs%StokesMixing)
then
1696 call mom_error(fatal,
"Stokes mixing requires user intervention in the code.\n"//&
1697 " Model now exiting. See MOM_vert_friction.F90 for \n"//&
1698 " details (search 'BGR 04/04/2018' to locate comment).")
1700 call get_param(param_file, mdl,
"VEL_UNDERFLOW", cs%vel_underflow, &
1701 "A negligibly small velocity magnitude below which velocity "//&
1702 "components are set to 0. A reasonable value might be "//&
1703 "1e-30 m/s, which is less than an Angstrom divided by "//&
1704 "the age of the universe.", units=
"m s-1", default=0.0, scale=us%m_s_to_L_T)
1706 alloc_(cs%a_u(isdb:iedb,jsd:jed,nz+1)) ; cs%a_u(:,:,:) = 0.0
1707 alloc_(cs%h_u(isdb:iedb,jsd:jed,nz)) ; cs%h_u(:,:,:) = 0.0
1708 alloc_(cs%a_v(isd:ied,jsdb:jedb,nz+1)) ; cs%a_v(:,:,:) = 0.0
1709 alloc_(cs%h_v(isd:ied,jsdb:jedb,nz)) ; cs%h_v(:,:,:) = 0.0
1711 cs%id_Kv_slow = register_diag_field(
'ocean_model',
'Kv_slow', diag%axesTi, time, &
1712 'Slow varying vertical viscosity',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
1714 cs%id_Kv_u = register_diag_field(
'ocean_model',
'Kv_u', diag%axesCuL, time, &
1715 'Total vertical viscosity at u-points',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
1717 cs%id_Kv_v = register_diag_field(
'ocean_model',
'Kv_v', diag%axesCvL, time, &
1718 'Total vertical viscosity at v-points',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
1720 cs%id_au_vv = register_diag_field(
'ocean_model',
'au_visc', diag%axesCui, time, &
1721 'Zonal Viscous Vertical Coupling Coefficient',
'm s-1', conversion=us%Z_to_m*us%s_to_T)
1723 cs%id_av_vv = register_diag_field(
'ocean_model',
'av_visc', diag%axesCvi, time, &
1724 'Meridional Viscous Vertical Coupling Coefficient',
'm s-1', conversion=us%Z_to_m*us%s_to_T)
1726 cs%id_h_u = register_diag_field(
'ocean_model',
'Hu_visc', diag%axesCuL, time, &
1727 'Thickness at Zonal Velocity Points for Viscosity', thickness_units, &
1728 conversion=gv%H_to_m)
1730 cs%id_h_v = register_diag_field(
'ocean_model',
'Hv_visc', diag%axesCvL, time, &
1731 'Thickness at Meridional Velocity Points for Viscosity', thickness_units, &
1732 conversion=gv%H_to_m)
1734 cs%id_hML_u = register_diag_field(
'ocean_model',
'HMLu_visc', diag%axesCu1, time, &
1735 'Mixed Layer Thickness at Zonal Velocity Points for Viscosity', thickness_units, &
1736 conversion=gv%H_to_m)
1738 cs%id_hML_v = register_diag_field(
'ocean_model',
'HMLv_visc', diag%axesCv1, time, &
1739 'Mixed Layer Thickness at Meridional Velocity Points for Viscosity', thickness_units, &
1740 conversion=gv%H_to_m)
1742 cs%id_du_dt_visc = register_diag_field(
'ocean_model',
'du_dt_visc', diag%axesCuL, &
1743 time,
'Zonal Acceleration from Vertical Viscosity',
'm s-2', conversion=us%L_T2_to_m_s2)
1744 if (cs%id_du_dt_visc > 0)
call safe_alloc_ptr(adp%du_dt_visc,isdb,iedb,jsd,jed,nz)
1745 cs%id_dv_dt_visc = register_diag_field(
'ocean_model',
'dv_dt_visc', diag%axesCvL, &
1746 time,
'Meridional Acceleration from Vertical Viscosity',
'm s-2', conversion=us%L_T2_to_m_s2)
1747 if (cs%id_dv_dt_visc > 0)
call safe_alloc_ptr(adp%dv_dt_visc,isd,ied,jsdb,jedb,nz)
1749 cs%id_taux_bot = register_diag_field(
'ocean_model',
'taux_bot', diag%axesCu1, &
1750 time,
'Zonal Bottom Stress from Ocean to Earth',
'Pa', &
1751 conversion=us%R_to_kg_m3*us%L_T2_to_m_s2*us%Z_to_m)
1752 cs%id_tauy_bot = register_diag_field(
'ocean_model',
'tauy_bot', diag%axesCv1, &
1753 time,
'Meridional Bottom Stress from Ocean to Earth',
'Pa', &
1754 conversion=us%R_to_kg_m3*us%L_T2_to_m_s2*us%Z_to_m)
1756 if ((len_trim(cs%u_trunc_file) > 0) .or. (len_trim(cs%v_trunc_file) > 0)) &
1757 call pointaccel_init(mis, time, g, param_file, diag, dirs, cs%PointAccel_CSp)
1765 type(time_type),
target,
intent(in) :: time
1767 logical,
optional,
intent(in) :: activate
1771 real :: deltatime, wghta
1772 character(len=12) :: msg
1774 if (cs%truncRampTime==0.)
return
1778 if (
present(activate))
then
1780 cs%rampStartTime = time
1781 cs%CFLrampingIsActivated = .true.
1784 if (.not.cs%CFLrampingIsActivated)
return
1785 deltatime = max( 0., time_type_to_real( time - cs%rampStartTime ) )
1786 if (deltatime >= cs%truncRampTime)
then
1787 cs%CFL_trunc = cs%CFL_truncE
1788 cs%truncRampTime = 0.
1790 wghta = min( 1., deltatime / cs%truncRampTime )
1793 wghta = 1. - ( (1. - wghta)**2 )
1794 cs%CFL_trunc = cs%CFL_truncS + wghta * ( cs%CFL_truncE - cs%CFL_truncS )
1796 write(msg(1:12),
'(es12.3)') cs%CFL_trunc
1797 call mom_error(note,
"MOM_vert_friction: updateCFLtruncationValue set CFL"// &
1798 " limit to "//trim(msg))
1806 dealloc_(cs%a_u) ; dealloc_(cs%h_u)
1807 dealloc_(cs%a_v) ; dealloc_(cs%h_v)
1808 if (
associated(cs%a1_shelf_u))
deallocate(cs%a1_shelf_u)
1809 if (
associated(cs%a1_shelf_v))
deallocate(cs%a1_shelf_v)