Calculates the wave speed of the first baroclinic mode.
59 type(ocean_grid_type),
intent(in) :: G
60 type(verticalGrid_type),
intent(in) :: GV
61 type(unit_scale_type),
intent(in) :: US
62 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
64 type(thermo_var_ptrs),
intent(in) :: tv
65 real,
dimension(SZI_(G),SZJ_(G)),
intent(out) :: cg1
66 type(wave_speed_CS),
pointer :: CS
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)
280 call calculate_density_derivs(t_int, s_int, pres, drho_dt, drho_ds, &
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.