44 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
45 use mom_cpu_clock, only : clock_module_driver, clock_module, clock_routine
56 implicit none ;
private 58 #include <MOM_memory.h> 96 integer :: max_rino_it
100 logical :: eliminate_massless
103 logical :: layer_stagger = .false.
104 logical :: debug = .false.
107 integer :: id_kd_shear = -1, id_tke = -1
108 integer :: id_ild2 = -1, id_dz_int = -1
112 character(len=40) ::
mdl =
"MOM_kappa_shear" 115 #undef ADD_DIAGNOSTICS 121 kv_io, dt, G, GV, CS, initialize_all)
124 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
126 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
128 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
133 real,
dimension(:,:),
pointer :: p_surf
135 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
136 intent(inout) :: kappa_io
140 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
141 intent(inout) :: tke_io
146 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
147 intent(inout) :: kv_io
151 real,
intent(in) :: dt
154 logical,
optional,
intent(in) :: initialize_all
184 real,
dimension(SZI_(G),SZK_(G)) :: &
186 u_2d, v_2d, T_2d, S_2d, rho_2d
187 real,
dimension(SZI_(G),SZK_(G)+1) :: &
189 real,
dimension(SZK_(G)) :: &
200 u_test, v_test, T_test, S_test
201 real,
dimension(SZK_(G)+1) :: &
243 real :: dist_from_bot
251 real :: tol_dksrc, tol2
252 real :: tol_dksrc_low
269 logical :: use_temperature
271 logical :: new_kappa = .true.
274 integer,
dimension(SZK_(G)+1) :: kc
277 real,
dimension(SZK_(G)+1) :: kf
279 integer :: ks_kappa, ke_kappa
280 integer :: dt_halvings
283 integer :: dt_refinements
286 integer :: is, ie, js, je, i, j, k, nz, nzc, itt, itt_dt
289 real,
dimension(SZK_(G)) :: &
293 real,
dimension(SZK_(G)+1) :: &
309 #ifdef ADD_DIAGNOSTICS 310 real,
dimension(SZK_(G)+1) :: &
312 real,
dimension(SZI_(G),SZK_(G)+1) :: &
314 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: &
318 integer :: max_debug_itt ;
parameter(max_debug_itt=20)
319 real :: wt(szk_(g)+1), wt_tot, I_wt_tot, wt_itt
320 real,
dimension(SZK_(G)+1) :: &
321 Ri_k, tke_prev, dtke, dkappa, dtke_norm, &
323 real,
dimension(SZK_(G)+1,0:max_debug_itt) :: &
324 tke_it1, N2_it1, Sh2_it1, ksrc_it1, kappa_it1, kprev_it1
325 real,
dimension(SZK_(G)+1,1:max_debug_itt) :: &
326 dkappa_it1, wt_it1, K_Q_it1, d_dkappa_it1, dkappa_norm
327 real,
dimension(SZK_(G),0:max_debug_itt) :: &
328 u_it1, v_it1, rho_it1, T_it1, S_it1
329 real,
dimension(0:max_debug_itt) :: &
330 dk_wt_it1, dkpos_wt_it1, dkneg_wt_it1, k_mag
331 real,
dimension(max_debug_itt) :: dt_it1
333 is = g%isc ; ie = g%iec; js = g%jsc ; je = g%jec ; nz = g%ke
337 tol_dksrc = 10.0 ; tol_dksrc_low = 0.95 ; tol2 = 2.0*cs%kappa_tol_err
340 use_temperature = .false. ;
if (
associated(tv%T)) use_temperature = .true.
341 new_kappa = .true. ;
if (
present(initialize_all)) new_kappa = initialize_all
343 ri_crit = cs%Rino_crit
344 gr0 = gv%Rho0*gv%g_Earth ; g_r0 = gv%g_Earth/gv%Rho0
347 dz_massless = 0.1*sqrt(k0dt)
352 #ifdef ADD_DIAGNOSTICS 365 #ifdef ADD_DIAGNOSTICS 371 do k=1,nz ;
do i=is,ie
372 h_2d(i,k) = h(i,j,k)*gv%H_to_m
373 u_2d(i,k) = u_in(i,j,k) ; v_2d(i,k) = v_in(i,j,k)
375 if (use_temperature)
then ;
do k=1,nz ;
do i=is,ie
376 t_2d(i,k) = tv%T(i,j,k) ; s_2d(i,k) = tv%S(i,j,k)
377 enddo ;
enddo ;
else ;
do k=1,nz ;
do i=is,ie
378 rho_2d(i,k) = gv%Rlay(k)
379 enddo ;
enddo ;
endif 380 if (.not.new_kappa)
then ;
do k=1,nz+1 ;
do i=is,ie
381 kappa_2d(i,k) = kappa_io(i,j,k)
382 enddo ;
enddo ;
endif 387 do i=is,ie ;
if (g%mask2dT(i,j) > 0.5)
then 391 if (cs%eliminate_massless)
then 395 dz(k) = 0.0 ; u0xdz(k) = 0.0 ; v0xdz(k) = 0.0
396 t0xdz(k) = 0.0 ; s0xdz(k) = 0.0
400 if ((k>cs%nkml) .and. (dz(nzc) > 0.0) .and. &
401 (h_2d(i,k) > dz_massless)) nzc = nzc+1
408 dz(nzc) = dz(nzc) + h_2d(i,k)
409 u0xdz(nzc) = u0xdz(nzc) + u_2d(i,k)*h_2d(i,k)
410 v0xdz(nzc) = v0xdz(nzc) + v_2d(i,k)*h_2d(i,k)
411 if (use_temperature)
then 412 t0xdz(nzc) = t0xdz(nzc) + t_2d(i,k)*h_2d(i,k)
413 s0xdz(nzc) = s0xdz(nzc) + s_2d(i,k)*h_2d(i,k)
415 t0xdz(nzc) = t0xdz(nzc) + rho_2d(i,k)*h_2d(i,k)
416 s0xdz(nzc) = s0xdz(nzc) + rho_2d(i,k)*h_2d(i,k)
421 do k=1,nzc ; idz(k) = 1.0 / dz(k) ;
enddo 425 kf(1) = 0.0 ; dz_in_lay = h_2d(i,1)
427 if (kc(k) > kc(k-1))
then 428 kf(k) = 0.0 ; dz_in_lay = h_2d(i,k)
430 kf(k) = dz_in_lay*idz(kc(k)) ; dz_in_lay = dz_in_lay + h_2d(i,k)
437 u0xdz(k) = u_2d(i,k)*dz(k) ; v0xdz(k) = v_2d(i,k)*dz(k)
439 if (use_temperature)
then 441 t0xdz(k) = t_2d(i,k)*dz(k) ; s0xdz(k) = s_2d(i,k)*dz(k)
445 t0xdz(k) = rho_2d(i,k)*dz(k) ; s0xdz(k) = rho_2d(i,k)*dz(k)
449 do k=1,nzc+1 ; kc(k) = k ; kf(k) = 0.0 ;
enddo 451 do k=1,nzc ; idz(k) = 1.0 / dz(k) ;
enddo 456 i_dz_int(1) = 2.0 / dz(1)
457 dist_from_top(1) = 0.0
459 i_dz_int(k) = 2.0 / (dz(k-1) + dz(k))
460 dist_from_top(k) = dist_from_top(k-1) + dz(k-1)
462 i_dz_int(nzc+1) = 2.0 / dz(nzc)
467 a1(2) = k0dt*i_dz_int(2)
468 b1 = 1.0 / (dz(1)+a1(2))
469 u(1) = b1 * u0xdz(1) ; v(1) = b1 * v0xdz(1)
470 t(1) = b1 * t0xdz(1) ; sal(1) = b1 * s0xdz(1)
471 c1(2) = a1(2) * b1 ; d1 = dz(1) * b1
473 bd1 = dz(k) + d1*a1(k)
474 a1(k+1) = k0dt*i_dz_int(k+1)
475 b1 = 1.0 / (bd1 + a1(k+1))
476 u(k) = b1 * (u0xdz(k) + a1(k)*u(k-1))
477 v(k) = b1 * (v0xdz(k) + a1(k)*v(k-1))
478 t(k) = b1 * (t0xdz(k) + a1(k)*t(k-1))
479 sal(k) = b1 * (s0xdz(k) + a1(k)*sal(k-1))
480 c1(k+1) = a1(k+1) * b1 ; d1 = bd1 * b1
485 b1 = 1.0 / ((dz(nzc) + d1*a1(nzc)) + k0dt*i_dz_int(nzc+1))
486 u(nzc) = b1 * (u0xdz(nzc) + a1(nzc)*u(nzc-1))
487 v(nzc) = b1 * (v0xdz(nzc) + a1(nzc)*v(nzc-1))
489 b1 = 1.0 / (dz(nzc) + d1*a1(nzc))
490 t(nzc) = b1 * (t0xdz(nzc) + a1(nzc)*t(nzc-1))
491 sal(nzc) = b1 * (s0xdz(nzc) + a1(nzc)*sal(nzc-1))
493 u(k) = u(k) + c1(k+1)*u(k+1) ; v(k) = v(k) + c1(k+1)*v(k+1)
494 t(k) = t(k) + c1(k+1)*t(k+1) ; sal(k) = sal(k) + c1(k+1)*sal(k+1)
498 b1 = 1.0 / (dz(1) + k0dt*i_dz_int(2))
499 u(1) = b1 * u0xdz(1) ; v(1) = b1 * v0xdz(1)
501 t(1) = b1 * t0xdz(1) ; sal(1) = b1 * s0xdz(1)
510 dz_int(1) = 0.0 ; dz_int(2) = dz(1)
512 norm = 1.0 / (dz(k)*(dz(k-1)+dz(k+1)) + 2.0*dz(k-1)*dz(k+1))
513 dz_int(k) = dz_int(k) + dz(k) * ( ((dz(k)+dz(k+1)) * dz(k-1)) * norm)
514 dz_int(k+1) = dz(k) * ( ((dz(k-1)+dz(k)) * dz(k+1)) * norm)
516 dz_int(nzc) = dz_int(nzc) + dz(nzc) ; dz_int(nzc+1) = 0.0
518 #ifdef ADD_DIAGNOSTICS 519 do k=1,nzc+1 ; i_ld2_1d(k) = 0.0 ;
enddo 524 dist_from_bot = dist_from_bot + dz(k)
525 i_l2_bdry(k) = (dist_from_top(k) + dist_from_bot)**2 / &
526 (dist_from_top(k) * dist_from_bot)**2
528 f2 = 0.25*((g%CoriolisBu(i,j)**2 + g%CoriolisBu(i-1,j-1)**2) + &
529 (g%CoriolisBu(i,j-1)**2 + g%CoriolisBu(i-1,j)**2))
532 if (use_temperature)
then 534 if (
associated(p_surf)) pressure(1) = p_surf(i,j)
536 pressure(k) = pressure(k-1) + gr0*dz(k-1)
537 t_int(k) = 0.5*(t(k-1) + t(k))
538 sal_int(k) = 0.5*(sal(k-1) + sal(k))
541 dbuoy_ds, 2, nzc-1, tv%eqn_of_state)
543 dbuoy_dt(k) = -g_r0*dbuoy_dt(k)
544 dbuoy_ds(k) = -g_r0*dbuoy_ds(k)
547 do k=1,nzc+1 ; dbuoy_dt(k) = -g_r0 ; dbuoy_ds(k) = 0.0 ;
enddo 554 do k=1,nzc+1 ; kappa(k) = 1.0 ; k_q(k) = 0.0 ;
enddo 556 do k=1,nzc+1 ; kappa(k) = kappa_2d(i,k) ; k_q(k) = 0.0 ;
enddo 560 n2(1) = 0.0 ; n2(nzc+1) = 0.0
562 n2(k) = max((dbuoy_dt(k) * (t0xdz(k-1)*idz(k-1) - t0xdz(k)*idz(k)) + &
563 dbuoy_ds(k) * (s0xdz(k-1)*idz(k-1) - s0xdz(k)*idz(k))) * &
567 u_it1(k,0) = u0xdz(k)*idz(k) ; v_it1(k,0) = v0xdz(k)*idz(k)
568 t_it1(k,0) = t0xdz(k)*idz(k) ; s_it1(k,0) = s0xdz(k)*idz(k)
571 kprev_it1(k,0) = kappa(k) ; kappa_it1(k,0) = kappa(k)
572 tke_it1(k,0) = tke(k)
573 n2_it1(k,0) = n2(k) ; sh2_it1(k,0) = s2(k) ; ksrc_it1(k,0) = k_src(k)
576 u_it1(k,0) = 0.0 ; v_it1(k,0) = 0.0
577 t_it1(k,0) = 0.0 ; s_it1(k,0) = 0.0
578 kprev_it1(k+1,0) = 0.0 ; kappa_it1(k+1,0) = 0.0 ; tke_it1(k+1,0) = 0.0
579 n2_it1(k+1,0) = 0.0 ; sh2_it1(k+1,0) = 0.0 ; ksrc_it1(k+1,0) = 0.0
581 do itt=1,max_debug_itt
584 u_it1(k,itt) = 0.0 ; v_it1(k,itt) = 0.0
585 t_it1(k,itt) = 0.0 ; s_it1(k,itt) = 0.0
589 kprev_it1(k,itt) = 0.0 ; kappa_it1(k,itt) = 0.0 ; tke_it1(k,itt) = 0.0
590 n2_it1(k,itt) = 0.0 ; sh2_it1(k,itt) = 0.0
591 ksrc_it1(k,itt) = 0.0
592 dkappa_it1(k,itt) = 0.0 ; wt_it1(k,itt) = 0.0
593 k_q_it1(k,itt) = 0.0 ; d_dkappa_it1(k,itt) = 0.0
596 do k=1,nz+1 ; ksrc_av(k) = 0.0 ;
enddo 601 dz, i_dz_int, dbuoy_dt, dbuoy_ds, &
602 u, v, t, sal, n2=n2, s2=s2)
608 kappa_avg(k) = 0.0 ; tke_avg(k) = 0.0
609 local_src_avg(k) = 0.0
611 if ( dz_int(k) > 0.0 ) &
612 local_src_avg(k) = 0.1 * k0dt * i_dz_int(k) / dz_int(k)
618 do itt=1,cs%max_KS_it
625 ri_k(k) = 1e3 ;
if (s2(k) > 1e-3*n2(k)) ri_k(k) = n2(k) / s2(k)
632 nzc, cs, k_q, tke, kappa_out, kappa_src, local_src)
637 ks_kappa = nz+1 ; ke_kappa = 0
638 do k=2,nzc ;
if (kappa_out(k) > 0.0)
then 641 do k=nzc,ks_kappa,-1 ;
if (kappa_out(k) > 0.0)
then 644 if (ke_kappa == nzc) kappa_out(nzc+1) = 0.0
650 if ((ke_kappa < ks_kappa) .or. (itt==cs%max_RiNo_it))
then 656 tol_max(k) = kappa_src(k) + tol_dksrc * local_src(k)
657 tol_min(k) = kappa_src(k) - tol_dksrc_low * local_src(k)
658 tol_chg(k) = tol2 * local_src_avg(k)
661 do itt_dt=1,(cs%max_KS_it+1-itt)/2
670 dz, i_dz_int, dbuoy_dt, dbuoy_ds, &
671 u_test, v_test, t_test, s_test, n2, s2, &
672 ks_int = ks_kappa, ke_int = ke_kappa)
675 do k=max(ks_kappa-1,2),min(ke_kappa+1,nzc)
676 if (n2(k) < ri_crit * s2(k))
then 677 k_src(k) = (2.0 * cs%Shearmix_rate * sqrt(s2(k))) * &
678 ((ri_crit*s2(k) - n2(k)) / (ri_crit*s2(k) + cs%FRi_curvature*n2(k)))
679 if ((k_src(k) > max(tol_max(k), kappa_src(k) + idtt*tol_chg(k))) .or. &
680 (k_src(k) < min(tol_min(k), kappa_src(k) - idtt*tol_chg(k))))
then 681 valid_dt = .false. ;
exit 684 if (0.0 < min(tol_min(k), kappa_src(k) - idtt*tol_chg(k)))
then 685 valid_dt = .false. ; k_src(k) = 0.0 ;
exit 691 dt_test = 0.5*dt_test
693 if ((dt_test < dt_rem) .and. valid_dt)
then 695 do itt_dt=1,dt_refinements
697 0.5*(dt_test+dt_inc), nzc, dz, i_dz_int, dbuoy_dt, &
698 dbuoy_ds, u_test, v_test, t_test, s_test, n2, s2, &
699 ks_int = ks_kappa, ke_int = ke_kappa)
701 idtt = 1.0 / (dt_test+dt_inc)
702 do k=max(ks_kappa-1,2),min(ke_kappa+1,nzc)
703 if (n2(k) < ri_crit * s2(k))
then 704 k_src(k) = (2.0 * cs%Shearmix_rate * sqrt(s2(k))) * &
705 ((ri_crit*s2(k) - n2(k)) / &
706 (ri_crit*s2(k) + cs%FRi_curvature*n2(k)))
707 if ((k_src(k) > max(tol_max(k), kappa_src(k) + idtt*tol_chg(k))) .or. &
708 (k_src(k) < min(tol_min(k), kappa_src(k) - idtt*tol_chg(k))))
then 709 valid_dt = .false. ;
exit 712 if (0.0 < min(tol_min(k), kappa_src(k) - idtt*tol_chg(k)))
then 713 valid_dt = .false. ; k_src(k) = 0.0 ;
exit 718 if (valid_dt) dt_test = dt_test + dt_inc
725 dt_now = min(dt_test*(1.0+cs%kappa_tol_err)+dt_inc,dt_rem)
727 local_src_avg(k) = local_src_avg(k) + dt_now * local_src(k)
734 if (ke_kappa < ks_kappa)
then 737 dt_wt = dt_rem / dt ; dt_rem = 0.0
742 tke_avg(k) = tke_avg(k) + dt_wt*tke(k)
744 tke_pred(k) = tke(k) ; kappa_pred(k) = 0.0 ; kappa(k) = 0.0
751 dz, i_dz_int, dbuoy_dt, dbuoy_ds, &
752 u_test, v_test, t_test, s_test, n2=n2, s2=s2, &
753 ks_int = ks_kappa, ke_int = ke_kappa)
757 do k=1,nzc+1 ; k_q_tmp(k) = k_q(k) ;
enddo 758 call find_kappa_tke(n2, s2, kappa_out, idz, dz_int, i_l2_bdry, f2, &
759 nzc, cs, k_q_tmp, tke_pred, kappa_pred)
762 ks_kappa = nz+1 ; ke_kappa = 0
764 kappa_mid(k) = 0.5*(kappa_out(k) + kappa_pred(k))
765 if ((kappa_mid(k) > 0.0) .and. (k<ks_kappa)) ks_kappa = k
766 if (kappa_mid(k) > 0.0) ke_kappa = k
771 dz, i_dz_int, dbuoy_dt, dbuoy_ds, &
772 u_test, v_test, t_test, s_test, n2=n2, s2=s2, &
773 ks_int = ks_kappa, ke_int = ke_kappa)
777 call find_kappa_tke(n2, s2, kappa_out, idz, dz_int, i_l2_bdry, f2, &
778 nzc, cs, k_q, tke_pred, kappa_pred)
782 dt_wt = dt_now / dt ; dt_rem = dt_rem - dt_now
784 kappa_mid(k) = 0.5*(kappa_out(k) + kappa_pred(k))
785 kappa_avg(k) = kappa_avg(k) + kappa_mid(k)*dt_wt
786 tke_avg(k) = tke_avg(k) + dt_wt*0.5*(tke_pred(k) + tke(k))
787 kappa(k) = kappa_pred(k)
792 if (dt_rem > 0.0)
then 796 dz, i_dz_int, dbuoy_dt, dbuoy_ds, &
797 u, v, t, sal, n2, s2)
802 if (itt <= max_debug_itt)
then 804 dk_wt_it1(itt) = 0.0 ; dkpos_wt_it1(itt) = 0.0 ; dkneg_wt_it1(itt) = 0.0
806 wt_itt = 1.0/
real(itt) ; wt_tot = 0.0
808 ksrc_av(k) = (1.0-wt_itt)*ksrc_av(k) + wt_itt*k_src(k)
809 wt_tot = wt_tot + dz_int(k) * ksrc_av(k)
812 i_wt_tot = 0.0 ;
if (wt_tot > 0.0) i_wt_tot = 1.0/wt_tot
815 wt(k) = (dz_int(k)*ksrc_av(k)) * i_wt_tot
816 k_mag(itt) = k_mag(itt) + wt(k)*kappa_mid(k)
817 dkappa_it1(k,itt) = kappa_pred(k) - kappa_out(k)
818 dk_wt_it1(itt) = dk_wt_it1(itt) + wt(k)*dkappa_it1(k,itt)
820 dkpos_wt_it1(itt) = dkpos_wt_it1(itt) + wt(k)*dkappa_it1(k,itt)
822 dkneg_wt_it1(itt) = dkneg_wt_it1(itt) + wt(k)*dkappa_it1(k,itt)
824 wt_it1(k,itt) = wt(k)
828 ri_k(k) = 1e3 ;
if (n2(k) < 1e3 * s2(k)) ri_k(k) = n2(k) / s2(k)
829 dtke(k) = tke_pred(k) - tke(k)
830 dtke_norm(k) = dtke(k) / (0.5*(tke(k) + tke_pred(k)))
831 dkappa(k) = kappa_pred(k) - kappa_out(k)
833 if (itt <= max_debug_itt)
then 835 u_it1(k,itt) = u(k) ; v_it1(k,itt) = v(k)
836 t_it1(k,itt) = t(k) ; s_it1(k,itt) = sal(k)
839 kprev_it1(k,itt)=kappa_out(k)
840 kappa_it1(k,itt)=kappa_mid(k) ; tke_it1(k,itt) = 0.5*(tke(k)+tke_pred(k))
841 n2_it1(k,itt)=n2(k) ; sh2_it1(k,itt)=s2(k)
842 ksrc_it1(k,itt) = kappa_src(k)
843 k_q_it1(k,itt) = kappa_out(k) / (tke(k))
845 if (abs(dkappa_it1(k,itt-1)) > 1e-20) &
846 d_dkappa_it1(k,itt) = dkappa_it1(k,itt) / dkappa_it1(k,itt-1)
848 dkappa_norm(k,itt) = dkappa(k) / max(0.5*(kappa_pred(k) + kappa_out(k)), 1e-100)
853 if (dt_rem <= 0.0)
exit 861 kappa_2d(i,k) = kappa_avg(k)
866 if (kf(k) == 0.0)
then 867 kappa_2d(i,k) = kappa_avg(kc(k))
868 tke_2d(i,k) = tke_avg(kc(k))
870 kappa_2d(i,k) = (1.0-kf(k)) * kappa_avg(kc(k)) + &
871 kf(k) * kappa_avg(kc(k)+1)
872 tke_2d(i,k) = (1.0-kf(k)) * tke_avg(kc(k)) + &
873 kf(k) * tke_avg(kc(k)+1)
877 #ifdef ADD_DIAGNOSTICS 878 i_ld2_2d(i,1) = 0.0 ; dz_int_2d(i,1) = dz_int(1)
880 i_ld2_2d(i,k) = (n2(k) / cs%lambda**2 + f2) / &
881 max(tke(k),1e-30) + i_l2_bdry(k)
882 dz_int_2d(i,k) = dz_int(k)
884 i_ld2_2d(i,nzc+1) = 0.0 ; dz_int_2d(i,nzc+1) = dz_int(nzc+1)
886 i_ld2_2d(i,k) = 0.0 ; dz_int_2d(i,k) = 0.0
892 kappa_2d(i,k) = 0.0 ; tke_2d(i,k) = 0.0
893 #ifdef ADD_DIAGNOSTICS 895 dz_int_2d(i,k) = dz_int(k)
900 do k=1,nz+1 ;
do i=is,ie
901 kappa_io(i,j,k) = g%mask2dT(i,j) * kappa_2d(i,k)
902 tke_io(i,j,k) = g%mask2dT(i,j) * tke_2d(i,k)
903 kv_io(i,j,k) = ( g%mask2dT(i,j) * kappa_2d(i,k) ) * cs%Prandtl_turb
904 #ifdef ADD_DIAGNOSTICS 905 i_ld2_3d(i,j,k) = i_ld2_2d(i,k)
906 dz_int_3d(i,j,k) = dz_int_2d(i,k)
913 call hchksum(kappa_io,
"kappa",g%HI)
914 call hchksum(tke_io,
"tke",g%HI)
917 if (cs%id_Kd_shear > 0)
call post_data(cs%id_Kd_shear, kappa_io, cs%diag)
918 if (cs%id_TKE > 0)
call post_data(cs%id_TKE, tke_io, cs%diag)
919 #ifdef ADD_DIAGNOSTICS 920 if (cs%id_ILd2 > 0)
call post_data(cs%id_ILd2, i_ld2_3d, cs%diag)
921 if (cs%id_dz_Int > 0)
call post_data(cs%id_dz_Int, dz_int_3d, cs%diag)
929 dz, I_dz_int, dbuoy_dT, dbuoy_dS, &
930 u, v, T, Sal, N2, S2, ks_int, ke_int)
934 integer,
intent(in) :: nz
936 real,
dimension(nz+1),
intent(in) :: kappa
938 real,
dimension(nz),
intent(in) :: u0
939 real,
dimension(nz),
intent(in) :: v0
940 real,
dimension(nz),
intent(in) :: T0
941 real,
dimension(nz),
intent(in) :: S0
942 real,
dimension(nz),
intent(in) :: dz
943 real,
dimension(nz+1),
intent(in) :: I_dz_int
945 real,
dimension(nz+1),
intent(in) :: dbuoy_dT
947 real,
dimension(nz+1),
intent(in) :: dbuoy_dS
949 real,
intent(in) :: dt
950 real,
dimension(nz),
intent(inout) :: u
951 real,
dimension(nz),
intent(inout) :: v
952 real,
dimension(nz),
intent(inout) :: T
953 real,
dimension(nz),
intent(inout) :: Sal
954 real,
dimension(nz+1),
optional, &
957 real,
dimension(nz+1),
optional, &
959 integer,
optional,
intent(in) :: ks_int
960 integer,
optional,
intent(in) :: ke_int
988 real,
dimension(nz+1) :: c1
989 real :: a_a, a_b, b1, d1, bd1, b1nz_0
993 if (
present(ks_int)) ks = max(ks_int-1,1)
994 if (
present(ke_int)) ke = min(ke_int,nz)
999 a_b = dt*(kappa(ks+1)*i_dz_int(ks+1))
1000 b1 = 1.0 / (dz(ks) + a_b)
1001 c1(ks+1) = a_b * b1 ; d1 = dz(ks) * b1
1003 u(ks) = (b1 * dz(ks))*u0(ks) ; v(ks) = (b1 * dz(ks))*v0(ks)
1004 t(ks) = (b1 * dz(ks))*t0(ks) ; sal(ks) = (b1 * dz(ks))*s0(ks)
1007 a_b = dt*(kappa(k+1)*i_dz_int(k+1))
1008 bd1 = dz(k) + d1*a_a
1009 b1 = 1.0 / (bd1 + a_b)
1010 c1(k+1) = a_b * b1 ; d1 = bd1 * b1
1012 u(k) = b1 * (dz(k)*u0(k) + a_a*u(k-1))
1013 v(k) = b1 * (dz(k)*v0(k) + a_a*v(k-1))
1014 t(k) = b1 * (dz(k)*t0(k) + a_a*t(k-1))
1015 sal(k) = b1 * (dz(k)*s0(k) + a_a*sal(k-1))
1022 b1 = 1.0 / (dz(ke) + d1*a_a)
1023 t(ke) = b1 * (dz(ke)*t0(ke) + a_a*t(ke-1))
1024 sal(ke) = b1 * (dz(ke)*s0(ke) + a_a*sal(ke-1))
1030 a_b = dt*(kappa(nz+1)*i_dz_int(nz+1))
1031 b1nz_0 = 1.0 / ((dz(nz) + d1*a_a) + a_b)
1035 u(ke) = b1nz_0 * (dz(ke)*u0(ke) + a_a*u(ke-1))
1036 v(ke) = b1nz_0 * (dz(ke)*v0(ke) + a_a*v(ke-1))
1039 u(k) = u(k) + c1(k+1)*u(k+1)
1040 v(k) = v(k) + c1(k+1)*v(k+1)
1041 t(k) = t(k) + c1(k+1)*t(k+1)
1042 sal(k) = sal(k) + c1(k+1)*sal(k+1)
1046 u(k) = u0(k) ; v(k) = v0(k) ; t(k) = t0(k) ; sal(k) = s0(k)
1050 if (
present(s2))
then 1051 s2(1) = 0.0 ; s2(nz+1) = 0.0
1053 s2(ks) = ((u(ks)-u0(ks-1))**2 + (v(ks)-v0(ks-1))**2) * i_dz_int(ks)**2
1055 s2(k) = ((u(k)-u(k-1))**2 + (v(k)-v(k-1))**2) * i_dz_int(k)**2
1058 s2(ke+1) = ((u0(ke+1)-u(ke))**2 + (v0(ke+1)-v(ke))**2) * i_dz_int(ke+1)**2
1061 if (
present(n2))
then 1062 n2(1) = 0.0 ; n2(nz+1) = 0.0
1064 n2(ks) = max(0.0, i_dz_int(ks) * &
1065 (dbuoy_dt(ks) * (t0(ks-1)-t(ks)) + dbuoy_ds(ks) * (s0(ks-1)-sal(ks))))
1067 n2(k) = max(0.0, i_dz_int(k) * &
1068 (dbuoy_dt(k) * (t(k-1)-t(k)) + dbuoy_ds(k) * (sal(k-1)-sal(k))))
1071 n2(ke+1) = max(0.0, i_dz_int(ke+1) * &
1072 (dbuoy_dt(ke+1) * (t(ke)-t0(ke+1)) + dbuoy_ds(ke+1) * (sal(ke)-s0(ke+1))))
1078 subroutine find_kappa_tke(N2, S2, kappa_in, Idz, dz_Int, I_L2_bdry, f2, &
1079 nz, CS, K_Q, tke, kappa, kappa_src, local_src)
1080 integer,
intent(in) :: nz
1081 real,
dimension(nz+1),
intent(in) :: N2
1083 real,
dimension(nz+1),
intent(in) :: S2
1084 real,
dimension(nz+1),
intent(in) :: kappa_in
1086 real,
dimension(nz+1),
intent(in) :: dz_Int
1088 real,
dimension(nz+1),
intent(in) :: I_L2_bdry
1090 real,
dimension(nz),
intent(in) :: Idz
1091 real,
intent(in) :: f2
1093 real,
dimension(nz+1),
intent(inout) :: K_Q
1096 real,
dimension(nz+1),
intent(out) :: tke
1098 real,
dimension(nz+1),
intent(out) :: kappa
1100 real,
dimension(nz+1),
optional, &
1101 intent(out) :: kappa_src
1102 real,
dimension(nz+1),
optional, &
1103 intent(out) :: local_src
1125 real,
dimension(nz) :: &
1129 real,
dimension(nz+1) :: &
1149 real :: cQcomp, cKcomp
1164 real :: eden1, eden2, I_eden, ome
1165 real :: diffusive_src
1173 real :: decay_term, I_Q, kap_src, v1, v2
1180 real,
parameter :: roundoff = 1.0e-16
1183 logical :: tke_noflux_bottom_BC = .false.
1184 logical :: tke_noflux_top_BC = .false.
1185 logical :: do_Newton
1186 logical :: abort_Newton
1188 logical :: was_Newton
1189 logical :: within_tolerance
1191 integer :: ks_src, ke_src
1192 integer :: ks_kappa, ke_kappa, ke_tke
1193 integer :: ks_kappa_prev, ke_kappa_prev
1194 integer :: itt, k, k2
1196 integer :: max_debug_itt ;
parameter(max_debug_itt=20)
1197 real :: K_err_lin, Q_err_lin
1198 real,
dimension(nz+1) :: &
1201 real,
dimension(nz+1,1:max_debug_itt) :: &
1202 tke_it1, kappa_it1, kprev_it1, &
1203 dkappa_it1, K_Q_it1, d_dkappa_it1, dkappa_norm_it1
1206 real :: max_TKE_err, min_TKE_err, TKE_err(nz)
1210 c_n2 = cs%C_N**2 ; c_s2 = cs%C_S**2
1211 q0 = cs%TKE_bg ; kappa0 = cs%kappa_0 ; tke_min = max(cs%TKE_bg,1.0e-20)
1212 ri_crit = cs%Rino_crit
1213 ilambda2 = 1.0 / cs%lambda**2
1214 kappa_trunc = 0.01*kappa0
1215 do_newton = .false. ; abort_newton = .false.
1216 tol_err = cs%kappa_tol_err
1219 ks_kappa = 2 ; ke_kappa = nz ; ks_kappa_prev = 2 ; ke_kappa_prev = nz
1221 ke_src = 0 ; ks_src = nz+1
1223 if (n2(k) < ri_crit * s2(k))
then 1227 k_src(k) = (2.0 * cs%Shearmix_rate * sqrt(s2(k))) * &
1228 ((ri_crit*s2(k) - n2(k)) / (ri_crit*s2(k) + cs%FRi_curvature*n2(k)))
1230 if (ks_src > k) ks_src = k
1237 if (ks_src > ke_src)
then 1239 kappa(k) = 0.0 ; k_q(k) = 0.0 ; tke(k) = tke_min
1241 if (
present(kappa_src))
then ;
do k=1,nz+1 ; kappa_src(k) = 0.0 ;
enddo ;
endif 1242 if (
present(local_src))
then ;
do k=1,nz+1 ; local_src(k) = 0.0 ;
enddo ;
endif 1247 kappa(k) = kappa_in(k)
1249 tke_decay(k) = sqrt(c_n2*n2(k) + c_s2*s2(k))
1250 if ((kappa(k) > 0.0) .and. (k_q(k) > 0.0))
then 1251 tke(k) = kappa(k) / k_q(k)
1257 kappa(1) = 0.0 ; kappa(nz+1) = 0.0
1262 eden2 = kappa0 * idz(nz)
1263 if (tke_noflux_bottom_bc)
then 1264 eden1 = dz_int(nz+1)*tke_decay(nz+1)
1265 i_eden = 1.0 / (eden2 + eden1)
1266 e1(nz+1) = eden2 * i_eden ; ome = eden1 * i_eden
1268 e1(nz+1) = 0.0 ; ome = 1.0
1271 eden1 = dz_int(k)*tke_decay(k) + ome * eden2
1272 eden2 = kappa0 * idz(k-1)
1273 i_eden = 1.0 / (eden2 + eden1)
1274 e1(k) = eden2 * i_eden ; ome = eden1 * i_eden
1280 do itt=1,cs%max_RiNo_it
1287 do k=1,nz+1 ; kappa_prev(k) = kappa(k) ; tke_prev(k) = tke(k) ;
enddo 1290 if (.not.do_newton)
then 1296 ke_tke = max(ke_kappa,ke_kappa_prev)+1
1298 do k=1,min(ke_tke,nz)
1299 aq(k) = (0.5*(kappa(k)+kappa(k+1))+kappa0) * idz(k)
1302 if (tke_noflux_top_bc)
then 1303 tke_src = kappa0*s2(1) + q0 * tke_decay(1)
1304 bd1 = dz_int(1) * tke_decay(1)
1305 bq = 1.0 / (bd1 + aq(1))
1306 tke(1) = bq * (dz_int(1)*tke_src)
1307 cq(2) = aq(1) * bq ; cqcomp = bd1 * bq
1309 tke(1) = q0 ; cq(2) = 0.0 ; cqcomp = 1.0
1313 tke_src = (kappa(k) + kappa0)*s2(k) + q0*tke_decay(k)
1314 bd1 = dz_int(k)*(tke_decay(k) + n2(k)*k_q(k)) + cqcomp*aq(k-1)
1315 bq = 1.0 / (bd1 + aq(k))
1316 tke(k) = bq * (dz_int(k)*tke_src + aq(k-1)*tke(k-1))
1317 cq(k+1) = aq(k) * bq ; cqcomp = bd1 * bq
1319 if ((ke_tke == nz+1) .and. .not.(tke_noflux_bottom_bc))
then 1324 tke_src = kappa0*s2(k) + q0*tke_decay(k)
1327 bq = 1.0 / (dz_int(k)*tke_decay(k) + cqcomp*aq(k-1))
1328 tke(k) = max(tke_min, bq * (dz_int(k)*tke_src + aq(k-1)*tke(k-1)))
1329 dq(k) = tke(k) + dq(k)
1331 bq = 1.0 / ((dz_int(k)*tke_decay(k) + cqcomp*aq(k-1)) + aq(k))
1332 cq(k+1) = aq(k) * bq
1335 tke(k) = max((bq * (dz_int(k)*tke_src + aq(k-1)*tke(k-1)) + &
1336 cq(k+1)*(tke(k+1) - e1(k+1)*tke(k))) / &
1337 (1.0 - cq(k+1)*e1(k+1)), tke_min)
1338 dq(k) = tke(k) + dq(k)
1343 dq(k) = e1(k)*dq(k-1)
1344 tke(k) = max(tke(k) + dq(k), tke_min)
1345 if (abs(dq(k)) < roundoff*tke(k))
exit 1348 if (dq(k2) == 0.0)
exit 1354 tke(k) = max(tke(k) + cq(k+1)*tke(k+1), tke_min)
1355 dq(k) = tke(k) + dq(k)
1362 ke_kappa_prev = ke_kappa ; ks_kappa_prev = ks_kappa
1365 ck(2) = 0.0 ; ckcomp = 1.0
1366 if (itt == 1)
then ;
dO k=2,nz
1367 i_ld2(k) = (n2(k)*ilambda2 + f2) / tke(k) + i_l2_bdry(k)
1372 i_ld2(k) = (n2(k)*ilambda2 + f2) / tke(k) + i_l2_bdry(k)
1373 bd1 = dz_int(k)*i_ld2(k) + ckcomp*idz(k-1)
1374 bk = 1.0 / (bd1 + idz(k))
1376 kappa(k) = bk * (idz(k-1)*kappa(k-1) + dz_int(k) * k_src(k))
1377 ck(k+1) = idz(k) * bk ; ckcomp = bd1 * bk
1380 if (kappa(k) < ckcomp*kappa_trunc)
then 1382 if (k > ke_src)
then ; ke_kappa = k-1 ; k_q(k) = 0.0 ;
exit ;
endif 1383 elseif (kappa(k) < 2.0*ckcomp*kappa_trunc)
then 1384 kappa(k) = 2.0 * (kappa(k) - ckcomp*kappa_trunc)
1387 k_q(ke_kappa) = kappa(ke_kappa) / tke(ke_kappa)
1388 dk(ke_kappa) = dk(ke_kappa) + kappa(ke_kappa)
1389 do k=ke_kappa+2,ke_kappa_prev
1390 dk(k) = -kappa(k) ; kappa(k) = 0.0 ; k_q(k) = 0.0
1392 do k=ke_kappa-1,2,-1
1393 kappa(k) = kappa(k) + ck(k+1)*kappa(k+1)
1395 if (kappa(k) <= kappa_trunc)
then 1397 if (k < ks_src)
then ; ks_kappa = k+1 ; k_q(k) = 0.0 ;
exit ;
endif 1398 elseif (kappa(k) < 2.0*kappa_trunc)
then 1399 kappa(k) = 2.0 * (kappa(k) - kappa_trunc)
1402 dk(k) = dk(k) + kappa(k)
1403 k_q(k) = kappa(k) / tke(k)
1405 do k=ks_kappa_prev,ks_kappa-2 ; kappa(k) = 0.0 ; k_q(k) = 0.0 ;
enddo 1410 ks_kappa_prev = ks_kappa ; ke_kappa_prev = ke_kappa ; ke_kappa = nz
1412 dk(1) = 0.0 ; ck(2) = 0.0 ; ckcomp = 1.0 ; dkdq(1) = 0.0
1413 aq(1) = (0.5*(kappa(1)+kappa(2))+kappa0) * idz(1)
1414 dqdz(1) = 0.5*(tke(1) - tke(2))*idz(1)
1415 if (tke_noflux_top_bc)
then 1416 tke_src = dz_int(1) * (kappa0*s2(1) - (tke(1) - q0)*tke_decay(1)) - &
1417 aq(1) * (tke(1) - tke(2))
1419 bq = 1.0 / (aq(1) + dz_int(1)*tke_decay(1))
1421 cqcomp = (dz_int(1)*tke_decay(1)) * bq
1422 dqmdk(2) = -dqdz(1) * bq
1423 dq(1) = bq * tke_src
1425 dq(1) = 0.0 ; cq(2) = 0.0 ; cqcomp = 1.0 ; dqmdk(2) = 0.0
1429 i_ld2(k) = (n2(k)*ilambda2 + f2) * i_q + i_l2_bdry(k)
1431 kap_src = dz_int(k) * (k_src(k) - i_ld2(k)*kappa(k)) + &
1432 idz(k-1)*(kappa(k-1)-kappa(k)) - idz(k)*(kappa(k)-kappa(k+1))
1436 decay_term = -idz(k-1)*dqmdk(k)*dkdq(k-1) + dz_int(k)*i_ld2(k)
1437 if (decay_term < 0.0)
then ; abort_newton = .true. ;
exit ;
endif 1438 bk = 1.0 / (idz(k) + idz(k-1)*ckcomp + decay_term)
1440 ck(k+1) = bk * idz(k)
1441 ckcomp = bk * (idz(k-1)*ckcomp + decay_term)
1442 dkdq(k) = bk * (idz(k-1)*dkdq(k-1)*cq(k) + &
1443 (n2(k)*ilambda2 + f2)*i_q**2*kappa(k))
1444 dk(k) = bk * (kap_src + idz(k-1)*dk(k-1) + idz(k-1)*dkdq(k-1)*dq(k-1))
1447 if (dk(k) <= ckcomp*(kappa_trunc - kappa(k)))
then 1448 dk(k) = -ckcomp*kappa(k)
1450 elseif (dk(k) < ckcomp*(2.0*kappa_trunc - kappa(k)))
then 1451 dk(k) = 2.0 * dk(k) - ckcomp*(2.0*kappa_trunc - kappa(k))
1455 aq(k) = (0.5*(kappa(k)+kappa(k+1))+kappa0) * idz(k)
1456 dqdz(k) = 0.5*(tke(k) - tke(k+1))*idz(k)
1457 tke_src = dz_int(k) * ((kappa(k) + kappa0)*s2(k) - kappa(k)*n2(k) - &
1458 (tke(k) - q0)*tke_decay(k)) - &
1459 (aq(k) * (tke(k) - tke(k+1)) - aq(k-1) * (tke(k-1) - tke(k)))
1460 v1 = aq(k-1) + dqdz(k-1)*dkdq(k-1)
1461 v2 = (v1*dqmdk(k) + dqdz(k-1)*ck(k)) + &
1462 ((dqdz(k-1) - dqdz(k)) + dz_int(k)*(s2(k) - n2(k)))
1466 decay_term = dz_int(k)*tke_decay(k) - dqdz(k-1)*dkdq(k-1)*cq(k) - v2*dkdq(k)
1467 if (decay_term < 0.0)
then ; abort_newton = .true. ;
exit ;
endif 1468 bq = 1.0 / (aq(k) + (cqcomp*aq(k-1) + decay_term))
1470 cq(k+1) = aq(k) * bq
1471 cqcomp = (cqcomp*aq(k-1) + decay_term) * bq
1472 dqmdk(k+1) = (v2 * ck(k+1) - dqdz(k)) * bq
1475 dq(k) = max(bq * ((v1 * dq(k-1) + dqdz(k-1)*dk(k-1)) + &
1476 (v2 * dk(k) + tke_src)), cqcomp*(-0.5*tke(k)))
1479 if ((itt > 1) .and. (k > ke_src) .and. (dk(k) == 0.0) .and. &
1480 ((kappa(k) + kappa(k+1)) == 0.0))
then 1482 ke_kappa = k-1 ;
exit 1485 if ((ke_kappa == nz) .and. (.not. abort_newton))
then 1486 dk(nz+1) = 0.0 ; dkdq(nz+1) = 0.0
1487 if (tke_noflux_bottom_bc)
then 1489 tke_src = dz_int(k) * (kappa0*s2(k) - (tke(k) - q0)*tke_decay(k)) + &
1490 aq(k-1) * (tke(k-1) - tke(k))
1492 v1 = aq(k-1) + dqdz(k-1)*dkdq(k-1)
1493 decay_term = max(0.0, dz_int(k)*tke_decay(k) - dqdz(k-1)*dkdq(k-1)*cq(k))
1494 if (decay_term < 0.0)
then 1495 abort_newton = .true.
1497 bq = 1.0 / (aq(k) + (cqcomp*aq(k-1) + decay_term))
1499 dq(k) = max(bq * ((v1 * dq(k-1) + dqdz(k-1)*dk(k-1)) + tke_src), &
1501 tke(k) = max(tke(k) + dq(k), tke_min)
1506 elseif (.not. abort_newton)
then 1508 dq(ke_kappa+1) = dq(ke_kappa+1) / (1.0 - cq(ke_kappa+2)*e1(ke_kappa+2))
1509 tke(ke_kappa+1) = max(tke(ke_kappa+1) + dq(ke_kappa+1), tke_min)
1510 do k=ke_kappa+2,nz+1
1514 aq(k) = (0.5*(kappa(k)+kappa(k+1))+kappa0) * idz(k)
1515 tke_src = (dz_int(k) * (kappa0*s2(k) - (tke(k)-q0)*tke_decay(k)) - &
1516 (aq(k) * (tke(k) - tke(k+1)) - &
1517 aq(k-1) * (tke(k-1) - tke(k))) ) / &
1518 (aq(k) + (aq(k-1) + dz_int(k)*tke_decay(k)))
1523 dq(k) = max(e1(k)*dq(k-1),-0.5*tke(k))
1524 tke(k) = max(tke(k) + dq(k), tke_min)
1525 if (abs(dq(k)) < roundoff*tke(k))
exit 1528 do k2=k+1,ke_kappa_prev+1 ; dq(k2) = 0.0 ; dk(k2) = 0.0 ;
enddo 1529 do k=k2,nz+1 ;
if (dq(k) == 0.0)
exit ; dq(k) = 0.0 ; dk(k) = 0.0 ;
enddo 1532 if (.not. abort_newton)
then 1535 dq(k) = max(dq(k) + (cq(k+1)*dq(k+1) + dqmdk(k+1) * dk(k+1)), &
1537 tke(k) = max(tke(k) + dq(k), tke_min)
1538 dk(k) = dk(k) + (ck(k+1)*dk(k+1) + dkdq(k) * dq(k))
1540 if (dk(k) <= kappa_trunc - kappa(k))
then 1543 if ((k < ks_src) .and. (k+1 > ks_kappa)) ks_kappa = k+1
1544 elseif (dk(k) < 2.0*kappa_trunc - kappa(k))
then 1545 dk(k) = 2.0*dk(k) - (2.0*kappa_trunc - kappa(k))
1546 kappa(k) = max(kappa(k) + dk(k), 0.0)
1547 if (k<=ks_kappa) ks_kappa = 2
1549 kappa(k) = kappa(k) + dk(k)
1550 if (k<=ks_kappa) ks_kappa = 2
1553 dq(1) = max(dq(1) + cq(2)*dq(2) + dqmdk(2) * dk(2), tke_min - tke(1))
1554 tke(1) = max(tke(1) + dq(1), tke_min)
1567 i_ld2(k) = (n2(k)*ilambda2 + f2) * i_q + i_l2_bdry(k)
1569 kap_src = dz_int(k) * (k_src(k) - i_ld2(k)*kappa_prev(k)) + &
1570 (idz(k-1)*(kappa_prev(k-1)-kappa_prev(k)) - &
1571 idz(k)*(kappa_prev(k)-kappa_prev(k+1)))
1572 k_err_lin = -idz(k-1)*(dk(k-1)-dk(k)) + idz(k)*(dk(k)-dk(k+1)) + &
1573 dz_int(k)*i_ld2(k)*dk(k) - kap_src - &
1574 (n2(k)*ilambda2 + f2)*i_q**2*kappa_prev(k) * dq(k)
1576 tke_src = dz_int(k) * ((kappa_prev(k) + kappa0)*s2(k) - &
1577 kappa_prev(k)*n2(k) - (tke_prev(k) - q0)*tke_decay(k)) - &
1578 (aq(k) * (tke_prev(k) - tke_prev(k+1)) - &
1579 aq(k-1) * (tke_prev(k-1) - tke_prev(k)))
1580 q_err_lin = (aq(k-1) * (dq(k-1)-dq(k)) - aq(k) * (dq(k)-dq(k+1))) - &
1581 0.5*(tke_prev(k)-tke_prev(k+1))*idz(k) * (dk(k) + dk(k+1)) - &
1582 0.5*(tke_prev(k)-tke_prev(k-1))*idz(k-1)* (dk(k-1) + dk(k)) + &
1583 dz_int(k) * (dk(k) * (s2(k) - n2(k)) - dq(k)*tke_decay(k)) + tke_src
1590 max_err = 0.0 ; max_tke_err = 0.0 ; min_tke_err = 0.0
1591 do k=min(ks_kappa,ks_kappa_prev),max(ke_kappa,ke_kappa_prev)
1592 norm_err = abs(kappa(k) - kappa_prev(k)) / &
1593 (kappa0 + 0.5*(kappa(k) + kappa_prev(k)))
1594 if (max_err < norm_err) max_err = norm_err
1596 tke_err(k) = dq(k) / (tke(k) - 0.5*dq(k))
1597 if (tke_err(k) > max_tke_err) max_tke_err = tke_err(k)
1598 if (tke_err(k) < min_tke_err) min_tke_err = tke_err(k)
1601 if (max(max_err,max_tke_err,-min_tke_err) >= 2.0*newton_err)
then 1602 do_newton = .false. ; abort_newton = .true.
1605 if (max(max_err,max_tke_err,-min_tke_err) < newton_err) do_newton = .true.
1607 within_tolerance = (max_err < tol_err)
1610 if ((tol_err < newton_err) .and. (.not.abort_newton))
then 1613 newton_test = newton_err ;
if (do_newton) newton_test = 2.0*newton_err
1614 was_newton = do_newton
1615 within_tolerance = .true. ; do_newton = .true.
1616 do k=min(ks_kappa,ks_kappa_prev),max(ke_kappa,ke_kappa_prev)
1617 kappa_mean = kappa0 + (kappa(k) - 0.5*dk(k))
1618 if (abs(dk(k)) > newton_test * kappa_mean)
then 1619 if (do_newton) abort_newton = .true.
1620 within_tolerance = .false. ; do_newton = .false. ;
exit 1621 elseif (abs(dk(k)) > tol_err * kappa_mean)
then 1622 within_tolerance = .false. ;
if (.not.do_newton)
exit 1624 if (abs(dq(k)) > newton_test*(tke(k) - 0.5*dq(k)))
then 1625 if (do_newton) abort_newton = .true.
1626 do_newton = .false. ;
if (.not.within_tolerance)
exit 1631 within_tolerance = .true.
1632 do k=min(ks_kappa,ks_kappa_prev),max(ke_kappa,ke_kappa_prev)
1633 if (abs(dk(k)) > tol_err * (kappa0 + (kappa(k) - 0.5*dk(k))))
then 1634 within_tolerance = .false. ;
exit 1640 if (abort_newton)
then 1641 do_newton = .false. ; abort_newton = .false.
1643 newton_err = 0.5*newton_err
1645 do k=2,nz ; k_q(k) = kappa(k) / max(tke(k), tke_min) ;
enddo 1649 if (itt <= max_debug_itt)
then 1651 kprev_it1(k,itt)=kappa_prev(k)
1652 kappa_it1(k,itt)=kappa(k) ; tke_it1(k,itt) = tke(k)
1653 dkappa_it1(k,itt) = kappa(k) - kappa_prev(k)
1654 dkappa_norm_it1(k,itt) = (kappa(k) - kappa_prev(k)) / &
1655 (kappa0 + 0.5*(kappa(k) + kappa_prev(k)))
1656 k_q_it1(k,itt) = kappa(k) / max(tke(k),tke_min)
1657 d_dkappa_it1(k,itt) = 0.0
1658 if (itt > 1)
then ;
if (abs(dkappa_it1(k,itt-1)) > 1e-20) &
1659 d_dkappa_it1(k,itt) = dkappa_it1(k,itt) / dkappa_it1(k,itt-1)
1665 if (within_tolerance)
exit 1670 do it2=itt+1,max_debug_itt ;
do k=1,nz+1
1671 kprev_it1(k,it2) = 0.0 ; kappa_it1(k,it2) = 0.0 ; tke_it1(k,it2) = 0.0
1672 dkappa_it1(k,it2) = 0.0 ; k_q_it1(k,it2) = 0.0 ; d_dkappa_it1(k,it2) = 0.0
1677 do k=1,ks_kappa-1 ; k_q(k) = 0.0 ;
enddo 1678 do k=ks_kappa,ke_kappa ; k_q(k) = kappa(k) / tke(k) ;
enddo 1679 do k=ke_kappa+1,nz+1 ; k_q(k) = 0.0 ;
enddo 1682 if (
present(local_src))
then 1683 local_src(1) = 0.0 ; local_src(nz+1) = 0.0
1685 diffusive_src = idz(k-1)*(kappa(k-1)-kappa(k)) + &
1686 idz(k)*(kappa(k+1)-kappa(k))
1687 chg_by_k0 = kappa0 * ((idz(k-1)+idz(k)) / dz_int(k) + i_ld2(k))
1688 if (diffusive_src <= 0.0)
then 1689 local_src(k) = k_src(k) + chg_by_k0
1691 local_src(k) = (k_src(k) + chg_by_k0) + diffusive_src / dz_int(k)
1695 if (
present(kappa_src))
then 1696 kappa_src(1) = 0.0 ; kappa_src(nz+1) = 0.0
1698 kappa_src(k) = k_src(k)
1706 type(time_type),
intent(in) :: Time
1711 type(
diag_ctrl),
target,
intent(inout) :: diag
1724 logical :: merge_mixedlayer
1726 #include "version_variable.h" 1729 if (
associated(cs))
then 1730 call mom_error(warning,
"kappa_shear_init called with an associated "// &
1731 "control structure.")
1747 "Parameterization of shear-driven turbulence following Jackson, Hallberg and Legg, JPO 2008")
1749 "If true, use the Jackson-Hallberg-Legg (JPO 2008) \n"//&
1750 "shear mixing parameterization.", default=.false.)
1751 call get_param(param_file,
mdl,
"RINO_CRIT", cs%RiNo_crit, &
1752 "The critical Richardson number for shear mixing.", &
1753 units=
"nondim", default=0.25)
1754 call get_param(param_file,
mdl,
"SHEARMIX_RATE", cs%Shearmix_rate, &
1755 "A nondimensional rate scale for shear-driven entrainment.\n"//&
1756 "Jackson et al find values in the range of 0.085-0.089.", &
1757 units=
"nondim", default=0.089)
1758 call get_param(param_file,
mdl,
"MAX_RINO_IT", cs%max_RiNo_it, &
1759 "The maximum number of iterations that may be used to \n"//&
1760 "estimate the Richardson number driven mixing.", &
1761 units=
"nondim", default=50)
1762 call get_param(param_file,
mdl,
"KD", kd_normal, default=1.0e-7, do_not_log=.true.)
1763 call get_param(param_file,
mdl,
"KD_KAPPA_SHEAR_0", cs%kappa_0, &
1764 "The background diffusivity that is used to smooth the \n"//&
1765 "density and shear profiles before solving for the \n"//&
1766 "diffusivities. Defaults to value of KD.", units=
"m2 s-1", default=kd_normal)
1767 call get_param(param_file,
mdl,
"FRI_CURVATURE", cs%FRi_curvature, &
1768 "The nondimensional curvature of the function of the \n"//&
1769 "Richardson number in the kappa source term in the \n"//&
1770 "Jackson et al. scheme.", units=
"nondim", default=-0.97)
1771 call get_param(param_file,
mdl,
"TKE_N_DECAY_CONST", cs%C_N, &
1772 "The coefficient for the decay of TKE due to \n"//&
1773 "stratification (i.e. proportional to N*tke). \n"//&
1774 "The values found by Jackson et al. are 0.24-0.28.", &
1775 units=
"nondim", default=0.24)
1778 call get_param(param_file,
mdl,
"TKE_SHEAR_DECAY_CONST", cs%C_S, &
1779 "The coefficient for the decay of TKE due to shear (i.e. \n"//&
1780 "proportional to |S|*tke). The values found by Jackson \n"//&
1781 "et al. are 0.14-0.12.", units=
"nondim", default=0.14)
1782 call get_param(param_file,
mdl,
"KAPPA_BUOY_SCALE_COEF", cs%lambda, &
1783 "The coefficient for the buoyancy length scale in the \n"//&
1784 "kappa equation. The values found by Jackson et al. are \n"//&
1785 "in the range of 0.81-0.86.", units=
"nondim", default=0.82)
1786 call get_param(param_file,
mdl,
"KAPPA_N_OVER_S_SCALE_COEF2", cs%lambda2_N_S, &
1787 "The square of the ratio of the coefficients of the \n"//&
1788 "buoyancy and shear scales in the diffusivity equation, \n"//&
1789 "Set this to 0 (the default) to eliminate the shear scale. \n"//&
1790 "This is only used if USE_JACKSON_PARAM is true.", &
1791 units=
"nondim", default=0.0)
1792 call get_param(param_file,
mdl,
"KAPPA_SHEAR_TOL_ERR", cs%kappa_tol_err, &
1793 "The fractional error in kappa that is tolerated. \n"//&
1794 "Iteration stops when changes between subsequent \n"//&
1795 "iterations are smaller than this everywhere in a \n"//&
1796 "column. The peak diffusivities usually converge most \n"//&
1797 "rapidly, and have much smaller errors than this.", &
1798 units=
"nondim", default=0.1)
1799 call get_param(param_file,
mdl,
"TKE_BACKGROUND", cs%TKE_bg, &
1800 "A background level of TKE used in the first iteration \n"//&
1801 "of the kappa equation. TKE_BACKGROUND could be 0.", &
1802 units=
"m2 s-2", default=0.0)
1803 call get_param(param_file,
mdl,
"KAPPA_SHEAR_ELIM_MASSLESS", cs%eliminate_massless, &
1804 "If true, massless layers are merged with neighboring \n"//&
1805 "massive layers in this calculation. The default is \n"//&
1806 "true and I can think of no good reason why it should \n"//&
1807 "be false. This is only used if USE_JACKSON_PARAM is true.", &
1809 call get_param(param_file,
mdl,
"MAX_KAPPA_SHEAR_IT", cs%max_KS_it, &
1810 "The maximum number of iterations that may be used to \n"//&
1811 "estimate the time-averaged diffusivity.", units=
"nondim", &
1813 call get_param(param_file,
mdl,
"PRANDTL_TURB", cs%Prandtl_turb, &
1814 "The turbulent Prandtl number applied to shear \n"//&
1815 "instability.", units=
"nondim", default=1.0, do_not_log=.true.)
1816 call get_param(param_file,
mdl,
"DEBUG_KAPPA_SHEAR", cs%debug, &
1817 "If true, write debugging data for the kappa-shear code. \n"//&
1818 "Caution: this option is _very_ verbose and should only \n"//&
1819 "be used in single-column mode!", default=.false.)
1828 call get_param(param_file,
mdl,
"KAPPA_SHEAR_MERGE_ML",merge_mixedlayer, &
1829 "If true, combine the mixed layers together before \n"//&
1830 "solving the kappa-shear equations.", default=.true.)
1831 if (merge_mixedlayer) cs%nkml = gv%nkml
1839 cs%id_Kd_shear = register_diag_field(
'ocean_model',
'Kd_shear',diag%axesTi,time, &
1840 'Shear-driven Diapycnal Diffusivity',
'meter2 second-1')
1841 cs%id_TKE = register_diag_field(
'ocean_model',
'TKE_shear',diag%axesTi,time, &
1842 'Shear-driven Turbulent Kinetic Energy',
'meter2 second-2')
1843 #ifdef ADD_DIAGNOSTICS 1844 cs%id_ILd2 = register_diag_field(
'ocean_model',
'ILd2_shear',diag%axesTi,time, &
1845 'Inverse kappa decay scale at interfaces',
'meter-2')
1846 cs%id_dz_Int = register_diag_field(
'ocean_model',
'dz_Int_shear',diag%axesTi,time, &
1847 'Finite volume thickness of interfaces',
'meter')
1858 default=.false., do_not_log = .true.)
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
Provides the ocean grid type.
subroutine find_kappa_tke(N2, S2, kappa_in, Idz, dz_Int, I_L2_bdry, f2, nz, CS, K_Q, tke, kappa, kappa_src, local_src)
This subroutine calculates new, consistent estimates of TKE and kappa.
logical function, public kappa_shear_init(Time, G, GV, param_file, diag, CS)
subroutine, public calculate_density_derivs(T, S, pressure, drho_dT, drho_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs.
logical function, public is_root_pe()
subroutine calculate_projected_state(kappa, u0, v0, T0, S0, dt, nz, dz, I_dz_int, dbuoy_dT, dbuoy_dS, u, v, T, Sal, N2, S2, ks_int, ke_int)
Provides subroutines for quantities specific to the equation of state.
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
subroutine, public mom_error(level, message, all_print)
logical function, public kappa_shear_is_used(param_file)
subroutine, public calculate_kappa_shear(u_in, v_in, h, tv, p_surf, kappa_io, tke_io, kv_io, dt, G, GV, CS, initialize_all)
Subroutine for calculating diffusivity and TKE.