16 implicit none ;
private
18 #include <MOM_memory.h>
29 logical :: use_ebt_mode = .false.
33 real :: mono_n2_column_fraction = 0.
37 real :: mono_n2_depth = -1.
49 subroutine wave_speed(h, tv, G, GV, US, cg1, CS, full_halos, use_ebt_mode, &
50 mono_N2_column_fraction, mono_N2_depth, modal_structure)
54 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
57 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: cg1
59 logical,
optional,
intent(in) :: full_halos
61 logical,
optional,
intent(in) :: use_ebt_mode
63 real,
optional,
intent(in) :: mono_n2_column_fraction
66 real,
optional,
intent(in) :: mono_n2_depth
69 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
70 optional,
intent(out) :: modal_structure
73 real,
dimension(SZK_(G)+1) :: &
80 real,
dimension(SZK_(G)) :: &
84 real,
dimension(SZK_(G),SZI_(G)) :: &
89 real,
dimension(SZK_(G)) :: &
95 real :: det, ddet, detkm1, detkm2, ddetkm1, ddetkm2
101 real,
dimension(SZI_(G)) :: &
111 real,
parameter :: tol1 = 0.0001, tol2 = 0.001
112 real,
pointer,
dimension(:,:,:) :: t => null(), s => null()
117 real :: rescale, i_rescale
118 integer :: kf(szi_(g))
119 integer,
parameter :: max_itt = 10
120 real :: lam_it(max_itt), det_it(max_itt), ddet_it(max_itt)
124 integer :: i, j, k, k2, itt, is, ie, js, je, nz
128 logical :: l_use_ebt_mode, calc_modal_structure
129 real :: l_mono_n2_column_fraction, l_mono_n2_depth
130 real :: mode_struct(szk_(g)), ms_min, ms_max, ms_sq
132 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
134 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_wave_speed: "// &
135 "Module must be initialized before it is used.")
136 if (
present(full_halos))
then ;
if (full_halos)
then
137 is = g%isd ; ie = g%ied ; js = g%jsd ; je = g%jed
140 l2_to_z2 = us%L_to_Z**2
142 l_use_ebt_mode = cs%use_ebt_mode
143 if (
present(use_ebt_mode)) l_use_ebt_mode = use_ebt_mode
144 l_mono_n2_column_fraction = cs%mono_N2_column_fraction
145 if (
present(mono_n2_column_fraction)) l_mono_n2_column_fraction = mono_n2_column_fraction
146 l_mono_n2_depth = cs%mono_N2_depth
147 if (
present(mono_n2_depth)) l_mono_n2_depth = mono_n2_depth
148 calc_modal_structure = l_use_ebt_mode
149 if (
present(modal_structure)) calc_modal_structure = .true.
150 if (calc_modal_structure)
then
151 do k=1,nz;
do j=js,je;
do i=is,ie
152 modal_structure(i,j,k) = 0.0
153 enddo ;
enddo ;
enddo
156 s => tv%S ; t => tv%T
157 g_rho0 = gv%g_Earth / gv%Rho0
158 z_to_pa = gv%Z_to_H * gv%H_to_Pa
159 use_eos =
associated(tv%eqn_of_state)
161 rescale = 1024.0**4 ; i_rescale = 1.0/rescale
164 c2_scale = us%m_s_to_L_T**2
166 min_h_frac = tol1 / real(nz)
182 do i=is,ie ; htot(i) = 0.0 ;
enddo
183 do k=1,nz ;
do i=is,ie ; htot(i) = htot(i) + h(i,j,k)*gv%H_to_Z ;
enddo ;
enddo
186 hmin(i) = htot(i)*min_h_frac ; kf(i) = 1 ; h_here(i) = 0.0
187 hxt_here(i) = 0.0 ; hxs_here(i) = 0.0 ; hxr_here(i) = 0.0
190 do k=1,nz ;
do i=is,ie
191 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
192 hf(kf(i),i) = h_here(i)
193 tf(kf(i),i) = hxt_here(i) / h_here(i)
194 sf(kf(i),i) = hxs_here(i) / h_here(i)
198 h_here(i) = h(i,j,k)*gv%H_to_Z
199 hxt_here(i) = (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
200 hxs_here(i) = (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
202 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
203 hxt_here(i) = hxt_here(i) + (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
204 hxs_here(i) = hxs_here(i) + (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
207 do i=is,ie ;
if (h_here(i) > 0.0)
then
208 hf(kf(i),i) = h_here(i)
209 tf(kf(i),i) = hxt_here(i) / h_here(i)
210 sf(kf(i),i) = hxs_here(i) / h_here(i)
213 do k=1,nz ;
do i=is,ie
214 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
215 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
219 h_here(i) = h(i,j,k)*gv%H_to_Z
220 hxr_here(i) = (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
222 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
223 hxr_here(i) = hxr_here(i) + (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
226 do i=is,ie ;
if (h_here(i) > 0.0)
then
227 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
233 do i=is,ie ;
if (g%mask2dT(i,j) > 0.5)
then
237 pres(k) = pres(k-1) + z_to_pa*hf(k-1,i)
238 t_int(k) = 0.5*(tf(k,i)+tf(k-1,i))
239 s_int(k) = 0.5*(sf(k,i)+sf(k-1,i))
242 kf(i)-1, tv%eqn_of_state, scale=us%kg_m3_to_R)
248 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * &
249 max(0.0,drho_dt(k)*(tf(k,i)-tf(k-1,i)) + &
250 drho_ds(k)*(sf(k,i)-sf(k-1,i)))
255 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * &
256 max(0.0,rf(k,i)-rf(k-1,i))
260 if (calc_modal_structure)
then
266 if (drxh_sum <= 0.0)
then
273 hc(1) = hf(1,i) ; tc(1) = tf(1,i) ; sc(1) = sf(1,i)
275 if ((drho_dt(k)*(tf(k,i)-tc(kc)) + drho_ds(k)*(sf(k,i)-sc(kc))) * &
276 (hc(kc) + hf(k,i)) < 2.0 * tol2*drxh_sum)
then
278 i_hnew = 1.0 / (hc(kc) + hf(k,i))
279 tc(kc) = (hc(kc)*tc(kc) + hf(k,i)*tf(k,i)) * i_hnew
280 sc(kc) = (hc(kc)*sc(kc) + hf(k,i)*sf(k,i)) * i_hnew
281 hc(kc) = (hc(kc) + hf(k,i))
286 if ((drho_dt(k2)*(tc(k2)-tc(k2-1)) + drho_ds(k2)*(sc(k2)-sc(k2-1))) * &
287 (hc(k2) + hc(k2-1)) < tol2*drxh_sum)
then
289 i_hnew = 1.0 / (hc(kc) + hc(kc-1))
290 tc(kc-1) = (hc(kc)*tc(kc) + hc(kc-1)*tc(kc-1)) * i_hnew
291 sc(kc-1) = (hc(kc)*sc(kc) + hc(kc-1)*sc(kc-1)) * i_hnew
292 hc(kc-1) = (hc(kc) + hc(kc-1))
299 drho_ds(kc) = drho_ds(k) ; drho_dt(kc) = drho_dt(k)
300 tc(kc) = tf(k,i) ; sc(kc) = sf(k,i) ; hc(kc) = hf(k,i)
305 gprime(k) = g_rho0 * (drho_dt(k)*(tc(k)-tc(k-1)) + &
306 drho_ds(k)*(sc(k)-sc(k-1)))
311 hc(1) = hf(1,i) ; rc(1) = rf(1,i)
313 if ((rf(k,i) - rc(kc)) * (hc(kc) + hf(k,i)) < 2.0*tol2*drxh_sum)
then
315 rc(kc) = (hc(kc)*rc(kc) + hf(k,i)*rf(k,i)) / (hc(kc) + hf(k,i))
316 hc(kc) = (hc(kc) + hf(k,i))
321 if ((rc(k2)-rc(k2-1)) * (hc(k2)+hc(k2-1)) < tol2*drxh_sum)
then
323 rc(kc-1) = (hc(kc)*rc(kc) + hc(kc-1)*rc(kc-1)) / (hc(kc) + hc(kc-1))
324 hc(kc-1) = (hc(kc) + hc(kc-1))
331 rc(kc) = rf(k,i) ; hc(kc) = hf(k,i)
336 gprime(k) = g_rho0 * (rc(k)-rc(k-1))
345 if (l_use_ebt_mode)
then
348 n2min = l2_to_z2*gprime(2)/hc(1)
350 hw = 0.5*(hc(k-1)+hc(k))
352 if (l_mono_n2_column_fraction>0. .or. l_mono_n2_depth>=0.)
then
353 if ( ((g%bathyT(i,j)-sum_hc < l_mono_n2_column_fraction*g%bathyT(i,j)) .or. &
354 ((l_mono_n2_depth >= 0.) .and. (sum_hc > l_mono_n2_depth))) .and. &
355 (l2_to_z2*gp > n2min*hw) )
then
358 gp = us%Z_to_L**2 * (n2min*hw)
360 n2min = l2_to_z2 * gp/hw
363 igu(k) = 1.0/(gp*hc(k))
364 igl(k-1) = 1.0/(gp*hc(k-1))
365 speed2_tot = speed2_tot + gprime(k)*(hc(k-1)+hc(k))*0.707
366 sum_hc = sum_hc + hc(k)
372 igl(k) = 1.0/(gprime(k)*hc(k)) ; igu(k) = 1.0/(gprime(k)*hc(k-1))
373 speed2_tot = speed2_tot + gprime(k)*(hc(k-1)+hc(k))
377 if (calc_modal_structure)
then
378 mode_struct(1:kc) = 1.
382 if (calc_modal_structure)
then
383 lam0 = 0.5 / speed2_tot ; lam = lam0
385 lam0 = 1.0 / speed2_tot ; lam = lam0
390 if (l_use_ebt_mode)
then
399 detkm1 = 1.0 ; ddetkm1 = 0.0
400 det = (igl(1)-lam) ; ddet = -1.0
403 detkm2 = c2_scale*detkm1 ; ddetkm2 = c2_scale*ddetkm1
404 detkm1 = c2_scale*det ; ddetkm1 = c2_scale*ddet
405 det = (igu(2)+igl(2)-lam)*detkm1 - (igu(2)*igl(1))*detkm2
406 ddet = (igu(2)+igl(2)-lam)*ddetkm1 - (igu(2)*igl(1))*ddetkm2 - detkm1
418 detkm1 = 1.0 ; ddetkm1 = 0.0
419 det = (igu(2) + igl(2) - lam) ; ddet = -1.0
427 detkm2 = c2_scale*detkm1 ; ddetkm2 = c2_scale*ddetkm1
428 detkm1 = c2_scale*det ; ddetkm1 = c2_scale*ddet
430 det = (igu(k)+igl(k)-lam)*detkm1 - (igu(k)*igl(k-1))*detkm2
431 ddet = (igu(k)+igl(k)-lam)*ddetkm1 - (igu(k)*igl(k-1))*ddetkm2 - detkm1
434 if (abs(det) > rescale)
then
435 det = i_rescale*det ; detkm1 = i_rescale*detkm1
436 ddet = i_rescale*ddet ; ddetkm1 = i_rescale*ddetkm1
437 elseif (abs(det) < i_rescale)
then
438 det = rescale*det ; detkm1 = rescale*detkm1
439 ddet = rescale*ddet ; ddetkm1 = rescale*ddetkm1
443 det_it(itt) = det ; ddet_it(itt) = ddet
445 if ((ddet >= 0.0) .or. (-det > -0.5*lam*ddet))
then
456 if (calc_modal_structure)
then
458 igd(k) = igu(k) + igl(k)
460 call tdma6(kc, -igu, igd, -igl, lam, mode_struct)
461 ms_min = mode_struct(1)
462 ms_max = mode_struct(1)
463 ms_sq = mode_struct(1)**2
465 ms_min = min(ms_min, mode_struct(k))
466 ms_max = max(ms_max, mode_struct(k))
467 ms_sq = ms_sq + mode_struct(k)**2
469 if (ms_min<0. .and. ms_max>0.)
then
470 lam = 0.5 * ( lam - dlam )
472 mode_struct(1:kc) = abs(mode_struct(1:kc)) / sqrt( ms_sq )
474 mode_struct(1:kc) = mode_struct(1:kc) / sqrt( ms_sq )
478 if (abs(dlam) < tol2*lam)
exit
482 if (lam > 0.0) cg1(i,j) = 1.0 / sqrt(lam)
484 if (
present(modal_structure))
then
485 if (mode_struct(1)/=0.)
then
486 mode_struct(1:kc) = mode_struct(1:kc) / mode_struct(1)
493 hc_h(k) = gv%Z_to_H * hc(k)
496 nz, h(i,j,:), modal_structure(i,j,:), &
497 1.0e-30*gv%m_to_H, 1.0e-10*gv%m_to_H)
501 if (
present(modal_structure)) modal_structure(i,j,:) = 0.
506 if (
present(modal_structure)) modal_structure(i,j,:) = 0.
514 subroutine tdma6(n, a, b, c, lam, y)
515 integer,
intent(in) :: n
516 real,
dimension(n),
intent(in) :: a
517 real,
dimension(n),
intent(in) :: b
518 real,
dimension(n),
intent(in) :: c
519 real,
intent(in) :: lam
520 real,
dimension(n),
intent(inout) :: y
523 real :: beta(n), lambda
528 beta(1) = b(1) - lambda
529 if (beta(1)==0.)
then
531 lambda = (1. + 1.e-5) * lambda
532 beta(1) = b(1) - lambda
534 i_beta(1) = 1. / beta(1)
537 beta(k) = ( b(k) - lambda ) - a(k) * c(k-1) * i_beta(k-1)
539 if (beta(k)==0.)
then
541 lambda = (1. + 1.e-5) * lambda
542 i_beta(1) = 1. / ( b(1) - lambda )
544 i_beta(l) = 1. / ( ( b(l) - lambda ) - a(l) * c(l-1) * i_beta(l-1) )
545 yy(l) = y(l) - a(l) * yy(l-1) * i_beta(l-1)
548 i_beta(k) = 1. / beta(k)
550 yy(k) = y(k) - a(k) * yy(k-1) * i_beta(k-1)
553 y(n) = yy(n) * i_beta(n)
555 y(k) = ( yy(k) - c(k) * y(k+1) ) * i_beta(k)
560 subroutine wave_speeds(h, tv, G, GV, US, nmodes, cn, CS, full_halos)
564 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
566 integer,
intent(in) :: nmodes
567 real,
dimension(G%isd:G%ied,G%jsd:G%jed,nmodes),
intent(out) :: cn
569 logical,
optional,
intent(in) :: full_halos
572 real,
dimension(SZK_(G)+1) :: &
579 real,
dimension(SZK_(G)) :: &
582 real,
dimension(SZK_(G)-1) :: &
583 a_diag, b_diag, c_diag
586 real,
dimension(SZK_(G),SZI_(G)) :: &
591 real,
dimension(SZK_(G)) :: &
606 real :: ddet_l,ddet_r
607 real :: det_sub,ddet_sub
610 real,
dimension(nmodes) :: &
613 integer :: nrootsfound
616 real,
dimension(SZI_(G)) :: &
624 real,
parameter :: reduct_factor = 0.5
628 real,
parameter :: tol1 = 0.0001, tol2 = 0.001
629 real,
pointer,
dimension(:,:,:) :: t => null(), s => null()
631 integer :: kf(szi_(g))
632 integer,
parameter :: max_itt = 10
634 real,
dimension(SZK_(G)+1) :: z_int
637 integer,
parameter :: sub_it_max = 4
640 logical :: sub_rootfound
642 integer :: sub, sub_it
643 integer :: i, j, k, k2, itt, is, ie, js, je, nz, row, iint, m, ig, jg
645 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
647 if (
present(cs))
then
648 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_wave_speed: "// &
649 "Module must be initialized before it is used.")
652 if (
present(full_halos))
then ;
if (full_halos)
then
653 is = g%isd ; ie = g%ied ; js = g%jsd ; je = g%jed
656 s => tv%S ; t => tv%T
657 g_rho0 = gv%g_Earth / gv%Rho0
658 use_eos =
associated(tv%eqn_of_state)
659 z_to_pa = gv%Z_to_H * gv%H_to_Pa
660 c1_thresh = 0.01*us%m_s_to_L_T
662 min_h_frac = tol1 / real(nz)
669 do i=is,ie ; htot(i) = 0.0 ;
enddo
670 do k=1,nz ;
do i=is,ie ; htot(i) = htot(i) + h(i,j,k)*gv%H_to_Z ;
enddo ;
enddo
673 hmin(i) = htot(i)*min_h_frac ; kf(i) = 1 ; h_here(i) = 0.0
674 hxt_here(i) = 0.0 ; hxs_here(i) = 0.0 ; hxr_here(i) = 0.0
677 do k=1,nz ;
do i=is,ie
678 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
679 hf(kf(i),i) = h_here(i)
680 tf(kf(i),i) = hxt_here(i) / h_here(i)
681 sf(kf(i),i) = hxs_here(i) / h_here(i)
685 h_here(i) = h(i,j,k)*gv%H_to_Z
686 hxt_here(i) = (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
687 hxs_here(i) = (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
689 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
690 hxt_here(i) = hxt_here(i) + (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
691 hxs_here(i) = hxs_here(i) + (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
694 do i=is,ie ;
if (h_here(i) > 0.0)
then
695 hf(kf(i),i) = h_here(i)
696 tf(kf(i),i) = hxt_here(i) / h_here(i)
697 sf(kf(i),i) = hxs_here(i) / h_here(i)
700 do k=1,nz ;
do i=is,ie
701 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
702 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
706 h_here(i) = h(i,j,k)*gv%H_to_Z
707 hxr_here(i) = (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
709 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
710 hxr_here(i) = hxr_here(i) + (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
713 do i=is,ie ;
if (h_here(i) > 0.0)
then
714 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
721 if (g%mask2dT(i,j) > 0.5)
then
725 pres(k) = pres(k-1) + z_to_pa*hf(k-1,i)
726 t_int(k) = 0.5*(tf(k,i)+tf(k-1,i))
727 s_int(k) = 0.5*(sf(k,i)+sf(k-1,i))
730 kf(i)-1, tv%eqn_of_state, scale=us%kg_m3_to_R)
736 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * &
737 max(0.0,drho_dt(k)*(tf(k,i)-tf(k-1,i)) + &
738 drho_ds(k)*(sf(k,i)-sf(k-1,i)))
743 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * &
744 max(0.0,rf(k,i)-rf(k-1,i))
749 if (drxh_sum <= 0.0)
then
756 hc(1) = hf(1,i) ; tc(1) = tf(1,i) ; sc(1) = sf(1,i)
758 if ((drho_dt(k)*(tf(k,i)-tc(kc)) + drho_ds(k)*(sf(k,i)-sc(kc))) * &
759 (hc(kc) + hf(k,i)) < 2.0 * tol2*drxh_sum)
then
761 i_hnew = 1.0 / (hc(kc) + hf(k,i))
762 tc(kc) = (hc(kc)*tc(kc) + hf(k,i)*tf(k,i)) * i_hnew
763 sc(kc) = (hc(kc)*sc(kc) + hf(k,i)*sf(k,i)) * i_hnew
764 hc(kc) = (hc(kc) + hf(k,i))
769 if ((drho_dt(k2)*(tc(k2)-tc(k2-1)) + drho_ds(k2)*(sc(k2)-sc(k2-1))) * &
770 (hc(k2) + hc(k2-1)) < tol2*drxh_sum)
then
772 i_hnew = 1.0 / (hc(kc) + hc(kc-1))
773 tc(kc-1) = (hc(kc)*tc(kc) + hc(kc-1)*tc(kc-1)) * i_hnew
774 sc(kc-1) = (hc(kc)*sc(kc) + hc(kc-1)*sc(kc-1)) * i_hnew
775 hc(kc-1) = (hc(kc) + hc(kc-1))
782 drho_ds(kc) = drho_ds(k) ; drho_dt(kc) = drho_dt(k)
783 tc(kc) = tf(k,i) ; sc(kc) = sf(k,i) ; hc(kc) = hf(k,i)
788 gprime(k) = g_rho0 * (drho_dt(k)*(tc(k)-tc(k-1)) + &
789 drho_ds(k)*(sc(k)-sc(k-1)))
794 hc(1) = hf(1,i) ; rc(1) = rf(1,i)
796 if ((rf(k,i) - rc(kc)) * (hc(kc) + hf(k,i)) < 2.0*tol2*drxh_sum)
then
798 rc(kc) = (hc(kc)*rc(kc) + hf(k,i)*rf(k,i)) / (hc(kc) + hf(k,i))
799 hc(kc) = (hc(kc) + hf(k,i))
804 if ((rc(k2)-rc(k2-1)) * (hc(k2)+hc(k2-1)) < tol2*drxh_sum)
then
806 rc(kc-1) = (hc(kc)*rc(kc) + hc(kc-1)*rc(kc-1)) / (hc(kc) + hc(kc-1))
807 hc(kc-1) = (hc(kc) + hc(kc-1))
814 rc(kc) = rf(k,i) ; hc(kc) = hf(k,i)
819 gprime(k) = g_rho0 * (rc(k)-rc(k-1))
824 ig = i + g%idg_offset ; jg = j + g%jdg_offset
835 igl(k) = 1.0/(gprime(k)*hc(k)) ; igu(k) = 1.0/(gprime(k)*hc(k-1))
836 z_int(k) = z_int(k-1) + hc(k-1)
838 speed2_tot = speed2_tot + gprime(k)*(hc(k-1)+hc(k))
843 z_int(kc+1) = z_int(kc)+hc(kc)
845 if (abs(z_int(kc+1)-htot(i)) > 1.e-12*htot(i))
then
846 call mom_error(fatal,
"wave_structure: mismatch in total depths")
853 a_diag(row) = -igu(k)
854 b_diag(row) = igu(k)+igl(k)
855 c_diag(row) = -igl(k)
860 b_diag(row) = igu(k)+igl(k)
861 c_diag(row) = -igl(k)
864 a_diag(row) = -igu(k)
865 b_diag(row) = igu(k)+igl(k)
871 lam_1 = 1.0 / speed2_tot
876 call tridiag_det(a_diag(1:nrows),b_diag(1:nrows),c_diag(1:nrows), &
877 nrows,lam_1,det,ddet, row_scale=us%m_s_to_L_T**2)
880 if ((ddet >= 0.0) .or. (-det > -0.5*lam_1*ddet))
then
888 if (abs(dlam) < tol2*lam_1)
then
890 if (lam_1 > 0.0) cn(i,j,1) = 1.0 / sqrt(lam_1)
898 if (nmodes>1 .and. kc>=nmodes+1 .and. cn(i,j,1)>c1_thresh)
then
901 lammin = lam_1*(1.0 + tol2)
903 speed2_min = (reduct_factor*cn(i,j,1)/real(nmodes))**2
904 lammax = 1.0 / speed2_min
908 numint = nint((lammax - lammin)/laminc)
914 call tridiag_det(a_diag(1:nrows),b_diag(1:nrows),c_diag(1:nrows), &
915 nrows,lammin,det_l,ddet_l, row_scale=us%m_s_to_L_T**2)
918 xr = lammin + laminc * iint
920 call tridiag_det(a_diag(1:nrows),b_diag(1:nrows),c_diag(1:nrows), &
921 nrows,xr,det_r,ddet_r, row_scale=us%m_s_to_L_T**2)
922 if (det_l*det_r < 0.0)
then
923 if (det_l*ddet_l < 0.0)
then
924 nrootsfound = nrootsfound + 1
925 xbl(nrootsfound) = xl
926 xbr(nrootsfound) = xr
935 sub_rootfound = .false.
936 do sub_it=1,sub_it_max
940 xl_sub = xl + laminc/(nsub)*sub
941 call tridiag_det(a_diag(1:nrows),b_diag(1:nrows),c_diag(1:nrows), &
942 nrows,xl_sub,det_sub,ddet_sub, row_scale=us%m_s_to_L_T**2)
943 if (det_sub*det_r < 0.0)
then
944 if (det_sub*ddet_sub < 0.0)
then
945 sub_rootfound = .true.
946 nrootsfound = nrootsfound + 1
947 xbl(nrootsfound) = xl_sub
948 xbr(nrootsfound) = xr
953 if (sub_rootfound)
exit
956 if (sub_it == sub_it_max)
then
957 call mom_error(warning,
"wave_speed: root not found "// &
958 " after sub_it_max subdivisions of original"// &
965 if (nrootsfound >= nmodes-1)
then
968 elseif (iint == numint)
then
971 cn(i,j,nrootsfound+2:nmodes) = 0.0
984 call tridiag_det(a_diag(1:nrows),b_diag(1:nrows),c_diag(1:nrows), &
985 nrows,lam_n,det,ddet, row_scale=us%m_s_to_L_T**2)
989 if (abs(dlam) < tol2*lam_1)
then
991 if (lam_n > 0.0) cn(i,j,m+1) = 1.0 / sqrt(lam_n)
997 cn(i,j,2:nmodes) = 0.0
1015 subroutine tridiag_det(a, b, c, nrows, lam, det_out, ddet_out, row_scale)
1016 real,
dimension(:),
intent(in) :: a
1017 real,
dimension(:),
intent(in) :: b
1018 real,
dimension(:),
intent(in) :: c
1019 integer,
intent(in) :: nrows
1020 real,
intent(in) :: lam
1021 real,
intent(out):: det_out
1022 real,
intent(out):: ddet_out
1023 real,
optional,
intent(in) :: row_scale
1026 real,
dimension(nrows) :: det
1027 real,
dimension(nrows) :: ddet
1028 real,
parameter:: rescale = 1024.0**4
1033 if (
size(b) /= nrows)
call mom_error(warning,
"Diagonal b must be same length as nrows.")
1034 if (
size(a) /= nrows)
call mom_error(warning,
"Diagonal a must be same length as nrows.")
1035 if (
size(c) /= nrows)
call mom_error(warning,
"Diagonal c must be same length as nrows.")
1037 i_rescale = 1.0/rescale
1038 rscl = 1.0 ;
if (
present(row_scale)) rscl = row_scale
1040 det(1) = 1.0 ; ddet(1) = 0.0
1041 det(2) = b(2)-lam ; ddet(2) = -1.0
1043 det(n) = rscl*(b(n)-lam)*det(n-1) - rscl*(a(n)*c(n-1))*det(n-2)
1044 ddet(n) = rscl*(b(n)-lam)*ddet(n-1) - rscl*(a(n)*c(n-1))*ddet(n-2) - det(n-1)
1046 if (abs(det(n)) > rescale)
then
1047 det(n) = i_rescale*det(n) ; det(n-1) = i_rescale*det(n-1)
1048 ddet(n) = i_rescale*ddet(n) ; ddet(n-1) = i_rescale*ddet(n-1)
1049 elseif (abs(det(n)) < i_rescale)
then
1050 det(n) = rescale*det(n) ; det(n-1) = rescale*det(n-1)
1051 ddet(n) = rescale*ddet(n) ; ddet(n-1) = rescale*ddet(n-1)
1054 det_out = det(nrows)
1055 ddet_out = ddet(nrows) / rscl
1060 subroutine wave_speed_init(CS, use_ebt_mode, mono_N2_column_fraction, mono_N2_depth)
1062 logical,
optional,
intent(in) :: use_ebt_mode
1064 real,
optional,
intent(in) :: mono_n2_column_fraction
1067 real,
optional,
intent(in) :: mono_n2_depth
1071 #include "version_variable.h"
1072 character(len=40) :: mdl =
"MOM_wave_speed"
1074 if (
associated(cs))
then
1075 call mom_error(warning,
"wave_speed_init called with an "// &
1076 "associated control structure.")
1078 else ;
allocate(cs) ;
endif
1083 call wave_speed_set_param(cs, use_ebt_mode=use_ebt_mode, mono_n2_column_fraction=mono_n2_column_fraction)
1092 logical,
optional,
intent(in) :: use_ebt_mode
1094 real,
optional,
intent(in) :: mono_n2_column_fraction
1097 real,
optional,
intent(in) :: mono_n2_depth
1101 if (.not.
associated(cs))
call mom_error(fatal, &
1102 "wave_speed_set_param called with an associated control structure.")
1104 if (
present(use_ebt_mode)) cs%use_ebt_mode = use_ebt_mode
1105 if (
present(mono_n2_column_fraction)) cs%mono_N2_column_fraction = mono_n2_column_fraction
1106 if (
present(mono_n2_depth)) cs%mono_N2_depth = mono_n2_depth