6 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, clock_routine
18 implicit none ;
private
20 #include <MOM_memory.h>
27 logical :: regularize_surface_layers
31 logical :: reg_sfc_detrain
47 type(time_type),
pointer :: time => null()
52 integer :: id_def_rat = -1
53 logical :: allow_clocks_in_omp_loops
57 integer :: id_def_rat_2 = -1, id_def_rat_3 = -1
58 integer :: id_def_rat_u = -1, id_def_rat_v = -1
59 integer :: id_e1 = -1, id_e2 = -1, id_e3 = -1
60 integer :: id_def_rat_u_1b = -1, id_def_rat_v_1b = -1
61 integer :: id_def_rat_u_2 = -1, id_def_rat_u_2b = -1
62 integer :: id_def_rat_v_2 = -1, id_def_rat_v_2b = -1
63 integer :: id_def_rat_u_3 = -1, id_def_rat_u_3b = -1
64 integer :: id_def_rat_v_3 = -1, id_def_rat_v_3b = -1
81 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
86 real,
intent(in) :: dt
87 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
91 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
99 integer :: i, j, k, is, ie, js, je, nz
101 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
103 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_regularize_layers: "//&
104 "Module must be initialized before it is used.")
106 if (cs%regularize_surface_layers) &
109 if (cs%regularize_surface_layers)
then
120 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
125 real,
intent(in) :: dt
126 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
130 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
138 real,
dimension(SZIB_(G),SZJ_(G)) :: &
140 real,
dimension(SZI_(G),SZJB_(G)) :: &
142 real,
dimension(SZI_(G),SZJ_(G)) :: &
144 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: &
148 real,
dimension(SZIB_(G),SZJ_(G)) :: &
149 def_rat_u_1b, def_rat_u_2, def_rat_u_2b, def_rat_u_3, def_rat_u_3b
150 real,
dimension(SZI_(G),SZJB_(G)) :: &
151 def_rat_v_1b, def_rat_v_2, def_rat_v_2b, def_rat_v_3, def_rat_v_3b
152 real,
dimension(SZI_(G),SZJB_(G)) :: &
153 def_rat_h2, def_rat_h3
154 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: &
158 real,
dimension(SZI_(G),SZK_(G)+1) :: &
160 real,
dimension(SZI_(G),SZK_(G)) :: &
174 real,
dimension(SZI_(G)) :: &
179 h_add_tgt, h_add_tot, &
180 h_tot1, th_tot1, sh_tot1, &
181 h_tot3, th_tot3, sh_tot3, &
182 h_tot2, th_tot2, sh_tot2
183 real,
dimension(SZK_(G)) :: &
188 real :: e_e, e_w, e_n, e_s
193 real,
dimension(SZK_(G)+1) :: &
194 int_flux, int_Tflux, int_Sflux, int_Rflux
201 real :: int_top, int_bot
206 logical :: cols_left, ent_any, more_ent_i(SZI_(G)), ent_i(SZI_(G))
207 logical :: det_any, det_i(SZI_(G))
208 logical :: do_j(SZJ_(G)), do_i(SZI_(G)), find_i(SZI_(G))
209 logical :: debug = .false.
210 logical :: fatal_error
211 character(len=256) :: mesg
212 integer :: i, j, k, is, ie, js, je, nz, nkmb, nkml, k1, k2, k3, ks, nz_filt
214 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
216 if (.not.
associated(cs))
call mom_error(fatal,
"MOM_regularize_layers: "//&
217 "Module must be initialized before it is used.")
219 if (gv%nkml<1)
return
220 nkmb = gv%nk_rho_varies ; nkml = gv%nkml
221 if (.not.
associated(tv%eqn_of_state))
call mom_error(fatal, &
222 "MOM_regularize_layers: This module now requires the use of temperature and "//&
223 "an equation of state.")
225 h_neglect = gv%H_subroundoff
226 debug = (debug .or. cs%debug)
229 if (cs%id_def_rat_2 > 0)
then
230 is = g%isc-1 ; ie = g%iec+1 ; js = g%jsc-1 ; je = g%jec+1
234 i_dtol = 1.0 / max(cs%h_def_tol2 - cs%h_def_tol1, 1e-40)
235 i_dtol34 = 1.0 / max(cs%h_def_tol4 - cs%h_def_tol3, 1e-40)
237 p_ref_cv(:) = tv%P_Ref
239 do j=js-1,je+1 ;
do i=is-1,ie+1
242 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie+1
243 e(i,j,k+1) = e(i,j,k) - h(i,j,k)
244 enddo ;
enddo ;
enddo
247 call find_deficit_ratios(e, def_rat_u, def_rat_v, g, gv, cs, def_rat_u_1b, def_rat_v_1b, 1, h)
252 do j=js,je ; do_j(j) = .false. ;
enddo
253 do j=js,je ;
do i=is,ie
254 def_rat_h(i,j) = max(def_rat_u(i-1,j), def_rat_u(i,j), &
255 def_rat_v(i,j-1), def_rat_v(i,j))
256 if (def_rat_h(i,j) > cs%h_def_tol1) do_j(j) = .true.
260 if ((cs%id_def_rat_3 > 0) .or. (cs%id_e3 > 0) .or. &
261 (cs%id_def_rat_u_3 > 0) .or. (cs%id_def_rat_u_3b > 0) .or. &
262 (cs%id_def_rat_v_3 > 0) .or. (cs%id_def_rat_v_3b > 0) )
then
263 do j=js-1,je+1 ;
do i=is-1,ie+1
266 do k=2,nz+1 ;
do j=js,je ;
do i=is,ie
267 if (g%mask2dCu(i,j) <= 0.0)
then ; e_e = e(i,j,k) ;
else
268 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))
270 if (g%mask2dCu(i-1,j) <= 0.0)
then ; e_w = e(i,j,k) ;
else
271 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))
273 if (g%mask2dCv(i,j) <= 0.0)
then ; e_n = e(i,j,k) ;
else
274 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))
276 if (g%mask2dCv(i,j-1) <= 0.0)
then ; e_s = e(i,j,k) ;
else
277 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))
281 ef(i,j,k) = (1.0 - 0.5*wt) * e(i,j,k) + &
282 wt * 0.125 * ((e_e + e_w) + (e_n + e_s))
283 enddo ;
enddo ;
enddo
284 call find_deficit_ratios(ef, def_rat_u_3, def_rat_v_3, g, gv, cs, def_rat_u_3b, def_rat_v_3b)
287 do j=js,je ;
do i=is,ie
288 def_rat_h3(i,j) = max(def_rat_u_3(i-1,j), def_rat_u_3(i,j), &
289 def_rat_v_3(i,j-1), def_rat_v_3(i,j))
292 if (cs%id_e3 > 0)
call post_data(cs%id_e3, ef, cs%diag)
293 if (cs%id_def_rat_3 > 0)
call post_data(cs%id_def_rat_3, def_rat_h3, cs%diag)
294 if (cs%id_def_rat_u_3 > 0)
call post_data(cs%id_def_rat_u_3, def_rat_u_3, cs%diag)
295 if (cs%id_def_rat_u_3b > 0)
call post_data(cs%id_def_rat_u_3b, def_rat_u_3b, cs%diag)
296 if (cs%id_def_rat_v_3 > 0)
call post_data(cs%id_def_rat_v_3, def_rat_v_3, cs%diag)
297 if (cs%id_def_rat_v_3b > 0)
call post_data(cs%id_def_rat_v_3b, def_rat_v_3b, cs%diag)
317 do j=js,je ;
if (do_j(j))
then
324 do k=1,nz ;
do i=is,ie ; d_ea(i,k) = 0.0 ; d_eb(i,k) = 0.0 ;
enddo ;
enddo
328 do_i(i) = def_rat_h(i,j) > cs%h_def_tol1
329 if (def_rat_h(i,j) > max_def_rat) max_def_rat = def_rat_h(i,j)
331 nz_filt = nkmb+1 ;
if (max_def_rat > cs%h_def_tol3) nz_filt = nz+1
336 do k=1,nz_filt ;
do i=is,ie ;
if (do_i(i))
then
337 if (g%mask2dCu(i,j) <= 0.0)
then ; e_e = e(i,j,k) ;
else
338 e_e = max(e(i+1,j,k) + min(e(i,j,k) - e(i+1,j,nz+1), 0.0), &
339 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom_H)
342 if (g%mask2dCu(i-1,j) <= 0.0)
then ; e_w = e(i,j,k) ;
else
343 e_w = max(e(i-1,j,k) + min(e(i,j,k) - e(i-1,j,nz+1), 0.0), &
344 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom_H)
346 if (g%mask2dCv(i,j) <= 0.0)
then ; e_n = e(i,j,k) ;
else
347 e_n = max(e(i,j+1,k) + min(e(i,j,k) - e(i,j+1,nz+1), 0.0), &
348 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom_H)
350 if (g%mask2dCv(i,j-1) <= 0.0)
then ; e_s = e(i,j,k) ;
else
351 e_s = max(e(i,j-1,k) + min(e(i,j,k) - e(i,j-1,nz+1), 0.0), &
352 e(i,j,nz+1) + (nz+1-k)*gv%Angstrom_H)
355 wt = max(0.0, min(1.0, i_dtol*(def_rat_h(i,j)-cs%h_def_tol1)))
357 e_filt(i,k) = (1.0 - 0.5*wt) * e(i,j,k) + &
358 wt * 0.125 * ((e_e + e_w) + (e_n + e_s))
360 endif ;
enddo ;
enddo
361 do k=1,nz ;
do i=is,ie
363 t_2d(i,k) = tv%T(i,j,k) ; s_2d(i,k) = tv%S(i,j,k)
367 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then
368 h_2d_init(i,k) = h(i,j,k)
369 t_2d_init(i,k) = tv%T(i,j,k) ; s_2d_init(i,k) = tv%S(i,j,k)
370 endif ;
enddo ;
enddo
376 more_ent_i(i) = .false. ; ent_i(i) = .false.
377 h_add_tgt(i) = 0.0 ; h_add_tot(i) = 0.0
378 if (do_i(i) .and. (e_2d(i,nkmb+1) > e_filt(i,nkmb+1)))
then
379 more_ent_i(i) = .true. ; ent_i(i) = .true. ; ent_any = .true.
380 h_add_tgt(i) = e_2d(i,nkmb+1) - e_filt(i,nkmb+1)
387 do i=is,ie ;
if (more_ent_i(i))
then
388 if (h_2d(i,k) - gv%Angstrom_H > h_neglect)
then
389 if (e_2d(i,nkmb+1)-e_filt(i,nkmb+1) > h_2d(i,k) - gv%Angstrom_H)
then
390 h_add = h_2d(i,k) - gv%Angstrom_H
391 h_2d(i,k) = gv%Angstrom_H
393 h_add = e_2d(i,nkmb+1)-e_filt(i,nkmb+1)
394 h_2d(i,k) = h_2d(i,k) - h_add
396 d_eb(i,k-1) = d_eb(i,k-1) + h_add
397 h_add_tot(i) = h_add_tot(i) + h_add
398 e_2d(i,nkmb+1) = e_2d(i,nkmb+1) - h_add
399 h_prev = h_2d(i,nkmb)
400 h_2d(i,nkmb) = h_2d(i,nkmb) + h_add
402 t_2d(i,nkmb) = (h_prev*t_2d(i,nkmb) + h_add*t_2d(i,k)) / h_2d(i,nkmb)
403 s_2d(i,nkmb) = (h_prev*s_2d(i,nkmb) + h_add*s_2d(i,k)) / h_2d(i,nkmb)
405 if ((e_2d(i,nkmb+1) <= e_filt(i,nkmb+1)) .or. &
406 (h_add_tot(i) > 0.6*h_add_tgt(i)))
then
407 more_ent_i(i) = .false.
415 if (.not.cols_left)
exit
419 do k=ks,nkmb,-1 ;
do i=is,ie ;
if (ent_i(i))
then
420 d_eb(i,k) = d_eb(i,k) + d_eb(i,k+1)
421 endif ;
enddo ;
enddo
433 if ((max_def_rat > cs%h_def_tol3) .and. (cs%reg_sfc_detrain))
then
435 det_i(i) = .false. ; rcv_tol(i) = 0.0
436 if (do_i(i) .and. (e_2d(i,nkmb+1) < e_filt(i,nkmb+1)) .and. &
437 (def_rat_h(i,j) > cs%h_def_tol3))
then
438 det_i(i) = .true. ; det_any = .true.
439 rcv_tol(i) = min((def_rat_h(i,j) - cs%h_def_tol3), 1.0)
447 is,ie-is+1,tv%eqn_of_state, scale=us%kg_m3_to_R)
451 do i=is,ie ;
if (det_i(i))
then
458 rcv_min_det = (gv%Rlay(k2) + 0.6*rcv_tol(i)*(gv%Rlay(k2-1)-gv%Rlay(k2)))
460 rcv_max_det = (gv%Rlay(k2) + 0.6*rcv_tol(i)*(gv%Rlay(k2+1)-gv%Rlay(k2)))
462 rcv_max_det = (gv%Rlay(nz) + 0.6*rcv_tol(i)*(gv%Rlay(nz)-gv%Rlay(nz-1)))
464 if (rcv(i,k1) > rcv_max_det) &
467 h_deficit = (e_filt(i,k2)-e_filt(i,k2+1)) - h_2d(i,k2)
468 if ((e_filt(i,k2) > e_2d(i,k1+1)) .and. (h_deficit > 0.0) .and. &
469 (rcv(i,k1) < rcv_max_det) .and. (rcv(i,k1) > rcv_min_det))
then
471 h_add = min(e_filt(i,k2) - e_2d(i,k2), h_deficit )
472 if (h_add < h_2d(i,k1))
then
474 if (h_add > 0.0)
then
476 h_2d(i,k2) = h_2d(i,k2) + h_add
477 e_2d(i,k2) = e_2d(i,k2+1) + h_2d(i,k2)
478 d_ea(i,k2) = d_ea(i,k2) + h_add
480 t_2d(i,k2) = (h_prev*t_2d(i,k2) + h_add*t_2d(i,k1)) / h_2d(i,k2)
481 s_2d(i,k2) = (h_prev*s_2d(i,k2) + h_add*s_2d(i,k1)) / h_2d(i,k2)
482 h_det_tot = h_det_tot + h_add
484 h_2d(i,k1) = h_2d(i,k1) - h_add
485 do k3=k1,nkmb ; e_2d(i,k3+1) = e_2d(i,k3) - h_2d(i,k3) ;
enddo
486 do k3=k1+1,nkmb ; d_ea(i,k3) = d_ea(i,k3) + h_add ;
enddo
489 call mom_error(fatal,
"h_add is negative. Some logic is wrong.")
495 if (k2>nkmb+1) e_2d(i,k2) = e_2d(i,k2) + h_det_tot
499 h_2d(i,k2) = h_2d(i,k2) + h_add
500 e_2d(i,k2) = e_2d(i,k2+1) + h_2d(i,k2)
501 d_ea(i,k2) = d_ea(i,k2) + h_add
502 t_2d(i,k2) = (h_prev*t_2d(i,k2) + h_add*t_2d(i,k1)) / h_2d(i,k2)
503 s_2d(i,k2) = (h_prev*s_2d(i,k2) + h_add*s_2d(i,k1)) / h_2d(i,k2)
504 h_det_tot = h_det_tot + h_add
507 do k3=k1,nkmb ; e_2d(i,k3+1) = e_2d(i,k3) - h_2d(i,k3) ;
enddo
508 do k3=k1+1,nkmb ; d_ea(i,k3) = d_ea(i,k3) + h_add ;
enddo
517 if (k2>nkmb+1) e_2d(i,k2) = e_2d(i,k2) + h_det_tot
523 do k=nz-1,nkmb+1,-1 ;
do i=is,ie ;
if (det_i(i))
then
524 d_ea(i,k) = d_ea(i,k) + d_ea(i,k+1)
525 endif ;
enddo ;
enddo
528 do i=is,ie ; h_tot3(i) = 0.0 ; th_tot3(i) = 0.0 ; sh_tot3(i) = 0.0 ;
enddo
529 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then
530 h_tot3(i) = h_tot3(i) + h_2d(i,k)
531 th_tot3(i) = th_tot3(i) + h_2d(i,k) * t_2d(i,k)
532 sh_tot3(i) = sh_tot3(i) + h_2d(i,k) * s_2d(i,k)
533 endif ;
enddo ;
enddo
536 do i=is,ie ;
if (do_i(i))
then
539 scale = e_2d(i,nkmb+1) / e_filt(i,nkmb+1)
540 do k=2,nkmb+1 ; e_filt(i,k) = e_filt(i,k) * scale ;
enddo
544 if (e_filt(i,2) < e_2d(i,nkml))
then
545 scale = (e_2d(i,nkml) - e_filt(i,nkmb+1)) / &
546 ((e_filt(i,2) - e_filt(i,nkmb+1)) + h_neglect)
548 e_filt(i,k) = e_filt(i,nkmb+1) + scale * (e_filt(i,k) - e_filt(i,nkmb+1))
550 e_filt(i,2) = e_2d(i,nkml)
557 int_flux(k) = 0.0 ; int_rflux(k) = 0.0
558 int_tflux(k) = 0.0 ; int_sflux(k) = 0.0
561 int_bot = max(e_2d(i,k1+1),e_filt(i,k2+1))
562 h_add = int_top - int_bot
566 d_ea(i,k3) = d_ea(i,k3) + h_add
567 int_flux(k3) = int_flux(k3) + h_add
568 int_tflux(k3) = int_tflux(k3) + h_add*t_2d(i,k1)
569 int_sflux(k3) = int_sflux(k3) + h_add*s_2d(i,k1)
571 elseif (k1 > k2)
then
573 d_eb(i,k3) = d_eb(i,k3) + h_add
574 int_flux(k3+1) = int_flux(k3+1) - h_add
575 int_tflux(k3+1) = int_tflux(k3+1) - h_add*t_2d(i,k1)
576 int_sflux(k3+1) = int_sflux(k3+1) - h_add*s_2d(i,k1)
580 if (int_bot <= e_filt(i,k2+1))
then
583 elseif (int_bot <= e_2d(i,k1+1))
then
588 "Regularize_surface: Could not increment target or source.")
590 if ((k1 > nkmb) .or. (k2 > nkmb))
exit
594 call mom_error(fatal,
"Regularize_surface: Did not assign fluid to layer nkmb.")
598 do k=1,nkmb ; h_prev_1d(k) = h_2d(i,k) ;
enddo
599 h_2d(i,1) = h_2d(i,1) - int_flux(2)
601 h_2d(i,k) = h_2d(i,k) + (int_flux(k) - int_flux(k+1))
605 h_2d(i,nkmb) = h_2d(i,nkmb) + int_flux(nkmb)
607 t_2d(i,1) = (t_2d(i,1)*h_prev_1d(1) - int_tflux(2)) / h_2d(i,1)
608 s_2d(i,1) = (s_2d(i,1)*h_prev_1d(1) - int_sflux(2)) / h_2d(i,1)
610 t_2d(i,k) = (t_2d(i,k)*h_prev_1d(k) + (int_tflux(k) - int_tflux(k+1))) / h_2d(i,k)
611 s_2d(i,k) = (s_2d(i,k)*h_prev_1d(k) + (int_sflux(k) - int_sflux(k+1))) / h_2d(i,k)
613 t_2d(i,nkmb) = (t_2d(i,nkmb)*h_prev_1d(nkmb) + int_tflux(nkmb) ) / h_2d(i,nkmb)
614 s_2d(i,nkmb) = (s_2d(i,nkmb)*h_prev_1d(nkmb) + int_sflux(nkmb) ) / h_2d(i,nkmb)
619 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then
621 tv%T(i,j,k) = t_2d(i,k) ; tv%S(i,j,k) = s_2d(i,k)
622 ea(i,j,k) = ea(i,j,k) + d_ea(i,k)
623 eb(i,j,k) = eb(i,j,k) + d_eb(i,k)
624 endif ;
enddo ;
enddo
627 do i=is,ie ; h_tot1(i) = 0.0 ; th_tot1(i) = 0.0 ; sh_tot1(i) = 0.0 ;
enddo
628 do i=is,ie ; h_tot2(i) = 0.0 ; th_tot2(i) = 0.0 ; sh_tot2(i) = 0.0 ;
enddo
630 do k=1,nz ;
do i=is,ie ;
if (do_i(i))
then
631 h_tot1(i) = h_tot1(i) + h_2d_init(i,k)
632 h_tot2(i) = h_tot2(i) + h(i,j,k)
634 th_tot1(i) = th_tot1(i) + h_2d_init(i,k) * t_2d_init(i,k)
635 th_tot2(i) = th_tot2(i) + h(i,j,k) * tv%T(i,j,k)
636 sh_tot1(i) = sh_tot1(i) + h_2d_init(i,k) * s_2d_init(i,k)
637 sh_tot2(i) = sh_tot2(i) + h(i,j,k) * tv%S(i,j,k)
638 if (h(i,j,k) < 0.0) &
639 call mom_error(fatal,
"regularize_surface: Negative thicknesses.")
640 if (k==1)
then ; h_predicted = h_2d_init(i,k) + (d_eb(i,k) - d_ea(i,k+1))
641 elseif (k==nz)
then ; h_predicted = h_2d_init(i,k) + (d_ea(i,k) - d_eb(i,k-1))
643 h_predicted = h_2d_init(i,k) + ((d_ea(i,k) - d_eb(i,k-1)) + &
644 (d_eb(i,k) - d_ea(i,k+1)))
646 if (abs(h(i,j,k) - h_predicted) > max(1e-9*abs(h_predicted),gv%Angstrom_H)) &
647 call mom_error(fatal,
"regularize_surface: d_ea mismatch.")
648 endif ;
enddo ;
enddo
649 do i=is,ie ;
if (do_i(i))
then
650 fatal_error = .false.
651 if (abs(h_tot1(i) - h_tot2(i)) > 1e-12*h_tot1(i))
then
652 write(mesg,
'(ES11.4," became ",ES11.4," diff ",ES11.4)') &
653 h_tot1(i), h_tot2(i), (h_tot1(i) - h_tot2(i))
654 call mom_error(warning,
"regularize_surface: Mass non-conservation."//&
658 if (abs(th_tot1(i) - th_tot2(i)) > 1e-12*(th_tot1(i)+10.0*h_tot1(i)))
then
659 write(mesg,
'(ES11.4," became ",ES11.4," diff ",ES11.4," int diff ",ES11.4)') &
660 th_tot1(i), th_tot2(i), (th_tot1(i) - th_tot2(i)), (th_tot1(i) - th_tot3(i))
661 call mom_error(warning,
"regularize_surface: Heat non-conservation."//&
665 if (abs(sh_tot1(i) - sh_tot2(i)) > 1e-12*(sh_tot1(i)+10.0*h_tot1(i)))
then
666 write(mesg,
'(ES11.4," became ",ES11.4," diff ",ES11.4," int diff ",ES11.4)') &
667 sh_tot1(i), sh_tot2(i), (sh_tot1(i) - sh_tot2(i)), (sh_tot1(i) - sh_tot3(i))
668 call mom_error(warning,
"regularize_surface: Salinity non-conservation."//&
672 if (fatal_error)
then
673 write(mesg,
'("Error at lat/lon ",2(ES11.4))') g%geoLatT(i,j), g%geoLonT(i,j)
674 call mom_error(fatal,
"regularize_surface: Terminating with fatal error. "//&
682 if (cs%id_def_rat > 0)
call post_data(cs%id_def_rat, def_rat_h, cs%diag)
685 if (cs%id_e1 > 0)
call post_data(cs%id_e1, e, cs%diag)
686 if (cs%id_def_rat_u > 0)
call post_data(cs%id_def_rat_u, def_rat_u, cs%diag)
687 if (cs%id_def_rat_u_1b > 0)
call post_data(cs%id_def_rat_u_1b, def_rat_u_1b, cs%diag)
688 if (cs%id_def_rat_v > 0)
call post_data(cs%id_def_rat_v, def_rat_v, cs%diag)
689 if (cs%id_def_rat_v_1b > 0)
call post_data(cs%id_def_rat_v_1b, def_rat_v_1b, cs%diag)
691 if ((cs%id_def_rat_2 > 0) .or. &
692 (cs%id_def_rat_u_2 > 0) .or. (cs%id_def_rat_u_2b > 0) .or. &
693 (cs%id_def_rat_v_2 > 0) .or. (cs%id_def_rat_v_2b > 0) )
then
694 do j=js-1,je+1 ;
do i=is-1,ie+1
697 do k=1,nz ;
do j=js-1,je+1 ;
do i=is-1,ie+1
698 e(i,j,k+1) = e(i,j,k) - h(i,j,k)
699 enddo ;
enddo ;
enddo
701 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)
704 do j=js,je ;
do i=is,ie
705 def_rat_h2(i,j) = max(def_rat_u_2(i-1,j), def_rat_u_2(i,j), &
706 def_rat_v_2(i,j-1), def_rat_v_2(i,j))
709 if (cs%id_def_rat_2 > 0)
call post_data(cs%id_def_rat_2, def_rat_h2, cs%diag)
710 if (cs%id_e2 > 0)
call post_data(cs%id_e2, e, cs%diag)
711 if (cs%id_def_rat_u_2 > 0)
call post_data(cs%id_def_rat_u_2, def_rat_u_2, cs%diag)
712 if (cs%id_def_rat_u_2b > 0)
call post_data(cs%id_def_rat_u_2b, def_rat_u_2b, cs%diag)
713 if (cs%id_def_rat_v_2 > 0)
call post_data(cs%id_def_rat_v_2, def_rat_v_2, cs%diag)
714 if (cs%id_def_rat_v_2b > 0)
call post_data(cs%id_def_rat_v_2b, def_rat_v_2b, cs%diag)
725 def_rat_u_2lay, def_rat_v_2lay, halo, h)
728 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
730 real,
dimension(SZIB_(G),SZJ_(G)), &
731 intent(out) :: def_rat_u
733 real,
dimension(SZI_(G),SZJB_(G)), &
734 intent(out) :: def_rat_v
738 real,
dimension(SZIB_(G),SZJ_(G)), &
739 optional,
intent(out) :: def_rat_u_2lay
742 real,
dimension(SZI_(G),SZJB_(G)), &
743 optional,
intent(out) :: def_rat_v_2lay
746 integer,
optional,
intent(in) :: halo
747 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
748 optional,
intent(in) :: h
752 real,
dimension(SZIB_(G),SZJ_(G)) :: &
757 real,
dimension(SZI_(G),SZJB_(G)) :: &
766 integer :: i, j, k, is, ie, js, je, nz, nkmb
768 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
769 if (
present(halo))
then
770 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
772 nkmb = gv%nk_rho_varies
773 h_neglect = gv%H_subroundoff
774 hmix_min = cs%Hmix_min
777 do j=js,je ;
do i=is-1,ie
780 h1 = e(i,j,nkmb+1)-e(i,j,nz+1) ; h2 = e(i+1,j,nkmb+1)-e(i+1,j,nz+1)
781 if (e(i,j,nz+1) < e(i+1,j,nz+1))
then
782 if (h1 > h2) h1 = max(e(i,j,nkmb+1)-e(i+1,j,nz+1), h2)
783 elseif (e(i+1,j,nz+1) < e(i,j,nz+1))
then
784 if (h2 > h1) h2 = max(e(i+1,j,nkmb+1)-e(i,j,nz+1), h1)
786 h_def_u(i,j) = 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
787 h_norm_u(i,j) = 0.5*(h1+h2)
789 if (
present(def_rat_u_2lay))
then ;
do j=js,je ;
do i=is-1,ie
791 h1 = e(i,j,1)-e(i,j,nkmb+1) ; h2 = e(i+1,j,1)-e(i+1,j,nkmb+1)
792 if (e(i,j,nkmb+1) < e(i+1,j,nz+1))
then
793 if (h1 > h2) h1 = max(e(i,j,1)-e(i+1,j,nz+1), h2)
794 elseif (e(i+1,j,nkmb+1) < e(i,j,nz+1))
then
795 if (h2 > h1) h2 = max(e(i+1,j,1)-e(i,j,nz+1), h1)
797 h_def2_u(i,j) = h_def_u(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
798 enddo ;
enddo ;
endif
799 do k=1,nkmb ;
do j=js,je ;
do i=is-1,ie
801 h1 = h(i,j,k) ; h2 = h(i+1,j,k)
803 h1 = e(i,j,k)-e(i,j,k+1) ; h2 = e(i+1,j,k)-e(i+1,j,k+1)
807 if (e(i,j,k+1) < e(i+1,j,nz+1))
then
808 if (h1 > h2) h1 = max(e(i,j,k)-e(i+1,j,nz+1), h2)
809 elseif (e(i+1,j,k+1) < e(i,j,nz+1))
then
810 if (h2 > h1) h2 = max(e(i+1,j,k)-e(i,j,nz+1), h1)
812 h_def_u(i,j) = h_def_u(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
813 h_norm_u(i,j) = h_norm_u(i,j) + 0.5*(h1+h2)
814 enddo ;
enddo ;
enddo
815 if (
present(def_rat_u_2lay))
then ;
do j=js,je ;
do i=is-1,ie
816 def_rat_u(i,j) = g%mask2dCu(i,j) * h_def_u(i,j) / &
817 (max(hmix_min, h_norm_u(i,j)) + h_neglect)
818 def_rat_u_2lay(i,j) = g%mask2dCu(i,j) * h_def2_u(i,j) / &
819 (max(hmix_min, h_norm_u(i,j)) + h_neglect)
820 enddo ;
enddo ;
else ;
do j=js,je ;
do i=is-1,ie
821 def_rat_u(i,j) = g%mask2dCu(i,j) * h_def_u(i,j) / &
822 (max(hmix_min, h_norm_u(i,j)) + h_neglect)
823 enddo ;
enddo ;
endif
826 do j=js-1,je ;
do i=is,ie
829 h1 = e(i,j,nkmb+1)-e(i,j,nz+1) ; h2 = e(i,j+1,nkmb+1)-e(i,j+1,nz+1)
830 if (e(i,j,nz+1) < e(i,j+1,nz+1))
then
831 if (h1 > h2) h1 = max(e(i,j,nkmb+1)-e(i,j+1,nz+1), h2)
832 elseif (e(i,j+1,nz+1) < e(i,j,nz+1))
then
833 if (h2 > h1) h2 = max(e(i,j+1,nkmb+1)-e(i,j,nz+1), h1)
835 h_def_v(i,j) = 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
836 h_norm_v(i,j) = 0.5*(h1+h2)
838 if (
present(def_rat_v_2lay))
then ;
do j=js-1,je ;
do i=is,ie
840 h1 = e(i,j,1)-e(i,j,nkmb+1) ; h2 = e(i,j+1,1)-e(i,j+1,nkmb+1)
841 if (e(i,j,nkmb+1) < e(i,j+1,nz+1))
then
842 if (h1 > h2) h1 = max(e(i,j,1)-e(i,j+1,nz+1), h2)
843 elseif (e(i,j+1,nkmb+1) < e(i,j,nz+1))
then
844 if (h2 > h1) h2 = max(e(i,j+1,1)-e(i,j,nz+1), h1)
846 h_def2_v(i,j) = h_def_v(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
847 enddo ;
enddo ;
endif
848 do k=1,nkmb ;
do j=js-1,je ;
do i=is,ie
850 h1 = h(i,j,k) ; h2 = h(i,j+1,k)
852 h1 = e(i,j,k)-e(i,j,k+1) ; h2 = e(i,j+1,k)-e(i,j+1,k+1)
856 if (e(i,j,k+1) < e(i,j+1,nz+1))
then
857 if (h1 > h2) h1 = max(e(i,j,k)-e(i,j+1,nz+1), h2)
858 elseif (e(i,j+1,k+1) < e(i,j,nz+1))
then
859 if (h2 > h1) h2 = max(e(i,j+1,k)-e(i,j,nz+1), h1)
861 h_def_v(i,j) = h_def_v(i,j) + 0.5*(h1-h2)**2 / ((h1 + h2) + h_neglect)
862 h_norm_v(i,j) = h_norm_v(i,j) + 0.5*(h1+h2)
863 enddo ;
enddo ;
enddo
864 if (
present(def_rat_v_2lay))
then ;
do j=js-1,je ;
do i=is,ie
865 def_rat_v(i,j) = g%mask2dCv(i,j) * h_def_v(i,j) / &
866 (max(hmix_min, h_norm_v(i,j)) + h_neglect)
867 def_rat_v_2lay(i,j) = g%mask2dCv(i,j) * h_def2_v(i,j) / &
868 (max(hmix_min, h_norm_v(i,j)) + h_neglect)
869 enddo ;
enddo ;
else ;
do j=js-1,je ;
do i=is,ie
870 def_rat_v(i,j) = g%mask2dCv(i,j) * h_def_v(i,j) / &
871 (max(hmix_min, h_norm_v(i,j)) + h_neglect)
872 enddo ;
enddo ;
endif
878 type(time_type),
target,
intent(in) :: time
883 type(
diag_ctrl),
target,
intent(inout) :: diag
887 #include "version_variable.h"
888 character(len=40) :: mdl =
"MOM_regularize_layers"
889 logical :: use_temperature
890 integer :: isd, ied, jsd, jed
891 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
893 if (
associated(cs))
then
894 call mom_error(warning,
"regularize_layers_init called with an associated"// &
895 "associated control structure.")
897 else ;
allocate(cs) ;
endif
904 call get_param(param_file, mdl,
"REGULARIZE_SURFACE_LAYERS", cs%regularize_surface_layers, &
905 "If defined, vertically restructure the near-surface "//&
906 "layers when they have too much lateral variations to "//&
907 "allow for sensible lateral barotropic transports.", &
909 if (cs%regularize_surface_layers)
then
910 call get_param(param_file, mdl,
"REGULARIZE_SURFACE_DETRAIN", cs%reg_sfc_detrain, &
911 "If true, allow the buffer layers to detrain into the "//&
912 "interior as a part of the restructuring when "//&
913 "REGULARIZE_SURFACE_LAYERS is true.", default=.true.)
916 call get_param(param_file, mdl,
"HMIX_MIN", cs%Hmix_min, &
917 "The minimum mixed layer depth if the mixed layer depth "//&
918 "is determined dynamically.", units=
"m", default=0.0, scale=gv%m_to_H)
919 call get_param(param_file, mdl,
"REG_SFC_DEFICIT_TOLERANCE", cs%h_def_tol1, &
920 "The value of the relative thickness deficit at which "//&
921 "to start modifying the layer structure when "//&
922 "REGULARIZE_SURFACE_LAYERS is true.", units=
"nondim", &
924 cs%h_def_tol2 = 0.2 + 0.8*cs%h_def_tol1
925 cs%h_def_tol3 = 0.3 + 0.7*cs%h_def_tol1
926 cs%h_def_tol4 = 0.5 + 0.5*cs%h_def_tol1
928 call get_param(param_file, mdl,
"DEBUG", cs%debug, default=.false.)
933 call get_param(param_file, mdl,
"ALLOW_CLOCKS_IN_OMP_LOOPS", cs%allow_clocks_in_omp_loops, &
934 "If true, clocks can be called from inside loops that can "//&
935 "be threaded. To run with multiple threads, set to False.", &
938 cs%id_def_rat = register_diag_field(
'ocean_model',
'deficit_ratio', diag%axesT1, &
939 time,
'Max face thickness deficit ratio',
'nondim')
942 cs%id_def_rat_2 = register_diag_field(
'ocean_model',
'deficit_rat2', diag%axesT1, &
943 time,
'Corrected thickness deficit ratio',
'nondim')
944 cs%id_def_rat_3 = register_diag_field(
'ocean_model',
'deficit_rat3', diag%axesT1, &
945 time,
'Filtered thickness deficit ratio',
'nondim')
946 cs%id_e1 = register_diag_field(
'ocean_model',
'er_1', diag%axesTi, &
947 time,
'Intial interface depths before remapping',
'm')
948 cs%id_e2 = register_diag_field(
'ocean_model',
'er_2', diag%axesTi, &
949 time,
'Intial interface depths after remapping',
'm')
950 cs%id_e3 = register_diag_field(
'ocean_model',
'er_3', diag%axesTi, &
951 time,
'Intial interface depths filtered',
'm')
953 cs%id_def_rat_u = register_diag_field(
'ocean_model',
'defrat_u', diag%axesCu1, &
954 time,
'U-point thickness deficit ratio',
'nondim')
955 cs%id_def_rat_u_1b = register_diag_field(
'ocean_model',
'defrat_u_1b', diag%axesCu1, &
956 time,
'U-point 2-layer thickness deficit ratio',
'nondim')
957 cs%id_def_rat_u_2 = register_diag_field(
'ocean_model',
'defrat_u_2', diag%axesCu1, &
958 time,
'U-point corrected thickness deficit ratio',
'nondim')
959 cs%id_def_rat_u_2b = register_diag_field(
'ocean_model',
'defrat_u_2b', diag%axesCu1, &
960 time,
'U-point corrected 2-layer thickness deficit ratio',
'nondim')
961 cs%id_def_rat_u_3 = register_diag_field(
'ocean_model',
'defrat_u_3', diag%axesCu1, &
962 time,
'U-point filtered thickness deficit ratio',
'nondim')
963 cs%id_def_rat_u_3b = register_diag_field(
'ocean_model',
'defrat_u_3b', diag%axesCu1, &
964 time,
'U-point filtered 2-layer thickness deficit ratio',
'nondim')
966 cs%id_def_rat_v = register_diag_field(
'ocean_model',
'defrat_v', diag%axesCv1, &
967 time,
'V-point thickness deficit ratio',
'nondim')
968 cs%id_def_rat_v_1b = register_diag_field(
'ocean_model',
'defrat_v_1b', diag%axesCv1, &
969 time,
'V-point 2-layer thickness deficit ratio',
'nondim')
970 cs%id_def_rat_v_2 = register_diag_field(
'ocean_model',
'defrat_v_2', diag%axesCv1, &
971 time,
'V-point corrected thickness deficit ratio',
'nondim')
972 cs%id_def_rat_v_2b = register_diag_field(
'ocean_model',
'defrat_v_2b', diag%axesCv1, &
973 time,
'V-point corrected 2-layer thickness deficit ratio',
'nondim')
974 cs%id_def_rat_v_3 = register_diag_field(
'ocean_model',
'defrat_v_3', diag%axesCv1, &
975 time,
'V-point filtered thickness deficit ratio',
'nondim')
976 cs%id_def_rat_v_3b = register_diag_field(
'ocean_model',
'defrat_v_3b', diag%axesCv1, &
977 time,
'V-point filtered 2-layer thickness deficit ratio',
'nondim')
980 if (cs%allow_clocks_in_omp_loops)
then
981 id_clock_eos = cpu_clock_id(
'(Ocean regularize_layers EOS)', grain=clock_routine)
983 id_clock_pass = cpu_clock_id(
'(Ocean regularize_layers halo updates)', grain=clock_routine)