16 implicit none ;
private
18 #include <MOM_memory.h>
20 public wave_speed, wave_speeds, wave_speed_init, wave_speed_set_param
29 logical :: use_ebt_mode = .false.
33 logical :: better_cg1_est = .false.
35 real :: mono_n2_column_fraction = 0.
39 real :: mono_n2_depth = -1.
43 real :: min_speed2 = 0.
44 real :: wave_speed_tol = 0.001
48 logical :: remap_answers_2018 = .true.
57 subroutine wave_speed(h, tv, G, GV, US, cg1, CS, full_halos, use_ebt_mode, mono_N2_column_fraction, &
58 mono_N2_depth, modal_structure, better_speed_est, min_speed, wave_speed_tol)
62 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
65 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: cg1
67 logical,
optional,
intent(in) :: full_halos
69 logical,
optional,
intent(in) :: use_ebt_mode
71 real,
optional,
intent(in) :: mono_n2_column_fraction
74 real,
optional,
intent(in) :: mono_n2_depth
77 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
78 optional,
intent(out) :: modal_structure
79 logical,
optional,
intent(in) :: better_speed_est
81 real,
optional,
intent(in) :: min_speed
83 real,
optional,
intent(in) :: wave_speed_tol
87 real,
dimension(SZK_(G)+1) :: &
96 real,
dimension(SZK_(G)) :: &
99 real,
dimension(SZK_(G),SZI_(G)) :: &
104 real,
dimension(SZK_(G)) :: &
111 real :: det, ddet, detkm1, detkm2, ddetkm1, ddetkm2
117 real,
dimension(SZI_(G)) :: &
128 real,
pointer,
dimension(:,:,:) :: t => null(), s => null()
138 real :: rescale, i_rescale
139 integer :: kf(szi_(g))
140 integer,
parameter :: max_itt = 10
141 real :: lam_it(max_itt), det_it(max_itt), ddet_it(max_itt)
143 logical :: better_est
146 integer :: i, j, k, k2, itt, is, ie, js, je, nz
150 logical :: l_use_ebt_mode, calc_modal_structure
151 real :: l_mono_n2_column_fraction, l_mono_n2_depth
152 real :: mode_struct(szk_(g)), ms_min, ms_max, ms_sq
154 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
156 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_wave_speed: "// &
157 "Module must be initialized before it is used.")
158 if (
present(full_halos))
then ;
if (full_halos)
then
159 is = g%isd ; ie = g%ied ; js = g%jsd ; je = g%jed
162 l2_to_z2 = us%L_to_Z**2
164 l_use_ebt_mode = cs%use_ebt_mode
165 if (
present(use_ebt_mode)) l_use_ebt_mode = use_ebt_mode
166 l_mono_n2_column_fraction = cs%mono_N2_column_fraction
167 if (
present(mono_n2_column_fraction)) l_mono_n2_column_fraction = mono_n2_column_fraction
168 l_mono_n2_depth = cs%mono_N2_depth
169 if (
present(mono_n2_depth)) l_mono_n2_depth = mono_n2_depth
170 calc_modal_structure = l_use_ebt_mode
171 if (
present(modal_structure)) calc_modal_structure = .true.
172 if (calc_modal_structure)
then
173 do k=1,nz;
do j=js,je;
do i=is,ie
174 modal_structure(i,j,k) = 0.0
175 enddo ;
enddo ;
enddo
178 s => tv%S ; t => tv%T
179 g_rho0 = gv%g_Earth / gv%Rho0
181 z_to_pres = gv%Z_to_H * (gv%H_to_RZ * gv%g_Earth)
182 use_eos =
associated(tv%eqn_of_state)
184 better_est = cs%better_cg1_est ;
if (
present(better_speed_est)) better_est = better_speed_est
187 tol_solve = cs%wave_speed_tol ;
if (
present(wave_speed_tol)) tol_solve = wave_speed_tol
188 tol_hfrac = 0.1*tol_solve ; tol_merge = tol_solve / real(nz)
190 tol_solve = 0.001 ; tol_hfrac = 0.0001 ; tol_merge = 0.001
200 cg1_min2 = cs%min_speed2 ;
if (
present(min_speed)) cg1_min2 = min_speed**2
201 rescale = 1024.0**4 ; i_rescale = 1.0/rescale
202 c2_scale = us%m_s_to_L_T**2 / 4096.0**2
204 min_h_frac = tol_hfrac / real(nz)
221 do i=is,ie ; htot(i) = 0.0 ;
enddo
222 do k=1,nz ;
do i=is,ie ; htot(i) = htot(i) + h(i,j,k)*gv%H_to_Z ;
enddo ;
enddo
225 hmin(i) = htot(i)*min_h_frac ; kf(i) = 1 ; h_here(i) = 0.0
226 hxt_here(i) = 0.0 ; hxs_here(i) = 0.0 ; hxr_here(i) = 0.0
229 do k=1,nz ;
do i=is,ie
230 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
231 hf(kf(i),i) = h_here(i)
232 tf(kf(i),i) = hxt_here(i) / h_here(i)
233 sf(kf(i),i) = hxs_here(i) / h_here(i)
237 h_here(i) = h(i,j,k)*gv%H_to_Z
238 hxt_here(i) = (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
239 hxs_here(i) = (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
241 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
242 hxt_here(i) = hxt_here(i) + (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
243 hxs_here(i) = hxs_here(i) + (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
246 do i=is,ie ;
if (h_here(i) > 0.0)
then
247 hf(kf(i),i) = h_here(i)
248 tf(kf(i),i) = hxt_here(i) / h_here(i)
249 sf(kf(i),i) = hxs_here(i) / h_here(i)
252 do k=1,nz ;
do i=is,ie
253 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
254 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
258 h_here(i) = h(i,j,k)*gv%H_to_Z
259 hxr_here(i) = (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
261 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
262 hxr_here(i) = hxr_here(i) + (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
265 do i=is,ie ;
if (h_here(i) > 0.0)
then
266 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
271 do i=is,ie ;
if (g%mask2dT(i,j) > 0.5)
then
273 pres(1) = 0.0 ; h_top(1) = 0.0
275 pres(k) = pres(k-1) + z_to_pres*hf(k-1,i)
276 t_int(k) = 0.5*(tf(k,i)+tf(k-1,i))
277 s_int(k) = 0.5*(sf(k,i)+sf(k-1,i))
278 h_top(k) = h_top(k-1) + hf(k-1,i)
281 tv%eqn_of_state, (/2,kf(i)/) )
290 if (h_top(kf(i)) > 0.0)
then
291 i_htot = 1.0 / (h_top(kf(i)) + hf(kf(i),i))
294 h_bot(k) = h_bot(k+1) + hf(k,i)
295 drxh_sum = drxh_sum + ((h_top(k) * h_bot(k)) * i_htot) * &
296 max(0.0, drho_dt(k)*(tf(k,i)-tf(k-1,i)) + drho_ds(k)*(sf(k,i)-sf(k-1,i)))
304 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * &
305 max(0.0, drho_dt(k)*(tf(k,i)-tf(k-1,i)) + drho_ds(k)*(sf(k,i)-sf(k-1,i)))
312 do k=2,kf(i) ; h_top(k) = h_top(k-1) + hf(k-1,i) ;
enddo
313 if (h_top(kf(i)) > 0.0)
then
314 i_htot = 1.0 / (h_top(kf(i)) + hf(kf(i),i))
317 h_bot(k) = h_bot(k+1) + hf(k,i)
318 drxh_sum = drxh_sum + ((h_top(k) * h_bot(k)) * i_htot) * max(0.0,rf(k,i)-rf(k-1,i))
323 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * max(0.0,rf(k,i)-rf(k-1,i))
330 if (g_rho0 * drxh_sum <= cg1_min2)
then
332 if (
present(modal_structure)) modal_structure(i,j,:) = 0.
339 hc(1) = hf(1,i) ; tc(1) = tf(1,i) ; sc(1) = sf(1,i)
342 merge = ((drho_dt(k)*(tf(k,i)-tc(kc)) + drho_ds(k)*(sf(k,i)-sc(kc))) * &
343 ((hc(kc) * hf(k,i))*i_htot) < 2.0 * tol_merge*drxh_sum)
345 merge = ((drho_dt(k)*(tf(k,i)-tc(kc)) + drho_ds(k)*(sf(k,i)-sc(kc))) * &
346 (hc(kc) + hf(k,i)) < 2.0 * tol_merge*drxh_sum)
350 i_hnew = 1.0 / (hc(kc) + hf(k,i))
351 tc(kc) = (hc(kc)*tc(kc) + hf(k,i)*tf(k,i)) * i_hnew
352 sc(kc) = (hc(kc)*sc(kc) + hf(k,i)*sf(k,i)) * i_hnew
353 hc(kc) = (hc(kc) + hf(k,i))
359 merge = ((drho_dt(k2)*(tc(k2)-tc(k2-1)) + drho_ds(k2)*(sc(k2)-sc(k2-1))) * &
360 ((hc(k2) * hc(k2-1))*i_htot) < tol_merge*drxh_sum)
362 merge = ((drho_dt(k2)*(tc(k2)-tc(k2-1)) + drho_ds(k2)*(sc(k2)-sc(k2-1))) * &
363 (hc(k2) + hc(k2-1)) < tol_merge*drxh_sum)
367 i_hnew = 1.0 / (hc(kc) + hc(kc-1))
368 tc(kc-1) = (hc(kc)*tc(kc) + hc(kc-1)*tc(kc-1)) * i_hnew
369 sc(kc-1) = (hc(kc)*sc(kc) + hc(kc-1)*sc(kc-1)) * i_hnew
370 hc(kc-1) = (hc(kc) + hc(kc-1))
377 drho_ds(kc) = drho_ds(k) ; drho_dt(kc) = drho_dt(k)
378 tc(kc) = tf(k,i) ; sc(kc) = sf(k,i) ; hc(kc) = hf(k,i)
383 gprime(k) = g_rho0 * (drho_dt(k)*(tc(k)-tc(k-1)) + drho_ds(k)*(sc(k)-sc(k-1)))
388 hc(1) = hf(1,i) ; rc(1) = rf(1,i)
391 merge = ((rf(k,i) - rc(kc)) * ((hc(kc) * hf(k,i))*i_htot) < 2.0*tol_merge*drxh_sum)
393 merge = ((rf(k,i) - rc(kc)) * (hc(kc) + hf(k,i)) < 2.0*tol_merge*drxh_sum)
397 rc(kc) = (hc(kc)*rc(kc) + hf(k,i)*rf(k,i)) / (hc(kc) + hf(k,i))
398 hc(kc) = (hc(kc) + hf(k,i))
404 merge = ((rc(k2)-rc(k2-1)) * ((hc(k2) * hc(k2-1))*i_htot) < tol_merge*drxh_sum)
406 merge = ((rc(k2)-rc(k2-1)) * (hc(k2)+hc(k2-1)) < tol_merge*drxh_sum)
410 rc(kc-1) = (hc(kc)*rc(kc) + hc(kc-1)*rc(kc-1)) / (hc(kc) + hc(kc-1))
411 hc(kc-1) = (hc(kc) + hc(kc-1))
418 rc(kc) = rf(k,i) ; hc(kc) = hf(k,i)
423 gprime(k) = g_rho0 * (rc(k)-rc(k-1))
433 h_top(1) = 0.0 ; h_bot(kc+1) = 0.0
434 do k=2,kc+1 ; h_top(k) = h_top(k-1) + hc(k-1) ;
enddo
435 do k=kc,2,-1 ; h_bot(k) = h_bot(k+1) + hc(k) ;
enddo
436 i_htot = 0.0 ;
if (h_top(kc+1) > 0.0) i_htot = 1.0 / h_top(kc+1)
439 if (l_use_ebt_mode)
then
442 n2min = l2_to_z2*gprime(2)/hc(1)
444 hw = 0.5*(hc(k-1)+hc(k))
446 if (l_mono_n2_column_fraction>0. .or. l_mono_n2_depth>=0.)
then
447 if ( ((g%bathyT(i,j)-sum_hc < l_mono_n2_column_fraction*g%bathyT(i,j)) .or. &
448 ((l_mono_n2_depth >= 0.) .and. (sum_hc > l_mono_n2_depth))) .and. &
449 (l2_to_z2*gp > n2min*hw) )
then
452 gp = us%Z_to_L**2 * (n2min*hw)
454 n2min = l2_to_z2 * gp/hw
457 igu(k) = 1.0/(gp*hc(k))
458 igl(k-1) = 1.0/(gp*hc(k-1))
459 sum_hc = sum_hc + hc(k)
462 speed2_tot = speed2_tot + 2.0 * gprime(k)*((h_top(k) * h_bot(k)) * i_htot)
464 speed2_tot = speed2_tot + gprime(k)*(hc(k-1)+hc(k))*0.707
471 igl(k) = 1.0/(gprime(k)*hc(k)) ; igu(k) = 1.0/(gprime(k)*hc(k-1))
473 speed2_tot = speed2_tot + gprime(k)*((h_top(k) * h_bot(k)) * i_htot)
475 speed2_tot = speed2_tot + gprime(k)*(hc(k-1)+hc(k))
480 if (calc_modal_structure)
then
482 mode_struct(1:kc) = 1.
486 if (calc_modal_structure)
then
487 lam0 = 0.5 / speed2_tot ; lam = lam0
489 lam0 = 1.0 / speed2_tot ; lam = lam0
494 if (l_use_ebt_mode)
then
503 call tridiag_det(igu, igl, 1, kc, lam, det, ddet, row_scale=c2_scale)
514 call tridiag_det(igu, igl, 2, kc, lam, det, ddet, row_scale=c2_scale)
517 det_it(itt) = det ; ddet_it(itt) = ddet
519 if ((ddet >= 0.0) .or. (-det > -0.5*lam*ddet))
then
530 if (calc_modal_structure)
then
531 call tdma6(kc, igu, igl, lam, mode_struct)
532 ms_min = mode_struct(1)
533 ms_max = mode_struct(1)
534 ms_sq = mode_struct(1)**2
536 ms_min = min(ms_min, mode_struct(k))
537 ms_max = max(ms_max, mode_struct(k))
538 ms_sq = ms_sq + mode_struct(k)**2
540 if (ms_min<0. .and. ms_max>0.)
then
541 lam = 0.5 * ( lam - dlam )
543 mode_struct(1:kc) = abs(mode_struct(1:kc)) / sqrt( ms_sq )
545 mode_struct(1:kc) = mode_struct(1:kc) / sqrt( ms_sq )
549 if (abs(dlam) < tol_solve*lam)
exit
553 if (lam > 0.0) cg1(i,j) = 1.0 / sqrt(lam)
555 if (
present(modal_structure))
then
556 if (mode_struct(1)/=0.)
then
557 mode_struct(1:kc) = mode_struct(1:kc) / mode_struct(1)
564 hc_h(k) = gv%Z_to_H * hc(k)
566 if (cs%remap_answers_2018)
then
567 call remapping_core_h(cs%remapping_CS, kc, hc_h(:), mode_struct, &
568 nz, h(i,j,:), modal_structure(i,j,:), &
569 1.0e-30*gv%m_to_H, 1.0e-10*gv%m_to_H)
571 call remapping_core_h(cs%remapping_CS, kc, hc_h(:), mode_struct, &
572 nz, h(i,j,:), modal_structure(i,j,:), &
573 gv%H_subroundoff, gv%H_subroundoff)
578 if (
present(modal_structure)) modal_structure(i,j,:) = 0.
583 if (
present(modal_structure)) modal_structure(i,j,:) = 0.
587 end subroutine wave_speed
592 subroutine tdma6(n, a, c, lam, y)
593 integer,
intent(in) :: n
594 real,
dimension(:),
intent(in) :: a
595 real,
dimension(:),
intent(in) :: c
596 real,
intent(in) :: lam
597 real,
dimension(:),
intent(inout) :: y
607 beta(1) = (a(1)+c(1)) - lambda
608 if (beta(1)==0.)
then
610 lambda = (1. + 1.e-5) * lambda
611 beta(1) = (a(1)+c(1)) - lambda
613 i_beta(1) = 1. / beta(1)
616 beta(k) = ( (a(k)+c(k)) - lambda ) - a(k) * c(k-1) * i_beta(k-1)
618 if (beta(k)==0.)
then
620 lambda = (1. + 1.e-5) * lambda
621 i_beta(1) = 1. / ( (a(1)+c(1)) - lambda )
623 i_beta(m) = 1. / ( ( (a(m)+c(m)) - lambda ) - a(m) * c(m-1) * i_beta(m-1) )
624 yy(m) = y(m) + a(m) * yy(m-1) * i_beta(m-1)
627 i_beta(k) = 1. / beta(k)
629 yy(k) = y(k) + a(k) * yy(k-1) * i_beta(k-1)
632 y(n) = yy(n) * i_beta(n)
634 y(k) = ( yy(k) + c(k) * y(k+1) ) * i_beta(k)
640 subroutine wave_speeds(h, tv, G, GV, US, nmodes, cn, CS, full_halos, better_speed_est, &
641 min_speed, wave_speed_tol)
645 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
647 integer,
intent(in) :: nmodes
648 real,
dimension(G%isd:G%ied,G%jsd:G%jed,nmodes),
intent(out) :: cn
650 logical,
optional,
intent(in) :: full_halos
652 logical,
optional,
intent(in) :: better_speed_est
654 real,
optional,
intent(in) :: min_speed
656 real,
optional,
intent(in) :: wave_speed_tol
660 real,
dimension(SZK_(G)+1) :: &
669 real,
dimension(SZK_(G),SZI_(G)) :: &
674 real,
dimension(SZK_(G)) :: &
695 real :: ddet_l,ddet_r
696 real :: det_sub,ddet_sub
699 real,
dimension(nmodes) :: &
702 integer :: nrootsfound
704 real,
dimension(SZI_(G)) :: &
713 real,
parameter :: reduct_factor = 0.5
717 real,
pointer,
dimension(:,:,:) :: t => null(), s => null()
725 integer :: kf(szi_(g))
726 integer,
parameter :: max_itt = 10
728 logical :: better_est
731 integer,
parameter :: sub_it_max = 4
734 logical :: sub_rootfound
736 integer :: sub, sub_it
737 integer :: i, j, k, k2, itt, is, ie, js, je, nz, row, iint, m, ig, jg
739 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
741 if (
present(cs))
then
742 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_wave_speed: "// &
743 "Module must be initialized before it is used.")
746 if (
present(full_halos))
then ;
if (full_halos)
then
747 is = g%isd ; ie = g%ied ; js = g%jsd ; je = g%jed
750 s => tv%S ; t => tv%T
751 g_rho0 = gv%g_Earth / gv%Rho0
753 z_to_pres = gv%Z_to_H * (gv%H_to_RZ * gv%g_Earth)
754 use_eos =
associated(tv%eqn_of_state)
755 c1_thresh = 0.01*us%m_s_to_L_T
756 c2_scale = us%m_s_to_L_T**2 / 4096.0**2
758 better_est = .false. ;
if (
present(cs)) better_est = cs%better_cg1_est
759 if (
present(better_speed_est)) better_est = better_speed_est
761 tol_solve = 0.001 ;
if (
present(cs)) tol_solve = cs%wave_speed_tol
762 if (
present(wave_speed_tol)) tol_solve = wave_speed_tol
763 tol_hfrac = 0.1*tol_solve ; tol_merge = tol_solve / real(nz)
765 tol_solve = 0.001 ; tol_hfrac = 0.0001 ; tol_merge = 0.001
767 cg1_min2 = 0.0 ;
if (
present(cs)) cg1_min2 = cs%min_speed2
768 if (
present(min_speed)) cg1_min2 = min_speed**2
774 min_h_frac = tol_hfrac / real(nz)
782 do i=is,ie ; htot(i) = 0.0 ;
enddo
783 do k=1,nz ;
do i=is,ie ; htot(i) = htot(i) + h(i,j,k)*gv%H_to_Z ;
enddo ;
enddo
786 hmin(i) = htot(i)*min_h_frac ; kf(i) = 1 ; h_here(i) = 0.0
787 hxt_here(i) = 0.0 ; hxs_here(i) = 0.0 ; hxr_here(i) = 0.0
790 do k=1,nz ;
do i=is,ie
791 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
792 hf(kf(i),i) = h_here(i)
793 tf(kf(i),i) = hxt_here(i) / h_here(i)
794 sf(kf(i),i) = hxs_here(i) / h_here(i)
798 h_here(i) = h(i,j,k)*gv%H_to_Z
799 hxt_here(i) = (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
800 hxs_here(i) = (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
802 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
803 hxt_here(i) = hxt_here(i) + (h(i,j,k)*gv%H_to_Z)*t(i,j,k)
804 hxs_here(i) = hxs_here(i) + (h(i,j,k)*gv%H_to_Z)*s(i,j,k)
807 do i=is,ie ;
if (h_here(i) > 0.0)
then
808 hf(kf(i),i) = h_here(i)
809 tf(kf(i),i) = hxt_here(i) / h_here(i)
810 sf(kf(i),i) = hxs_here(i) / h_here(i)
813 do k=1,nz ;
do i=is,ie
814 if ((h_here(i) > hmin(i)) .and. (h(i,j,k)*gv%H_to_Z > hmin(i)))
then
815 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
819 h_here(i) = h(i,j,k)*gv%H_to_Z
820 hxr_here(i) = (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
822 h_here(i) = h_here(i) + h(i,j,k)*gv%H_to_Z
823 hxr_here(i) = hxr_here(i) + (h(i,j,k)*gv%H_to_Z)*gv%Rlay(k)
826 do i=is,ie ;
if (h_here(i) > 0.0)
then
827 hf(kf(i),i) = h_here(i) ; rf(kf(i),i) = hxr_here(i) / h_here(i)
833 if (g%mask2dT(i,j) > 0.5)
then
835 pres(1) = 0.0 ; h_top(1) = 0.0
837 pres(k) = pres(k-1) + z_to_pres*hf(k-1,i)
838 t_int(k) = 0.5*(tf(k,i)+tf(k-1,i))
839 s_int(k) = 0.5*(sf(k,i)+sf(k-1,i))
840 h_top(k) = h_top(k-1) + hf(k-1,i)
843 tv%eqn_of_state, (/2,kf(i)/) )
852 if (h_top(kf(i)) > 0.0)
then
853 i_htot = 1.0 / (h_top(kf(i)) + hf(kf(i),i))
856 h_bot(k) = h_bot(k+1) + hf(k,i)
857 drxh_sum = drxh_sum + ((h_top(k) * h_bot(k)) * i_htot) * &
858 max(0.0, drho_dt(k)*(tf(k,i)-tf(k-1,i)) + drho_ds(k)*(sf(k,i)-sf(k-1,i)))
866 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * &
867 max(0.0, drho_dt(k)*(tf(k,i)-tf(k-1,i)) + drho_ds(k)*(sf(k,i)-sf(k-1,i)))
874 do k=2,kf(i) ; h_top(k) = h_top(k-1) + hf(k-1,i) ;
enddo
875 if (h_top(kf(i)) > 0.0)
then
876 i_htot = 1.0 / (h_top(kf(i)) + hf(kf(i),i))
879 h_bot(k) = h_bot(k+1) + hf(k,i)
880 drxh_sum = drxh_sum + ((h_top(k) * h_bot(k)) * i_htot) * max(0.0,rf(k,i)-rf(k-1,i))
885 drxh_sum = drxh_sum + 0.5*(hf(k-1,i)+hf(k,i)) * max(0.0,rf(k,i)-rf(k-1,i))
892 if (g_rho0 * drxh_sum > cg1_min2)
then
898 hc(1) = hf(1,i) ; tc(1) = tf(1,i) ; sc(1) = sf(1,i)
901 merge = ((drho_dt(k)*(tf(k,i)-tc(kc)) + drho_ds(k)*(sf(k,i)-sc(kc))) * &
902 ((hc(kc) * hf(k,i))*i_htot) < 2.0 * tol_merge*drxh_sum)
904 merge = ((drho_dt(k)*(tf(k,i)-tc(kc)) + drho_ds(k)*(sf(k,i)-sc(kc))) * &
905 (hc(kc) + hf(k,i)) < 2.0 * tol_merge*drxh_sum)
909 i_hnew = 1.0 / (hc(kc) + hf(k,i))
910 tc(kc) = (hc(kc)*tc(kc) + hf(k,i)*tf(k,i)) * i_hnew
911 sc(kc) = (hc(kc)*sc(kc) + hf(k,i)*sf(k,i)) * i_hnew
912 hc(kc) = (hc(kc) + hf(k,i))
918 merge = ((drho_dt(k2)*(tc(k2)-tc(k2-1)) + drho_ds(k2)*(sc(k2)-sc(k2-1))) * &
919 ((hc(k2) * hc(k2-1))*i_htot) < tol_merge*drxh_sum)
921 merge = ((drho_dt(k2)*(tc(k2)-tc(k2-1)) + drho_ds(k2)*(sc(k2)-sc(k2-1))) * &
922 (hc(k2) + hc(k2-1)) < tol_merge*drxh_sum)
926 i_hnew = 1.0 / (hc(kc) + hc(kc-1))
927 tc(kc-1) = (hc(kc)*tc(kc) + hc(kc-1)*tc(kc-1)) * i_hnew
928 sc(kc-1) = (hc(kc)*sc(kc) + hc(kc-1)*sc(kc-1)) * i_hnew
929 hc(kc-1) = (hc(kc) + hc(kc-1))
936 drho_ds(kc) = drho_ds(k) ; drho_dt(kc) = drho_dt(k)
937 tc(kc) = tf(k,i) ; sc(kc) = sf(k,i) ; hc(kc) = hf(k,i)
942 gprime(k) = g_rho0 * (drho_dt(k)*(tc(k)-tc(k-1)) + drho_ds(k)*(sc(k)-sc(k-1)))
947 hc(1) = hf(1,i) ; rc(1) = rf(1,i)
950 merge = ((rf(k,i) - rc(kc)) * ((hc(kc) * hf(k,i))*i_htot) < 2.0 * tol_merge*drxh_sum)
952 merge = ((rf(k,i) - rc(kc)) * (hc(kc) + hf(k,i)) < 2.0*tol_merge*drxh_sum)
956 rc(kc) = (hc(kc)*rc(kc) + hf(k,i)*rf(k,i)) / (hc(kc) + hf(k,i))
957 hc(kc) = (hc(kc) + hf(k,i))
963 merge = ((rc(k2)-rc(k2-1)) * ((hc(k2) * hc(k2-1))*i_htot) < tol_merge*drxh_sum)
965 merge = ((rc(k2)-rc(k2-1)) * (hc(k2)+hc(k2-1)) < tol_merge*drxh_sum)
969 rc(kc-1) = (hc(kc)*rc(kc) + hc(kc-1)*rc(kc-1)) / (hc(kc) + hc(kc-1))
970 hc(kc-1) = (hc(kc) + hc(kc-1))
977 rc(kc) = rf(k,i) ; hc(kc) = hf(k,i)
982 gprime(k) = g_rho0 * (rc(k)-rc(k-1))
995 h_top(1) = 0.0 ; h_bot(kc+1) = 0.0
996 do k=2,kc+1 ; h_top(k) = h_top(k-1) + hc(k-1) ;
enddo
997 do k=kc,2,-1 ; h_bot(k) = h_bot(k+1) + hc(k) ;
enddo
998 i_htot = 0.0 ;
if (h_top(kc+1) > 0.0) i_htot = 1.0 / h_top(kc+1)
1004 igl(k) = 1.0/(gprime(k)*hc(k)) ; igu(k) = 1.0/(gprime(k)*hc(k-1))
1005 if (better_est)
then
1006 speed2_tot = speed2_tot + gprime(k)*((h_top(k) * h_bot(k)) * i_htot)
1008 speed2_tot = speed2_tot + gprime(k)*(hc(k-1)+hc(k))
1013 lam_1 = 1.0 / speed2_tot
1018 call tridiag_det(igu, igl, 2, kc, lam_1, det, ddet, row_scale=c2_scale)
1022 if ((ddet >= 0.0) .or. (-det > -0.5*lam_1*ddet))
then
1029 lam_1 = lam_1 + dlam
1032 if (abs(dlam) < tol_solve*lam_1)
exit
1035 if (lam_1 > 0.0) cn(i,j,1) = 1.0 / sqrt(lam_1)
1039 if (nmodes>1 .and. kc>=nmodes+1 .and. cn(i,j,1)>c1_thresh)
then
1042 lammin = lam_1*(1.0 + tol_solve)
1044 speed2_min = (reduct_factor*cn(i,j,1)/real(nmodes))**2
1045 lammax = 1.0 / speed2_min
1049 numint = nint((lammax - lammin)/laminc)
1055 call tridiag_det(igu, igl, 2, kc, lammin, det_l, ddet_l, row_scale=c2_scale)
1058 xr = lammin + laminc * iint
1060 call tridiag_det(igu, igl, 2, kc, xr, det_r, ddet_r, row_scale=c2_scale)
1061 if (det_l*det_r < 0.0)
then
1062 if (det_l*ddet_l < 0.0)
then
1063 nrootsfound = nrootsfound + 1
1064 xbl(nrootsfound) = xl
1065 xbr(nrootsfound) = xr
1074 sub_rootfound = .false.
1075 do sub_it=1,sub_it_max
1079 xl_sub = xl + laminc/(nsub)*sub
1080 call tridiag_det(igu, igl, 2, kc, xl_sub, det_sub, ddet_sub, &
1082 if (det_sub*det_r < 0.0)
then
1083 if (det_sub*ddet_sub < 0.0)
then
1084 sub_rootfound = .true.
1085 nrootsfound = nrootsfound + 1
1086 xbl(nrootsfound) = xl_sub
1087 xbr(nrootsfound) = xr
1092 if (sub_rootfound)
exit
1095 if (sub_it == sub_it_max)
then
1096 call mom_error(warning,
"wave_speed: root not found "// &
1097 " after sub_it_max subdivisions of original"// &
1104 if (nrootsfound >= nmodes-1)
then
1107 elseif (iint == numint)
then
1123 call tridiag_det(igu, igl, 2, kc, lam_n, det, ddet, row_scale=c2_scale)
1126 lam_n = lam_n + dlam
1127 if (abs(dlam) < tol_solve*lam_1)
exit
1130 if (lam_n > 0.0) cn(i,j,m+1) = 1.0 / sqrt(lam_n)
1139 end subroutine wave_speeds
1145 subroutine tridiag_det(a, c, ks, ke, lam, det, ddet, row_scale)
1146 real,
dimension(:),
intent(in) :: a
1147 real,
dimension(:),
intent(in) :: c
1148 integer,
intent(in) :: ks
1149 integer,
intent(in) :: ke
1150 real,
intent(in) :: lam
1151 real,
intent(out):: det
1152 real,
intent(out):: ddet
1153 real,
optional,
intent(in) :: row_scale
1156 real :: detKm1, detKm2
1157 real :: ddetKm1, ddetKm2
1158 real,
parameter :: rescale = 1024.0**4
1163 i_rescale = 1.0 / rescale
1164 rscl = 1.0 ;
if (
present(row_scale)) rscl = row_scale
1166 detkm1 = 1.0 ; ddetkm1 = 0.0
1167 det = (a(ks)+c(ks)) - lam ; ddet = -1.0
1170 detkm2 = row_scale*detkm1 ; ddetkm2 = row_scale*ddetkm1
1171 detkm1 = row_scale*det ; ddetkm1 = row_scale*ddet
1173 det = ((a(k)+c(k))-lam)*detkm1 - (a(k)*c(k-1))*detkm2
1174 ddet = ((a(k)+c(k))-lam)*ddetkm1 - (a(k)*c(k-1))*ddetkm2 - detkm1
1177 if (abs(det) > rescale)
then
1178 det = i_rescale*det ; detkm1 = i_rescale*detkm1
1179 ddet = i_rescale*ddet ; ddetkm1 = i_rescale*ddetkm1
1180 elseif (abs(det) < i_rescale)
then
1181 det = rescale*det ; detkm1 = rescale*detkm1
1182 ddet = rescale*ddet ; ddetkm1 = rescale*ddetkm1
1186 end subroutine tridiag_det
1189 subroutine wave_speed_init(CS, use_ebt_mode, mono_N2_column_fraction, mono_N2_depth, remap_answers_2018, &
1190 better_speed_est, min_speed, wave_speed_tol)
1192 logical,
optional,
intent(in) :: use_ebt_mode
1194 real,
optional,
intent(in) :: mono_n2_column_fraction
1197 real,
optional,
intent(in) :: mono_n2_depth
1200 logical,
optional,
intent(in) :: remap_answers_2018
1203 logical,
optional,
intent(in) :: better_speed_est
1205 real,
optional,
intent(in) :: min_speed
1207 real,
optional,
intent(in) :: wave_speed_tol
1211 # include "version_variable.h"
1212 character(len=40) :: mdl =
"MOM_wave_speed"
1214 if (
associated(cs))
then
1215 call mom_error(warning,
"wave_speed_init called with an "// &
1216 "associated control structure.")
1218 else ;
allocate(cs) ;
endif
1223 call wave_speed_set_param(cs, use_ebt_mode=use_ebt_mode, mono_n2_column_fraction=mono_n2_column_fraction, &
1224 better_speed_est=better_speed_est, min_speed=min_speed, wave_speed_tol=wave_speed_tol)
1226 call initialize_remapping(cs%remapping_CS,
'PLM', boundary_extrapolation=.false., &
1227 answers_2018=cs%remap_answers_2018)
1229 end subroutine wave_speed_init
1232 subroutine wave_speed_set_param(CS, use_ebt_mode, mono_N2_column_fraction, mono_N2_depth, remap_answers_2018, &
1233 better_speed_est, min_speed, wave_speed_tol)
1235 logical,
optional,
intent(in) :: use_ebt_mode
1237 real,
optional,
intent(in) :: mono_n2_column_fraction
1240 real,
optional,
intent(in) :: mono_n2_depth
1243 logical,
optional,
intent(in) :: remap_answers_2018
1246 logical,
optional,
intent(in) :: better_speed_est
1248 real,
optional,
intent(in) :: min_speed
1250 real,
optional,
intent(in) :: wave_speed_tol
1253 if (.not.
associated(cs))
call mom_error(fatal, &
1254 "wave_speed_set_param called with an associated control structure.")
1256 if (
present(use_ebt_mode)) cs%use_ebt_mode = use_ebt_mode
1257 if (
present(mono_n2_column_fraction)) cs%mono_N2_column_fraction = mono_n2_column_fraction
1258 if (
present(mono_n2_depth)) cs%mono_N2_depth = mono_n2_depth
1259 if (
present(remap_answers_2018)) cs%remap_answers_2018 = remap_answers_2018
1260 if (
present(better_speed_est)) cs%better_cg1_est = better_speed_est
1261 if (
present(min_speed)) cs%min_speed2 = min_speed**2
1262 if (
present(wave_speed_tol)) cs%wave_speed_tol = wave_speed_tol
1264 end subroutine wave_speed_set_param