51 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
63 implicit none ;
private 65 #include <MOM_memory.h> 71 logical :: regularize_surface_layers
75 logical :: reg_sfc_detrain
88 type(time_type),
pointer :: time
93 type(group_pass_type) :: pass_h
95 integer :: id_def_rat = -1
96 logical :: allow_clocks_in_omp_loops
100 integer :: id_def_rat_2 = -1, id_def_rat_3 = -1
101 integer :: id_def_rat_u = -1, id_def_rat_v = -1
102 integer :: id_e1 = -1, id_e2 = -1, id_e3 = -1
103 integer :: id_def_rat_u_1b = -1, id_def_rat_v_1b = -1
104 integer :: id_def_rat_u_2 = -1, id_def_rat_u_2b = -1
105 integer :: id_def_rat_v_2 = -1, id_def_rat_v_2b = -1
106 integer :: id_def_rat_u_3 = -1, id_def_rat_u_3b = -1
107 integer :: id_def_rat_v_3 = -1, id_def_rat_v_3b = -1
120 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
125 real,
intent(in) :: dt
126 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
131 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
158 integer :: i, j, k, is, ie, js, je, nz
160 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
162 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_regularize_layers: "//&
163 "Module must be initialized before it is used.")
165 if (cs%regularize_surface_layers)
then 168 call do_group_pass(cs%pass_h,g%Domain)
172 if (cs%regularize_surface_layers)
then 183 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
188 real,
intent(in) :: dt
189 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
194 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
221 real,
dimension(SZIB_(G),SZJ_(G)) :: &
223 real,
dimension(SZI_(G),SZJB_(G)) :: &
225 real,
dimension(SZI_(G),SZJ_(G)) :: &
227 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: &
231 real,
dimension(SZIB_(G),SZJ_(G)) :: &
232 def_rat_u_1b, def_rat_u_2, def_rat_u_2b, def_rat_u_3, def_rat_u_3b
233 real,
dimension(SZI_(G),SZJB_(G)) :: &
234 def_rat_v_1b, def_rat_v_2, def_rat_v_2b, def_rat_v_3, def_rat_v_3b
235 real,
dimension(SZI_(G),SZJB_(G)) :: &
236 def_rat_h2, def_rat_h3
237 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: &
241 real,
dimension(SZI_(G),SZK_(G)+1) :: &
243 real,
dimension(SZI_(G),SZK_(G)) :: &
257 real,
dimension(SZI_(G)) :: &
262 h_add_tgt, h_add_tot, &
263 h_tot1, th_tot1, sh_tot1, &
264 h_tot3, th_tot3, sh_tot3, &
265 h_tot2, th_tot2, sh_tot2
266 real,
dimension(SZK_(G)) :: &
271 real :: e_e, e_w, e_n, e_s
276 real,
dimension(SZK_(G)+1) :: &
277 int_flux, int_Tflux, int_Sflux, int_Rflux
284 real :: int_top, int_bot
289 logical :: cols_left, ent_any, more_ent_i(szi_(g)), ent_i(szi_(g))
290 logical :: det_any, det_i(szi_(g))
291 logical :: do_j(szj_(g)), do_i(szi_(g)), find_i(szi_(g))
292 logical :: debug = .false.
293 logical :: fatal_error
294 character(len=256) :: mesg
295 integer :: i, j, k, is, ie, js, je, nz, nkmb, nkml, k1, k2, k3, ks, nz_filt
297 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
299 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_regularize_layers: "//&
300 "Module must be initialized before it is used.")
302 if (gv%nkml<1)
return 303 nkmb = gv%nk_rho_varies ; nkml = gv%nkml
304 if (.not.
ASSOCIATED(tv%eqn_of_state))
call mom_error(fatal, &
305 "MOM_regularize_layers: This module now requires the use of temperature and "//&
306 "an equation of state.")
308 h_neglect = gv%H_subroundoff
309 debug = (debug .or. cs%debug)
312 if (cs%id_def_rat_2 > 0)
then 313 is = g%isc-1 ; ie = g%iec+1 ; js = g%jsc-1 ; je = g%jec+1
317 i_dtol = 1.0 / max(cs%h_def_tol2 - cs%h_def_tol1, 1e-40)
318 i_dtol34 = 1.0 / max(cs%h_def_tol4 - cs%h_def_tol3, 1e-40)
320 p_ref_cv(:) = tv%P_Ref
322 do j=js-1,je+1 ;
do i=is-1,ie+1
325 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie+1
326 e(i,j,k+1) = e(i,j,k) - h(i,j,k)
327 enddo ;
enddo ;
enddo 330 call find_deficit_ratios(e, def_rat_u, def_rat_v, g, gv, cs, def_rat_u_1b, def_rat_v_1b, 1, h)
335 do j=js,je ; do_j(j) = .false. ;
enddo 336 do j=js,je ;
do i=is,ie
337 def_rat_h(i,j) = max(def_rat_u(i-1,j), def_rat_u(i,j), &
338 def_rat_v(i,j-1), def_rat_v(i,j))
339 if (def_rat_h(i,j) > cs%h_def_tol1) do_j(j) = .true.
343 if ((cs%id_def_rat_3 > 0) .or. (cs%id_e3 > 0) .or. &
344 (cs%id_def_rat_u_3 > 0) .or. (cs%id_def_rat_u_3b > 0) .or. &
345 (cs%id_def_rat_v_3 > 0) .or. (cs%id_def_rat_v_3b > 0) )
then 346 do j=js-1,je+1 ;
do i=is-1,ie+1
349 do k=2,nz+1 ;
do j=js,je ;
do i=is,ie
350 if (g%mask2dCu(i,j) <= 0.0)
then ; e_e = e(i,j,k) ;
else 351 e_e = max(e(i+1,j,k) + min(e(i,j,k) - e(i+1,j,nz+1), 0.0), e(i,j,nz+1))
353 if (g%mask2dCu(i-1,j) <= 0.0)
then ; e_w = e(i,j,k) ;
else 354 e_w = max(e(i-1,j,k) + min(e(i,j,k) - e(i-1,j,nz+1), 0.0), e(i,j,nz+1))
356 if (g%mask2dCv(i,j) <= 0.0)
then ; e_n = e(i,j,k) ;
else 357 e_n = max(e(i,j+1,k) + min(e(i,j,k) - e(i,j+1,nz+1), 0.0), e(i,j,nz+1))
359 if (g%mask2dCv(i,j-1) <= 0.0)
then ; e_s = e(i,j,k) ;
else 360 e_s = max(e(i,j-1,k) + min(e(i,j,k) - e(i,j-1,nz+1), 0.0), e(i,j,nz+1))
364 ef(i,j,k) = (1.0 - 0.5*wt) * e(i,j,k) + &
365 wt * 0.125 * ((e_e + e_w) + (e_n + e_s))
366 enddo ;
enddo ;
enddo 367 call find_deficit_ratios(ef, def_rat_u_3, def_rat_v_3, g, gv, cs, def_rat_u_3b, def_rat_v_3b)
370 do j=js,je ;
do i=is,ie
371 def_rat_h3(i,j) = max(def_rat_u_3(i-1,j), def_rat_u_3(i,j), &
372 def_rat_v_3(i,j-1), def_rat_v_3(i,j))
375 if (cs%id_e3 > 0)
call post_data(cs%id_e3, ef, cs%diag)
376 if (cs%id_def_rat_3 > 0)
call post_data(cs%id_def_rat_3, def_rat_h3, cs%diag)
377 if (cs%id_def_rat_u_3 > 0)
call post_data(cs%id_def_rat_u_3, def_rat_u_3, cs%diag)
378 if (cs%id_def_rat_u_3b > 0)
call post_data(cs%id_def_rat_u_3b, def_rat_u_3b, cs%diag)
379 if (cs%id_def_rat_v_3 > 0)
call post_data(cs%id_def_rat_v_3, def_rat_v_3, cs%diag)
380 if (cs%id_def_rat_v_3b > 0)
call post_data(cs%id_def_rat_v_3b, def_rat_v_3b, cs%diag)
400 do j=js,je ;
if (do_j(j))
then 407 do k=1,nz ;
do i=is,ie ; d_ea(i,k) = 0.0 ; d_eb(i,k) = 0.0 ;
enddo ;
enddo 411 do_i(i) = def_rat_h(i,j) > cs%h_def_tol1
412 if (def_rat_h(i,j) > max_def_rat) max_def_rat = def_rat_h(i,j)
414 nz_filt = nkmb+1 ;
if (max_def_rat > cs%h_def_tol3) nz_filt = nz+1
419 do k=1,nz_filt ;
do i=is,ie ;
if (do_i(i))
then 420 if (g%mask2dCu(i,j) <= 0.0)
then ; e_e = e(i,j,k) ;
else 421 e_e = max(e(i+1,j,k) + min(e(i,j,k) - e(i+1,j,nz+1), 0.0), &
422 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom)
425 if (g%mask2dCu(i-1,j) <= 0.0)
then ; e_w = e(i,j,k) ;
else 426 e_w = max(e(i-1,j,k) + min(e(i,j,k) - e(i-1,j,nz+1), 0.0), &
427 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom)
429 if (g%mask2dCv(i,j) <= 0.0)
then ; e_n = e(i,j,k) ;
else 430 e_n = max(e(i,j+1,k) + min(e(i,j,k) - e(i,j+1,nz+1), 0.0), &
431 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom)
433 if (g%mask2dCv(i,j-1) <= 0.0)
then ; e_s = e(i,j,k) ;
else 434 e_s = max(e(i,j-1,k) + min(e(i,j,k) - e(i,j-1,nz+1), 0.0), &
435 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom)
438 wt = max(0.0, min(1.0, i_dtol*(def_rat_h(i,j)-cs%h_def_tol1)))
440 e_filt(i,k) = (1.0 - 0.5*wt) * e(i,j,k) + &
441 wt * 0.125 * ((e_e + e_w) + (e_n + e_s))
443 endif ;
enddo ;
enddo 444 do k=1,nz ;
do i=is,ie
446 t_2d(i,k) = tv%T(i,j,k) ; s_2d(i,k) = tv%S(i,j,k)
450 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then 451 h_2d_init(i,k) = h(i,j,k)
452 t_2d_init(i,k) = tv%T(i,j,k) ; s_2d_init(i,k) = tv%S(i,j,k)
453 endif ;
enddo ;
enddo 459 more_ent_i(i) = .false. ; ent_i(i) = .false.
460 h_add_tgt(i) = 0.0 ; h_add_tot(i) = 0.0
461 if (do_i(i) .and. (e_2d(i,nkmb+1) > e_filt(i,nkmb+1)))
then 462 more_ent_i(i) = .true. ; ent_i(i) = .true. ; ent_any = .true.
463 h_add_tgt(i) = e_2d(i,nkmb+1) - e_filt(i,nkmb+1)
470 do i=is,ie ;
if (more_ent_i(i))
then 471 if (h_2d(i,k) - gv%Angstrom > h_neglect)
then 472 if (e_2d(i,nkmb+1)-e_filt(i,nkmb+1) > h_2d(i,k) - gv%Angstrom)
then 473 h_add = h_2d(i,k) - gv%Angstrom
474 h_2d(i,k) = gv%Angstrom
476 h_add = e_2d(i,nkmb+1)-e_filt(i,nkmb+1)
477 h_2d(i,k) = h_2d(i,k) - h_add
479 d_eb(i,k-1) = d_eb(i,k-1) + h_add
480 h_add_tot(i) = h_add_tot(i) + h_add
481 e_2d(i,nkmb+1) = e_2d(i,nkmb+1) - h_add
482 h_prev = h_2d(i,nkmb)
483 h_2d(i,nkmb) = h_2d(i,nkmb) + h_add
485 t_2d(i,nkmb) = (h_prev*t_2d(i,nkmb) + h_add*t_2d(i,k)) / h_2d(i,nkmb)
486 s_2d(i,nkmb) = (h_prev*s_2d(i,nkmb) + h_add*s_2d(i,k)) / h_2d(i,nkmb)
488 if ((e_2d(i,nkmb+1) <= e_filt(i,nkmb+1)) .or. &
489 (h_add_tot(i) > 0.6*h_add_tgt(i)))
then 490 more_ent_i(i) = .false.
498 if (.not.cols_left)
exit 502 do k=ks,nkmb,-1 ;
do i=is,ie ;
if (ent_i(i))
then 503 d_eb(i,k) = d_eb(i,k) + d_eb(i,k+1)
504 endif ;
enddo ;
enddo 516 if ((max_def_rat > cs%h_def_tol3) .and. (cs%reg_sfc_detrain))
then 518 det_i(i) = .false. ; rcv_tol(i) = 0.0
519 if (do_i(i) .and. (e_2d(i,nkmb+1) < e_filt(i,nkmb+1)) .and. &
520 (def_rat_h(i,j) > cs%h_def_tol3))
then 521 det_i(i) = .true. ; det_any = .true.
522 rcv_tol(i) = min((def_rat_h(i,j) - cs%h_def_tol3), 1.0)
530 is,ie-is+1,tv%eqn_of_state)
534 do i=is,ie ;
if (det_i(i))
then 541 rcv_min_det = gv%Rlay(k2) + 0.6*rcv_tol(i)*(gv%Rlay(k2-1)-gv%Rlay(k2))
543 rcv_max_det = gv%Rlay(k2) + 0.6*rcv_tol(i)*(gv%Rlay(k2+1)-gv%Rlay(k2))
545 rcv_max_det = gv%Rlay(nz) + 0.6*rcv_tol(i)*(gv%Rlay(nz)-gv%Rlay(nz-1))
547 if (rcv(i,k1) > rcv_max_det) &
550 h_deficit = (e_filt(i,k2)-e_filt(i,k2+1)) - h_2d(i,k2)
551 if ((e_filt(i,k2) > e_2d(i,k1+1)) .and. (h_deficit > 0.0) .and. &
552 (rcv(i,k1) < rcv_max_det) .and. (rcv(i,k1) > rcv_min_det))
then 554 h_add = min(e_filt(i,k2) - e_2d(i,k2), h_deficit )
555 if (h_add < h_2d(i,k1))
then 557 if (h_add > 0.0)
then 559 h_2d(i,k2) = h_2d(i,k2) + h_add
560 e_2d(i,k2) = e_2d(i,k2+1) + h_2d(i,k2)
561 d_ea(i,k2) = d_ea(i,k2) + h_add
563 t_2d(i,k2) = (h_prev*t_2d(i,k2) + h_add*t_2d(i,k1)) / h_2d(i,k2)
564 s_2d(i,k2) = (h_prev*s_2d(i,k2) + h_add*s_2d(i,k1)) / h_2d(i,k2)
565 h_det_tot = h_det_tot + h_add
567 h_2d(i,k1) = h_2d(i,k1) - h_add
568 do k3=k1,nkmb ; e_2d(i,k3+1) = e_2d(i,k3) - h_2d(i,k3) ;
enddo 569 do k3=k1+1,nkmb ; d_ea(i,k3) = d_ea(i,k3) + h_add ;
enddo 572 call mom_error(fatal,
"h_add is negative. Some logic is wrong.")
578 if (k2>nkmb+1) e_2d(i,k2) = e_2d(i,k2) + h_det_tot
582 h_2d(i,k2) = h_2d(i,k2) + h_add
583 e_2d(i,k2) = e_2d(i,k2+1) + h_2d(i,k2)
584 d_ea(i,k2) = d_ea(i,k2) + h_add
585 t_2d(i,k2) = (h_prev*t_2d(i,k2) + h_add*t_2d(i,k1)) / h_2d(i,k2)
586 s_2d(i,k2) = (h_prev*s_2d(i,k2) + h_add*s_2d(i,k1)) / h_2d(i,k2)
587 h_det_tot = h_det_tot + h_add
590 do k3=k1,nkmb ; e_2d(i,k3+1) = e_2d(i,k3) - h_2d(i,k3) ;
enddo 591 do k3=k1+1,nkmb ; d_ea(i,k3) = d_ea(i,k3) + h_add ;
enddo 600 if (k2>nkmb+1) e_2d(i,k2) = e_2d(i,k2) + h_det_tot
606 do k=nz-1,nkmb+1,-1 ;
do i=is,ie ;
if (det_i(i))
then 607 d_ea(i,k) = d_ea(i,k) + d_ea(i,k+1)
608 endif ;
enddo ;
enddo 611 do i=is,ie ; h_tot3(i) = 0.0 ; th_tot3(i) = 0.0 ; sh_tot3(i) = 0.0 ;
enddo 612 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then 613 h_tot3(i) = h_tot3(i) + h_2d(i,k)
614 th_tot3(i) = th_tot3(i) + h_2d(i,k) * t_2d(i,k)
615 sh_tot3(i) = sh_tot3(i) + h_2d(i,k) * s_2d(i,k)
616 endif ;
enddo ;
enddo 619 do i=is,ie ;
if (do_i(i))
then 622 scale = e_2d(i,nkmb+1) / e_filt(i,nkmb+1)
623 do k=2,nkmb+1 ; e_filt(i,k) = e_filt(i,k) * scale ;
enddo 627 if (e_filt(i,2) < e_2d(i,nkml))
then 628 scale = (e_2d(i,nkml) - e_filt(i,nkmb+1)) / &
629 ((e_filt(i,2) - e_filt(i,nkmb+1)) + h_neglect)
631 e_filt(i,k) = e_filt(i,nkmb+1) + scale * (e_filt(i,k) - e_filt(i,nkmb+1))
633 e_filt(i,2) = e_2d(i,nkml)
640 int_flux(k) = 0.0 ; int_rflux(k) = 0.0
641 int_tflux(k) = 0.0 ; int_sflux(k) = 0.0
644 int_bot = max(e_2d(i,k1+1),e_filt(i,k2+1))
645 h_add = int_top - int_bot
649 d_ea(i,k3) = d_ea(i,k3) + h_add
650 int_flux(k3) = int_flux(k3) + h_add
651 int_tflux(k3) = int_tflux(k3) + h_add*t_2d(i,k1)
652 int_sflux(k3) = int_sflux(k3) + h_add*s_2d(i,k1)
654 elseif (k1 > k2)
then 656 d_eb(i,k3) = d_eb(i,k3) + h_add
657 int_flux(k3+1) = int_flux(k3+1) - h_add
658 int_tflux(k3+1) = int_tflux(k3+1) - h_add*t_2d(i,k1)
659 int_sflux(k3+1) = int_sflux(k3+1) - h_add*s_2d(i,k1)
663 if (int_bot <= e_filt(i,k2+1))
then 666 elseif (int_bot <= e_2d(i,k1+1))
then 671 "Regularize_surface: Could not increment target or source.")
673 if ((k1 > nkmb) .or. (k2 > nkmb))
exit 677 call mom_error(fatal,
"Regularize_surface: Did not assign fluid to layer nkmb.")
681 do k=1,nkmb ; h_prev_1d(k) = h_2d(i,k) ;
enddo 682 h_2d(i,1) = h_2d(i,1) - int_flux(2)
684 h_2d(i,k) = h_2d(i,k) + (int_flux(k) - int_flux(k+1))
688 h_2d(i,nkmb) = h_2d(i,nkmb) + int_flux(nkmb)
690 t_2d(i,1) = (t_2d(i,1)*h_prev_1d(1) - int_tflux(2)) / h_2d(i,1)
691 s_2d(i,1) = (s_2d(i,1)*h_prev_1d(1) - int_sflux(2)) / h_2d(i,1)
693 t_2d(i,k) = (t_2d(i,k)*h_prev_1d(k) + (int_tflux(k) - int_tflux(k+1))) / h_2d(i,k)
694 s_2d(i,k) = (s_2d(i,k)*h_prev_1d(k) + (int_sflux(k) - int_sflux(k+1))) / h_2d(i,k)
696 t_2d(i,nkmb) = (t_2d(i,nkmb)*h_prev_1d(nkmb) + int_tflux(nkmb) ) / h_2d(i,nkmb)
697 s_2d(i,nkmb) = (s_2d(i,nkmb)*h_prev_1d(nkmb) + int_sflux(nkmb) ) / h_2d(i,nkmb)
702 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then 704 tv%T(i,j,k) = t_2d(i,k) ; tv%S(i,j,k) = s_2d(i,k)
705 ea(i,j,k) = ea(i,j,k) + d_ea(i,k)
706 eb(i,j,k) = eb(i,j,k) + d_eb(i,k)
707 endif ;
enddo ;
enddo 710 do i=is,ie ; h_tot1(i) = 0.0 ; th_tot1(i) = 0.0 ; sh_tot1(i) = 0.0 ;
enddo 711 do i=is,ie ; h_tot2(i) = 0.0 ; th_tot2(i) = 0.0 ; sh_tot2(i) = 0.0 ;
enddo 713 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then 714 h_tot1(i) = h_tot1(i) + h_2d_init(i,k)
715 h_tot2(i) = h_tot2(i) + h(i,j,k)
717 th_tot1(i) = th_tot1(i) + h_2d_init(i,k) * t_2d_init(i,k)
718 th_tot2(i) = th_tot2(i) + h(i,j,k) * tv%T(i,j,k)
719 sh_tot1(i) = sh_tot1(i) + h_2d_init(i,k) * s_2d_init(i,k)
720 sh_tot2(i) = sh_tot2(i) + h(i,j,k) * tv%S(i,j,k)
721 if (h(i,j,k) < 0.0) &
722 call mom_error(fatal,
"regularize_surface: Negative thicknesses.")
723 if (k==1)
then ; h_predicted = h_2d_init(i,k) + (d_eb(i,k) - d_ea(i,k+1))
724 elseif (k==nz)
then ; h_predicted = h_2d_init(i,k) + (d_ea(i,k) - d_eb(i,k-1))
726 h_predicted = h_2d_init(i,k) + ((d_ea(i,k) - d_eb(i,k-1)) + &
727 (d_eb(i,k) - d_ea(i,k+1)))
729 if (abs(h(i,j,k) - h_predicted) > max(1e-9*abs(h_predicted),gv%Angstrom)) &
730 call mom_error(fatal,
"regularize_surface: d_ea mismatch.")
731 endif ;
enddo ;
enddo 732 do i=is,ie ;
if (do_i(i))
then 733 fatal_error = .false.
734 if (abs(h_tot1(i) - h_tot2(i)) > 1e-12*h_tot1(i))
then 735 write(mesg,
'(ES11.4," became ",ES11.4," diff ",ES11.4)') &
736 h_tot1(i), h_tot2(i), (h_tot1(i) - h_tot2(i))
737 call mom_error(warning,
"regularize_surface: Mass non-conservation."//&
741 if (abs(th_tot1(i) - th_tot2(i)) > 1e-12*(th_tot1(i)+10.0*h_tot1(i)))
then 742 write(mesg,
'(ES11.4," became ",ES11.4," diff ",ES11.4," int diff ",ES11.4)') &
743 th_tot1(i), th_tot2(i), (th_tot1(i) - th_tot2(i)), (th_tot1(i) - th_tot3(i))
744 call mom_error(warning,
"regularize_surface: Heat non-conservation."//&
748 if (abs(sh_tot1(i) - sh_tot2(i)) > 1e-12*(sh_tot1(i)+10.0*h_tot1(i)))
then 749 write(mesg,
'(ES11.4," became ",ES11.4," diff ",ES11.4," int diff ",ES11.4)') &
750 sh_tot1(i), sh_tot2(i), (sh_tot1(i) - sh_tot2(i)), (sh_tot1(i) - sh_tot3(i))
751 call mom_error(warning,
"regularize_surface: Salinity non-conservation."//&
755 if (fatal_error)
then 756 write(mesg,
'("Error at lat/lon ",2(ES11.4))') g%geoLatT(i,j), g%geoLonT(i,j)
757 call mom_error(fatal,
"regularize_surface: Terminating with fatal error. "//&
765 if (cs%id_def_rat > 0)
call post_data(cs%id_def_rat, def_rat_h, cs%diag)
768 if (cs%id_e1 > 0)
call post_data(cs%id_e1, e, cs%diag)
769 if (cs%id_def_rat_u > 0)
call post_data(cs%id_def_rat_u, def_rat_u, cs%diag)
770 if (cs%id_def_rat_u_1b > 0)
call post_data(cs%id_def_rat_u_1b, def_rat_u_1b, cs%diag)
771 if (cs%id_def_rat_v > 0)
call post_data(cs%id_def_rat_v, def_rat_v, cs%diag)
772 if (cs%id_def_rat_v_1b > 0)
call post_data(cs%id_def_rat_v_1b, def_rat_v_1b, cs%diag)
774 if ((cs%id_def_rat_2 > 0) .or. &
775 (cs%id_def_rat_u_2 > 0) .or. (cs%id_def_rat_u_2b > 0) .or. &
776 (cs%id_def_rat_v_2 > 0) .or. (cs%id_def_rat_v_2b > 0) )
then 777 do j=js-1,je+1 ;
do i=is-1,ie+1
780 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie+1
781 e(i,j,k+1) = e(i,j,k) - h(i,j,k)
782 enddo ;
enddo ;
enddo 784 call find_deficit_ratios(e, def_rat_u_2, def_rat_v_2, g, gv, cs, def_rat_u_2b, def_rat_v_2b, h=h)
787 do j=js,je ;
do i=is,ie
788 def_rat_h2(i,j) = max(def_rat_u_2(i-1,j), def_rat_u_2(i,j), &
789 def_rat_v_2(i,j-1), def_rat_v_2(i,j))
792 if (cs%id_def_rat_2 > 0)
call post_data(cs%id_def_rat_2, def_rat_h2, cs%diag)
793 if (cs%id_e2 > 0)
call post_data(cs%id_e2, e, cs%diag)
794 if (cs%id_def_rat_u_2 > 0)
call post_data(cs%id_def_rat_u_2, def_rat_u_2, cs%diag)
795 if (cs%id_def_rat_u_2b > 0)
call post_data(cs%id_def_rat_u_2b, def_rat_u_2b, cs%diag)
796 if (cs%id_def_rat_v_2 > 0)
call post_data(cs%id_def_rat_v_2, def_rat_v_2, cs%diag)
797 if (cs%id_def_rat_v_2b > 0)
call post_data(cs%id_def_rat_v_2b, def_rat_v_2b, cs%diag)
808 def_rat_u_2lay, def_rat_v_2lay, halo, h)
811 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
813 real,
dimension(SZIB_(G),SZJ_(G)), &
814 intent(out) :: def_rat_u
816 real,
dimension(SZI_(G),SZJB_(G)), &
817 intent(out) :: def_rat_v
821 real,
dimension(SZIB_(G),SZJ_(G)), &
822 optional,
intent(out) :: def_rat_u_2lay
825 real,
dimension(SZI_(G),SZJB_(G)), &
826 optional,
intent(out) :: def_rat_v_2lay
829 integer,
optional,
intent(in) :: halo
830 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
831 optional,
intent(in) :: h
854 real,
dimension(SZIB_(G),SZJ_(G)) :: &
859 real,
dimension(SZI_(G),SZJB_(G)) :: &
867 integer :: i, j, k, is, ie, js, je, nz, nkmb
869 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
870 if (
present(halo))
then 871 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
873 nkmb = gv%nk_rho_varies
874 h_neglect = gv%H_subroundoff
877 do j=js,je ;
do i=is-1,ie
880 h1 = e(i,j,nkmb+1)-e(i,j,nz+1) ; h2 = e(i+1,j,nkmb+1)-e(i+1,j,nz+1)
881 if (e(i,j,nz+1) < e(i+1,j,nz+1))
then 882 if (h1 > h2) h1 = max(e(i,j,nkmb+1)-e(i+1,j,nz+1), h2)
883 elseif (e(i+1,j,nz+1) < e(i,j,nz+1))
then 884 if (h2 > h1) h2 = max(e(i+1,j,nkmb+1)-e(i,j,nz+1), h1)
886 h_def_u(i,j) = 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
887 h_norm_u(i,j) = 0.5*(h1+h2)
889 if (
present(def_rat_u_2lay))
then ;
do j=js,je ;
do i=is-1,ie
891 h1 = e(i,j,1)-e(i,j,nkmb+1) ; h2 = e(i+1,j,1)-e(i+1,j,nkmb+1)
892 if (e(i,j,nkmb+1) < e(i+1,j,nz+1))
then 893 if (h1 > h2) h1 = max(e(i,j,1)-e(i+1,j,nz+1), h2)
894 elseif (e(i+1,j,nkmb+1) < e(i,j,nz+1))
then 895 if (h2 > h1) h2 = max(e(i+1,j,1)-e(i,j,nz+1), h1)
897 h_def2_u(i,j) = h_def_u(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
898 enddo ;
enddo ;
endif 899 do k=1,nkmb ;
do j=js,je ;
do i=is-1,ie
901 h1 = h(i,j,k) ; h2 = h(i+1,j,k)
903 h1 = e(i,j,k)-e(i,j,k+1) ; h2 = e(i+1,j,k)-e(i+1,j,k+1)
907 if (e(i,j,k+1) < e(i+1,j,nz+1))
then 908 if (h1 > h2) h1 = max(e(i,j,k)-e(i+1,j,nz+1), h2)
909 elseif (e(i+1,j,k+1) < e(i,j,nz+1))
then 910 if (h2 > h1) h2 = max(e(i+1,j,k)-e(i,j,nz+1), h1)
912 h_def_u(i,j) = h_def_u(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
913 h_norm_u(i,j) = h_norm_u(i,j) + 0.5*(h1+h2)
914 enddo ;
enddo ;
enddo 915 if (
present(def_rat_u_2lay))
then ;
do j=js,je ;
do i=is-1,ie
916 def_rat_u(i,j) = g%mask2dCu(i,j) * h_def_u(i,j) / &
917 (max(cs%Hmix_min, h_norm_u(i,j)) + h_neglect)
918 def_rat_u_2lay(i,j) = g%mask2dCu(i,j) * h_def2_u(i,j) / &
919 (max(cs%Hmix_min, h_norm_u(i,j)) + h_neglect)
920 enddo ;
enddo ;
else ;
do j=js,je ;
do i=is-1,ie
921 def_rat_u(i,j) = g%mask2dCu(i,j) * h_def_u(i,j) / &
922 (max(cs%Hmix_min, h_norm_u(i,j)) + h_neglect)
923 enddo ;
enddo ;
endif 926 do j=js-1,je ;
do i=is,ie
929 h1 = e(i,j,nkmb+1)-e(i,j,nz+1) ; h2 = e(i,j+1,nkmb+1)-e(i,j+1,nz+1)
930 if (e(i,j,nz+1) < e(i,j+1,nz+1))
then 931 if (h1 > h2) h1 = max(e(i,j,nkmb+1)-e(i,j+1,nz+1), h2)
932 elseif (e(i,j+1,nz+1) < e(i,j,nz+1))
then 933 if (h2 > h1) h2 = max(e(i,j+1,nkmb+1)-e(i,j,nz+1), h1)
935 h_def_v(i,j) = 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
936 h_norm_v(i,j) = 0.5*(h1+h2)
938 if (
present(def_rat_v_2lay))
then ;
do j=js-1,je ;
do i=is,ie
940 h1 = e(i,j,1)-e(i,j,nkmb+1) ; h2 = e(i,j+1,1)-e(i,j+1,nkmb+1)
941 if (e(i,j,nkmb+1) < e(i,j+1,nz+1))
then 942 if (h1 > h2) h1 = max(e(i,j,1)-e(i,j+1,nz+1), h2)
943 elseif (e(i,j+1,nkmb+1) < e(i,j,nz+1))
then 944 if (h2 > h1) h2 = max(e(i,j+1,1)-e(i,j,nz+1), h1)
946 h_def2_v(i,j) = h_def_v(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
947 enddo ;
enddo ;
endif 948 do k=1,nkmb ;
do j=js-1,je ;
do i=is,ie
950 h1 = h(i,j,k) ; h2 = h(i,j+1,k)
952 h1 = e(i,j,k)-e(i,j,k+1) ; h2 = e(i,j+1,k)-e(i,j+1,k+1)
956 if (e(i,j,k+1) < e(i,j+1,nz+1))
then 957 if (h1 > h2) h1 = max(e(i,j,k)-e(i,j+1,nz+1), h2)
958 elseif (e(i,j+1,k+1) < e(i,j,nz+1))
then 959 if (h2 > h1) h2 = max(e(i,j+1,k)-e(i,j,nz+1), h1)
961 h_def_v(i,j) = h_def_v(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
962 h_norm_v(i,j) = h_norm_v(i,j) + 0.5*(h1+h2)
963 enddo ;
enddo ;
enddo 964 if (
present(def_rat_v_2lay))
then ;
do j=js-1,je ;
do i=is,ie
965 def_rat_v(i,j) = g%mask2dCv(i,j) * h_def_v(i,j) / &
966 (max(cs%Hmix_min, h_norm_v(i,j)) + h_neglect)
967 def_rat_v_2lay(i,j) = g%mask2dCv(i,j) * h_def2_v(i,j) / &
968 (max(cs%Hmix_min, h_norm_v(i,j)) + h_neglect)
969 enddo ;
enddo ;
else ;
do j=js-1,je ;
do i=is,ie
970 def_rat_v(i,j) = g%mask2dCv(i,j) * h_def_v(i,j) / &
971 (max(cs%Hmix_min, h_norm_v(i,j)) + h_neglect)
972 enddo ;
enddo ;
endif 977 type(time_type),
target,
intent(in) :: Time
981 type(
diag_ctrl),
target,
intent(inout) :: diag
993 #include "version_variable.h" 994 character(len=40) :: mdl =
"MOM_regularize_layers" 995 logical :: use_temperature
996 integer :: isd, ied, jsd, jed
997 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
999 if (
associated(cs))
then 1000 call mom_error(warning,
"regularize_layers_init called with an associated"// &
1001 "associated control structure.")
1003 else ;
allocate(cs) ;
endif 1010 call get_param(param_file, mdl,
"REGULARIZE_SURFACE_LAYERS", cs%regularize_surface_layers, &
1011 "If defined, vertically restructure the near-surface \n"//&
1012 "layers when they have too much lateral variations to \n"//&
1013 "allow for sensible lateral barotropic transports.", &
1015 if (cs%regularize_surface_layers)
then 1016 call get_param(param_file, mdl,
"REGULARIZE_SURFACE_DETRAIN", cs%reg_sfc_detrain, &
1017 "If true, allow the buffer layers to detrain into the \n"//&
1018 "interior as a part of the restructuring when \n"//&
1019 "REGULARIZE_SURFACE_LAYERS is true.", default=.true.)
1022 call get_param(param_file, mdl,
"HMIX_MIN", cs%Hmix_min, &
1023 "The minimum mixed layer depth if the mixed layer depth \n"//&
1024 "is determined dynamically.", units=
"m", default=0.0)
1025 call get_param(param_file, mdl,
"REG_SFC_DEFICIT_TOLERANCE", cs%h_def_tol1, &
1026 "The value of the relative thickness deficit at which \n"//&
1027 "to start modifying the layer structure when \n"//&
1028 "REGULARIZE_SURFACE_LAYERS is true.", units=
"nondim", &
1030 cs%h_def_tol2 = 0.2 + 0.8*cs%h_def_tol1
1031 cs%h_def_tol3 = 0.3 + 0.7*cs%h_def_tol1
1032 cs%h_def_tol4 = 0.5 + 0.5*cs%h_def_tol1
1034 call get_param(param_file, mdl,
"DEBUG", cs%debug, default=.false.)
1039 call get_param(param_file, mdl,
"ALLOW_CLOCKS_IN_OMP_LOOPS", &
1040 cs%allow_clocks_in_omp_loops, &
1041 "If true, clocks can be called from inside loops that can \n"//&
1042 "be threaded. To run with multiple threads, set to False.", &
1045 cs%id_def_rat = register_diag_field(
'ocean_model',
'deficit_ratio', diag%axesT1, &
1046 time,
'Max face thickness deficit ratio',
'Nondim')
1049 cs%id_def_rat_2 = register_diag_field(
'ocean_model',
'deficit_rat2', diag%axesT1, &
1050 time,
'Corrected thickness deficit ratio',
'Nondim')
1051 cs%id_def_rat_3 = register_diag_field(
'ocean_model',
'deficit_rat3', diag%axesT1, &
1052 time,
'Filtered thickness deficit ratio',
'Nondim')
1053 cs%id_e1 = register_diag_field(
'ocean_model',
'er_1', diag%axesTi, &
1054 time,
'Intial interface depths before remapping',
'm')
1055 cs%id_e2 = register_diag_field(
'ocean_model',
'er_2', diag%axesTi, &
1056 time,
'Intial interface depths after remapping',
'm')
1057 cs%id_e3 = register_diag_field(
'ocean_model',
'er_3', diag%axesTi, &
1058 time,
'Intial interface depths filtered',
'm')
1060 cs%id_def_rat_u = register_diag_field(
'ocean_model',
'defrat_u', diag%axesCu1, &
1061 time,
'U-point thickness deficit ratio',
'Nondim')
1062 cs%id_def_rat_u_1b = register_diag_field(
'ocean_model',
'defrat_u_1b', diag%axesCu1, &
1063 time,
'U-point 2-layer thickness deficit ratio',
'Nondim')
1064 cs%id_def_rat_u_2 = register_diag_field(
'ocean_model',
'defrat_u_2', diag%axesCu1, &
1065 time,
'U-point corrected thickness deficit ratio',
'Nondim')
1066 cs%id_def_rat_u_2b = register_diag_field(
'ocean_model',
'defrat_u_2b', diag%axesCu1, &
1067 time,
'U-point corrected 2-layer thickness deficit ratio',
'Nondim')
1068 cs%id_def_rat_u_3 = register_diag_field(
'ocean_model',
'defrat_u_3', diag%axesCu1, &
1069 time,
'U-point filtered thickness deficit ratio',
'Nondim')
1070 cs%id_def_rat_u_3b = register_diag_field(
'ocean_model',
'defrat_u_3b', diag%axesCu1, &
1071 time,
'U-point filtered 2-layer thickness deficit ratio',
'Nondim')
1073 cs%id_def_rat_v = register_diag_field(
'ocean_model',
'defrat_v', diag%axesCv1, &
1074 time,
'V-point thickness deficit ratio',
'Nondim')
1075 cs%id_def_rat_v_1b = register_diag_field(
'ocean_model',
'defrat_v_1b', diag%axesCv1, &
1076 time,
'V-point 2-layer thickness deficit ratio',
'Nondim')
1077 cs%id_def_rat_v_2 = register_diag_field(
'ocean_model',
'defrat_v_2', diag%axesCv1, &
1078 time,
'V-point corrected thickness deficit ratio',
'Nondim')
1079 cs%id_def_rat_v_2b = register_diag_field(
'ocean_model',
'defrat_v_2b', diag%axesCv1, &
1080 time,
'V-point corrected 2-layer thickness deficit ratio',
'Nondim')
1081 cs%id_def_rat_v_3 = register_diag_field(
'ocean_model',
'defrat_v_3', diag%axesCv1, &
1082 time,
'V-point filtered thickness deficit ratio',
'Nondim')
1083 cs%id_def_rat_v_3b = register_diag_field(
'ocean_model',
'defrat_v_3b', diag%axesCv1, &
1084 time,
'V-point filtered 2-layer thickness deficit ratio',
'Nondim')
1087 if(cs%allow_clocks_in_omp_loops)
then 1088 id_clock_eos = cpu_clock_id(
'(Ocean regularize_layers EOS)', grain=clock_routine)
1090 id_clock_pass = cpu_clock_id(
'(Ocean regularize_layers halo updates)', grain=clock_routine)
subroutine regularize_surface(h, tv, dt, ea, eb, G, GV, CS)
This subroutine ensures that there is a degree of horizontal smoothness in the depths of the near-sur...
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
Provides the ocean grid type.
subroutine, public do_group_pass(group, MOM_dom)
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.
subroutine find_deficit_ratios(e, def_rat_u, def_rat_v, G, GV, CS, def_rat_u_2lay, def_rat_v_2lay, halo, h)
This subroutine determines the amount by which the harmonic mean thickness at velocity points differ ...
subroutine, public regularize_layers_init(Time, G, param_file, diag, CS)
Provides subroutines for quantities specific to the equation of state.
subroutine, public regularize_layers(h, tv, dt, ea, eb, G, GV, CS)
This subroutine partially steps the bulk mixed layer model. The following processes are executed...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
subroutine, public mom_error(level, message, all_print)