17 implicit none ;
private
19 #include <MOM_memory.h>
21 public entrainment_diffusive, entrain_diffusive_init, entrain_diffusive_end
30 logical :: bulkmixedlayer
32 logical :: correct_density
41 integer :: id_diff_work = -1
51 subroutine entrainment_diffusive(h, tv, fluxes, dt, G, GV, US, CS, ea, eb, &
52 kb_out, Kd_Lay, Kd_int)
56 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
61 type(
forcing),
intent(in) :: fluxes
63 real,
intent(in) :: dt
66 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
69 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
72 integer,
dimension(SZI_(G),SZJ_(G)), &
73 optional,
intent(inout) :: kb_out
76 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
77 optional,
intent(in) :: kd_lay
79 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
80 optional,
intent(in) :: kd_int
89 real,
dimension(SZI_(G),SZK_(G)) :: &
91 real,
dimension(SZI_(G),SZK_(G)+1) :: &
93 real,
dimension(SZI_(G),SZK_(G)) :: &
106 real,
dimension(SZI_(G),SZK_(G)+1) :: &
109 real,
allocatable,
dimension(:,:,:) :: &
116 real :: hm, fm, fr, fk
119 real :: c1(szi_(g),szk_(g))
121 real,
dimension(SZI_(G)) :: &
152 real,
dimension(SZI_(G),SZK_(G)) :: &
160 real,
dimension(SZI_(G),SZK_(G)) :: &
175 real,
dimension(SZI_(G)) :: &
199 logical :: do_i(szi_(g)), did_i(szi_(g)), reiterate, correct_density
200 integer :: it, i, j, k, is, ie, js, je, nz, k2, kmb
201 integer :: kb(szi_(g))
203 integer :: kb_min_act
205 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
206 angstrom = gv%Angstrom_H
207 h_neglect = gv%H_subroundoff
209 if (.not.
associated(cs))
call mom_error(fatal, &
210 "MOM_entrain_diffusive: Module must be initialized before it is used.")
212 if (.not.(
present(kd_lay) .or.
present(kd_int)))
call mom_error(fatal, &
213 "MOM_entrain_diffusive: Either Kd_Lay or Kd_int must be present in call.")
215 if ((.not.cs%bulkmixedlayer .and. .not.
associated(fluxes%buoy)) .and. &
216 (
associated(fluxes%lprec) .or.
associated(fluxes%evap) .or. &
217 associated(fluxes%sens) .or.
associated(fluxes%sw)))
then
218 if (is_root_pe())
call mom_error(note,
"Calculate_Entrainment: &
219 &The code to handle evaporation and precipitation without &
220 &a bulk mixed layer has not been implemented.")
221 if (is_root_pe())
call mom_error(fatal, &
222 "Either define BULKMIXEDLAYER in MOM_input or use fluxes%buoy &
223 &and a linear equation of state to drive the model.")
226 tolerance = cs%Tolerance_Ent
227 kmb = gv%nk_rho_varies
228 k2 = max(kmb+1,2) ; kb_min = k2
229 if (.not. cs%bulkmixedlayer)
then
233 do i=is,ie ; ds_dsp1(i,nz) = 2.0 ; dsp1_ds(i,nz) = 0.5 ;
enddo
236 do i=is,ie ; ds_dsp1(i,nz) = 0.0 ; dsp1_ds(i,nz) = 0.0 ;
enddo
239 if (cs%id_diff_work > 0)
allocate(diff_work(g%isd:g%ied,g%jsd:g%jed,nz+1))
240 if (cs%id_Kd > 0)
allocate(kd_eff(g%isd:g%ied,g%jsd:g%jed,nz))
242 correct_density = (cs%correct_density .and.
associated(tv%eqn_of_state))
243 if (correct_density)
then
266 do i=is,ie ; kb(i) = 1 ;
enddo
268 if (
present(kd_lay))
then
269 do k=1,nz ;
do i=is,ie
270 dtkd(i,k) = gv%Z_to_H**2 * (dt * kd_lay(i,j,k))
272 if (
present(kd_int))
then
273 do k=1,nz+1 ;
do i=is,ie
274 dtkd_int(i,k) = gv%Z_to_H**2 * (dt * kd_int(i,j,k))
277 do k=2,nz ;
do i=is,ie
278 dtkd_int(i,k) = gv%Z_to_H**2 * (0.5 * dt * (kd_lay(i,j,k-1) + kd_lay(i,j,k)))
282 do k=1,nz ;
do i=is,ie
283 dtkd(i,k) = gv%Z_to_H**2 * (0.5 * dt * (kd_int(i,j,k)+kd_int(i,j,k+1)))
285 dO k=1,nz+1 ;
do i=is,ie
286 dtkd_int(i,k) = gv%Z_to_H**2 * (dt * kd_int(i,j,k))
290 do i=is,ie ; do_i(i) = (g%mask2dT(i,j) > 0.5) ;
enddo
291 do i=is,ie ; ds_dsp1(i,nz) = 0.0 ;
enddo
292 do i=is,ie ; dsp1_ds(i,nz) = 0.0 ;
enddo
294 do k=2,nz-1 ;
do i=is,ie
295 ds_dsp1(i,k) = gv%g_prime(k) / gv%g_prime(k+1)
298 if (cs%bulkmixedlayer)
then
302 call set_ent_bl(h, dtkd_int, tv, kb, kmb, do_i, g, gv, cs, j, ent_bl, sref, h_bl)
305 dtkd_kb(i) = 0.0 ;
if (kb(i) < nz) dtkd_kb(i) = dtkd(i,kb(i))
308 do i=is,ie ; ent_bl(i,kmb+1) = 0.0 ;
enddo
311 do k=2,nz-1 ;
do i=is,ie
312 dsp1_ds(i,k) = 1.0 / ds_dsp1(i,k)
313 i2p2dsp1_ds(i,k) = 0.5/(1.0+dsp1_ds(i,k))
314 grats(i,k) = 2.0*(2.0+(dsp1_ds(i,k)+ds_dsp1(i,k)))
320 if (cs%bulkmixedlayer)
then
323 htot(i) = h(i,j,1) - angstrom
325 do k=2,kmb ;
do i=is,ie
326 htot(i) = htot(i) + (h(i,j,k) - angstrom)
329 max_eakb(i) = max(ent_bl(i,kmb+1) + 0.5*htot(i), htot(i))
330 i_dskbp1(i) = 1.0 / (sref(i,kmb+2) - sref(i,kmb+1))
338 call find_maxf_kb(h_bl, sref, ent_bl, i_dskbp1, zeros, max_eakb, kmb, &
339 is, ie, g, gv, cs, maxf_kb, eakb_maxf, do_i, f_kb_maxent)
340 do i=is,ie ;
if (kb(i) <= nz)
then
341 maxf(i,kb(i)) = max(0.0, maxf_kb(i), f_kb_maxent(i))
342 if ((maxf_kb(i) > f_kb_maxent(i)) .and. (eakb_maxf(i) >= htot(i))) &
343 max_eakb(i) = eakb_maxf(i)
346 do i=is,ie ; ea_kbp1(i) = 0.0 ; eakb(i) = max_eakb(i) ;
enddo
347 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, &
348 max_eakb, max_eakb, kmb, is, ie, do_i, g, gv, cs, eakb, &
349 error=err_max_eakb0, f_kb=f_kb)
353 do i=is,ie ; min_eakb(i) = min(htot(i), max_eakb(i)) ;
enddo
354 call find_maxf_kb(h_bl, sref, ent_bl, i_dskbp1, min_eakb, max_eakb, &
355 kmb, is, ie, g, gv, cs, f_kb_maxent, do_i_in = do_i)
358 if ((.not.do_i(i)) .or. (err_max_eakb0(i) >= 0.0))
then
359 eakb(i) = 0.0 ; min_eakb(i) = 0.0
361 eakb(i) = max_eakb(i) ; min_eakb(i) = max_eakb(i)
368 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, &
369 zeros, max_eakb, kmb, is, ie, do_i, g, gv, cs, min_eakb, &
370 error=err_min_eakb0, f_kb=f_kb, err_max_eakb0=err_max_eakb0)
372 do i=is,ie ;
if ((kb(i)<nz) .and. (kb_min>kb(i))) kb_min = kb(i) ;
enddo
381 htot(i) = h(i,j,1) - angstrom
383 if (
associated(fluxes%buoy))
then ;
do i=is,ie
384 maxf(i,1) = (dt*fluxes%buoy(i,j)) / (gv%g_prime(2)*us%m_to_Z)
390 do k=kb_min,nz-1 ;
do i=is,ie
391 if ((k == kb(i)+1) .and. cs%bulkmixedlayer)
then
392 maxf(i,k) = ds_dsp1(i,k)*(f_kb_maxent(i) + htot(i))
393 htot(i) = htot(i) + (h(i,j,k) - angstrom)
394 elseif (k > kb(i))
then
395 maxf(i,k) = ds_dsp1(i,k)*(maxf(i,k-1) + htot(i))
396 htot(i) = htot(i) + (h(i,j,k) - angstrom)
401 if (.not.cs%bulkmixedlayer)
then
402 maxf_correct(i) = max(0.0, -(maxf(i,nz-1) + htot(i)))
404 htot(i) = h(i,j,nz) - angstrom
406 if (.not.cs%bulkmixedlayer)
then
407 do_any = .false. ;
do i=is,ie ;
if (maxf_correct(i) > 0.0) do_any = .true. ;
enddo
409 do k=nz-1,1,-1 ;
do i=is,ie
410 maxf(i,k) = maxf(i,k) + maxf_correct(i)
411 maxf_correct(i) = maxf_correct(i) * dsp1_ds(i,k)
415 do k=nz-1,kb_min,-1 ;
do i=is,ie ;
if (do_i(i))
then
417 maxf(i,k) = min(maxf(i,k),dsp1_ds(i,k+1)*maxf(i,k+1) + htot(i))
418 htot(i) = htot(i) + (h(i,j,k) - angstrom)
419 if ( (k == kb(i)) .and. ((maxf(i,k) < f_kb(i)) .or. &
420 (maxf(i,k) < maxf_kb(i)) .and. (eakb_maxf(i) <= max_eakb(i))) )
then
425 if ((f_kb(i) <= maxf_kb(i)) .and. (eakb_maxf(i) <= max_eakb(i)))
then
426 eakb(i) = eakb_maxf(i)
428 eakb(i) = max_eakb(i)
430 call f_kb_to_ea_kb(h_bl, sref, ent_bl, i_dskbp1, f_kb, kmb, i, &
431 g, gv, cs, eakb, angstrom)
432 if ((eakb(i) < max_eakb(i)) .or. (eakb(i) < min_eakb(i)))
then
433 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, zeros, &
434 eakb, eakb, kmb, i, i, do_i, g, gv, cs, eakb, &
436 if (eakb(i) < max_eakb(i))
then
437 max_eakb(i) = eakb(i) ; err_max_eakb0(i) = err_eakb0(i)
439 if (eakb(i) < min_eakb(i))
then
440 min_eakb(i) = eakb(i) ; err_min_eakb0(i) = err_eakb0(i)
445 endif ;
enddo ;
enddo
446 if (.not.cs%bulkmixedlayer)
then
448 maxf(i,1) = min(maxf(i,1),dsp1_ds(i,2)*maxf(i,2) + htot(i))
459 f(i,nz) = maxf(i,nz) ; minf(i,nz) = 0.0
463 if ((k==kb(i)) .and. (do_i(i)))
then
464 eakb(i) = min_eakb(i)
466 elseif ((k>kb(i)) .and. (do_i(i)))
then
471 hm = h(i,j,k) + h_neglect
474 f(i,k) = min(maxf(i,k), sqrt(ds_dsp1(i,k)*dtkd(i,k)), &
475 0.5*(ds_dsp1(i,k)+1.0) * (dtkd(i,k) / hm))
480 fk = dtkd(i,k) * grats(i,k)
481 minf(i,k) = min(maxf(i,k), &
482 0.9*(i2p2dsp1_ds(i,k) * fk / (hm + sqrt(hm*hm + fk))))
483 if (k==kb(i)) minf(i,k) = 0.0
493 is1 = ie+1 ; ie1 = is-1
494 do i=is,ie ;
if (do_i(i))
then ; is1 = i ;
exit ;
endif ;
enddo
495 do i=ie,is,-1 ;
if (do_i(i))
then ; ie1 = i ;
exit ;
endif ;
enddo
497 if (cs%bulkmixedlayer)
then
500 if (do_i(i) .and. (kb(i) < kb_min_act)) kb_min_act = kb(i)
507 if (do_i(i) .and. (kb(i) < nz)) &
508 ea_kbp1(i) = dsp1_ds(i,kb(i)+1)*f(i,kb(i)+1)
510 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, min_eakb, &
511 max_eakb, kmb, is1, ie1, do_i, g, gv, cs, eakb, f_kb=f_kb, &
512 err_max_eakb0=err_max_eakb0, err_min_eakb0=err_min_eakb0, &
518 do it=0,cs%max_ent_it-1
519 do i=is1,ie1 ;
if (do_i(i))
then
520 if (.not.cs%bulkmixedlayer) f(i,1) = min(f(i,1),maxf(i,1))
526 do k=kb_min_act,nz-1 ;
do i=is1,ie1 ;
if (do_i(i) .and. (k>=kb(i)))
then
528 if (cs%bulkmixedlayer .and. (k==kb(i)))
then
530 dfdfm(i,k) = dfdfm_kb(i)
533 fm = (f(i,k-1) - h(i,j,k)) + dsp1_ds(i,k+1)*f(i,k+1)
534 fk = grats(i,k)*dtkd(i,k)
535 fr = sqrt(fm*fm + fk)
538 f(i,k) = min(maxf(i,k), i2p2dsp1_ds(i,k) * (fm+fr))
540 f(i,k) = min(maxf(i,k), i2p2dsp1_ds(i,k) * (fk / (-1.0*fm+fr)))
543 if ((f(i,k) >= maxf(i,k)) .or. (fr == 0.0))
then
546 dfdfm(i,k) = i2p2dsp1_ds(i,k) * ((fr + fm) / fr)
551 c1(i,k) = dfdfm(i,k-1)*(dsp1_ds(i,k)*b1(i))
552 b1(i) = 1.0 / (1.0 - c1(i,k)*dfdfm(i,k))
553 f(i,k) = min(b1(i)*(f(i,k)-fprev(i,k)) + fprev(i,k), maxf(i,k))
554 if (f(i,k) >= maxf(i,k)) dfdfm(i,k) = 0.0
557 endif ;
enddo ;
enddo
559 do k=nz-2,kb_min_act,-1 ;
do i=is1,ie1
560 if (do_i(i) .and. (k > kb(i))) &
561 f(i,k) = min((f(i,k)+c1(i,k+1)*(f(i,k+1)-fprev(i,k+1))),maxf(i,k))
564 if (cs%bulkmixedlayer)
then
566 if (do_i(i) .and. (kb(i) < nz))
then
568 ea_kbp1(i) = dsp1_ds(i,kb(i)+1)*max(f(i,kb(i)+1), minf(i,kb(i)+1))
573 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, min_eakb, &
574 max_eakb, kmb, is1, ie1, do_i, g, gv, cs, eakb, f_kb=f_kb, &
575 err_max_eakb0=err_max_eakb0, err_min_eakb0=err_min_eakb0, &
578 if (do_i(i) .and. (kb(i) < nz)) f(i,kb(i)) = f_kb(i)
583 if (it < cs%max_ent_it-1)
then
586 if (cs%bulkmixedlayer)
then ;
do i=is1,ie1 ;
if (do_i(i))
then
587 eb_kmb(i) = max(2.0*ent_bl(i,kmb+1) - eakb(i), 0.0)
588 endif ;
enddo ;
endif
590 did_i(i) = do_i(i) ; do_i(i) = .false.
592 do k=kb_min_act,nz-1 ;
do i=is1,ie1
593 if (did_i(i) .and. (k >= kb(i)))
then
594 if (f(i,k) < minf(i,k))
then
596 do_i(i) = .true. ; reiterate = .true.
597 elseif (k > kb(i))
then
598 if ((abs(f(i,k) - fprev(i,k)) > tolerance) .or. &
599 ((h(i,j,k) + ((1.0+dsp1_ds(i,k))*f(i,k) - &
600 (f(i,k-1) + dsp1_ds(i,k+1)*f(i,k+1)))) < 0.9*angstrom))
then
601 do_i(i) = .true. ; reiterate = .true.
607 if (h(i,j,k) + ((f(i,k) + eakb(i)) - &
608 (eb_kmb(i) + dsp1_ds(i,k+1)*f(i,k+1))) < 0.9*angstrom)
then
609 do_i(i) = .true. ; reiterate = .true.
614 if (.not.reiterate)
exit
620 if (it == (cs%max_ent_it))
then
623 do i=is1,ie1 ;
if (do_i(i))
then
624 f(i,nz-1) = max(f(i,nz-1), min(minf(i,nz-1), 0.0))
625 if (kb(i) >= nz-1)
then ; ea_kbp1(i) = 0.0 ;
endif
627 do k=nz-2,kb_min_act,-1 ;
do i=is1,ie1 ;
if (do_i(i))
then
629 f(i,k) = min(max(minf(i,k),f(i,k)), (dsp1_ds(i,k+1)*f(i,k+1) + &
630 max(((f(i,k+1)-dsp1_ds(i,k+2)*f(i,k+2)) + &
631 (h(i,j,k+1) - angstrom)), 0.5*(h(i,j,k+1)-angstrom))))
632 elseif (k==kb(i))
then
633 ea_kbp1(i) = dsp1_ds(i,k+1)*f(i,k+1)
634 h_avail = dsp1_ds(i,k+1)*f(i,k+1) + max(0.5*(h(i,j,k+1)-angstrom), &
635 ((f(i,k+1)-dsp1_ds(i,k+2)*f(i,k+2)) + (h(i,j,k+1) - angstrom)))
636 if ((f(i,k) > 0.0) .and. (f(i,k) > h_avail))
then
637 f_kb(i) = max(0.0, h_avail)
639 if ((f_kb(i) < maxf_kb(i)) .and. (eakb_maxf(i) <= eakb(i))) &
640 eakb(i) = eakb_maxf(i)
641 call f_kb_to_ea_kb(h_bl, sref, ent_bl, i_dskbp1, f_kb, kmb, i, &
645 endif ;
enddo ;
enddo
648 if (cs%bulkmixedlayer)
then ;
do i=is1,ie1
649 if (do_i(i) .and. (kb(i) < nz))
then
650 h_avail = eakb(i) + max(0.5*(h_bl(i,kmb+1)-angstrom), &
651 (f_kb(i)-ea_kbp1(i)) + (h_bl(i,kmb+1)-angstrom))
653 ent_bl(i,kmb+1) = min(ent_bl(i,kmb+1),0.5*(eakb(i) + h_avail))
655 eb_kmb(i) = max(2.0*ent_bl(i,kmb+1) - eakb(i), 0.0)
660 do k=kb_min_act+1,nz-1 ;
do i=is1,ie1 ;
if (do_i(i))
then
661 if ((.not.cs%bulkmixedlayer) .or. (k > kb(i)+1))
then
662 f(i,k) = min(f(i,k), ds_dsp1(i,k)*( ((f(i,k-1) + &
663 dsp1_ds(i,k-1)*f(i,k-1)) - f(i,k-2)) + (h(i,j,k-1) - angstrom)))
664 f(i,k) = max(f(i,k),min(minf(i,k),0.0))
665 elseif (k == kb(i)+1)
then
666 f(i,k) = min(f(i,k), ds_dsp1(i,k)*( ((f(i,k-1) + eakb(i)) - &
667 eb_kmb(i)) + (h(i,j,k-1) - angstrom)))
668 f(i,k) = max(f(i,k),min(minf(i,k),0.0))
670 endif ;
enddo ;
enddo
673 call f_to_ent(f, h, kb, kmb, j, g, gv, cs, dsp1_ds, eakb, ent_bl, ea, eb)
677 if (correct_density)
then
679 h_guess(i,1) = (h(i,j,1) - angstrom) + (eb(i,j,1) - ea(i,j,2))
680 h_guess(i,nz) = (h(i,j,nz) - angstrom) + (ea(i,j,nz) - eb(i,j,nz-1))
681 if (h_guess(i,1) < 0.0) h_guess(i,1) = 0.0
682 if (h_guess(i,nz) < 0.0) h_guess(i,nz) = 0.0
684 do k=2,nz-1 ;
do i=is,ie
685 h_guess(i,k) = (h(i,j,k) - angstrom) + ((ea(i,j,k) - eb(i,j,k-1)) + &
686 (eb(i,j,k) - ea(i,j,k+1)))
687 if (h_guess(i,k) < 0.0) h_guess(i,k) = 0.0
689 if (cs%bulkmixedlayer)
then
690 call determine_dskb(h_bl, sref, ent_bl, eakb, is, ie, kmb, g, gv, &
691 .true., ds_kb, ds_anom_lim=ds_anom_lim)
694 rcv(is:ie), 1, ie-is+1, tv%eqn_of_state)
696 if ((k>kb(i)) .and. (f(i,k) > 0.0))
then
703 f_cor = h(i,j,k) * min(1.0 , max(-ds_dsp1(i,k), &
704 (gv%Rlay(k) - rcv(i)) / (gv%Rlay(k+1)-gv%Rlay(k))) )
710 if (f_cor > 0.0)
then
711 f_cor = min(f_cor, 0.9*f(i,k), ds_dsp1(i,k)*0.5*h_guess(i,k), &
714 f_cor = -min(-f_cor, 0.9*f(i,k), 0.5*h_guess(i,k), &
715 0.25*ds_dsp1(i,k)*h_guess(i,k-1) )
718 ea(i,j,k) = ea(i,j,k) - dsp1_ds(i,k)*f_cor
719 eb(i,j,k) = eb(i,j,k) + f_cor
720 elseif ((k==kb(i)) .and. (f(i,k) > 0.0))
then
724 ds_kb_eff = 2.0*ds_kb(i) - ds_anom_lim(i)
725 rho_cor = h(i,j,k) * (gv%Rlay(k)-rcv(i)) + eakb(i)*ds_anom_lim(i)
728 if (abs(rho_cor) < abs(0.9*eakb(i)*ds_kb_eff))
then
729 ea_cor = -rho_cor / ds_kb_eff
731 ea_cor = sign(0.9*eakb(i),-rho_cor*ds_kb_eff)
734 if (ea_cor > 0.0)
then
736 ea_cor = min(ea_cor, 0.5*(max_eakb(i) - eakb(i)), &
737 0.5*h_guess(i,k) / (ds_kb(i) * i_dskbp1(i)))
740 ea_cor = -min(-ea_cor, 0.5*h_guess(i,k), &
741 0.25*h_guess(i,k+1) / (ds_kb(i) * i_dskbp1(i)))
744 ea(i,j,k) = ea(i,j,k) + ea_cor
745 eb(i,j,k) = eb(i,j,k) - (ds_kb(i) * i_dskbp1(i)) * ea_cor
746 elseif (k < kb(i))
then
748 ea(i,j,k) = ea(i,j,k+1)
752 do k=kb_min-1,k2,-1 ;
do i=is,ie
753 ea(i,j,k) = ea(i,j,k+1)
761 h1 = (h(i,j,k) - angstrom) + (eb(i,j,k) - ea(i,j,k+1))
762 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
764 do k=kmb-1,2,-1 ;
do i=is,ie
766 eb(i,j,k) = max(2.0*ent_bl(i,k+1) - ea(i,j,k+1), 0.0)
769 h1 = (h(i,j,k) - angstrom) + (eb(i,j,k) - ea(i,j,k+1))
770 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
773 eb(i,j,1) = max(2.0*ent_bl(i,2) - ea(i,j,2), 0.0)
779 rcv(is:ie), 1, ie-is+1, tv%eqn_of_state)
780 do i=is,ie ;
if (f(i,k) > 0.0)
then
785 f_cor = h(i,j,k) * min(dsp1_ds(i,k) , max(-1.0, &
786 (gv%Rlay(k) - rcv(i)) / (gv%Rlay(k+1)-gv%Rlay(k))) )
792 if (f_cor >= 0.0)
then
793 f_cor = min(f_cor, 0.9*f(i,k), 0.5*dsp1_ds(i,k)*h_guess(i,k), &
796 f_cor = -min(-f_cor, 0.9*f(i,k), 0.5*h_guess(i,k), &
797 0.25*ds_dsp1(i,k)*h_guess(i,k-1) )
800 ea(i,j,k) = ea(i,j,k) - dsp1_ds(i,k)*f_cor
801 eb(i,j,k) = eb(i,j,k) + f_cor
808 if (cs%id_Kd > 0)
then
809 idt = gv%H_to_Z**2 / dt
810 do k=2,nz-1 ;
do i=is,ie
811 if (k<kb(i))
then ; kd_here = 0.0 ;
else
812 kd_here = f(i,k) * ( h(i,j,k) + ((ea(i,j,k) - eb(i,j,k-1)) + &
813 (eb(i,j,k) - ea(i,j,k+1))) ) / (i2p2dsp1_ds(i,k) * grats(i,k))
816 kd_eff(i,j,k) = max(dtkd(i,k), kd_here)*idt
819 kd_eff(i,j,1) = dtkd(i,1)*idt
820 kd_eff(i,j,nz) = dtkd(i,nz)*idt
824 if (cs%id_diff_work > 0)
then
825 g_2dt = 0.5 * gv%H_to_Z**2*us%L_to_Z**2 * (gv%g_Earth / dt)
826 do i=is,ie ; diff_work(i,j,1) = 0.0 ; diff_work(i,j,nz+1) = 0.0 ;
enddo
827 if (
associated(tv%eqn_of_state))
then
828 if (
associated(fluxes%p_surf))
then
829 do i=is,ie ; pressure(i) = fluxes%p_surf(i,j) ;
enddo
831 do i=is,ie ; pressure(i) = 0.0 ;
enddo
834 do i=is,ie ; pressure(i) = pressure(i) + gv%H_to_Pa*h(i,j,k-1) ;
enddo
837 t_eos(i) = 0.5*(tv%T(i,j,kmb) + tv%T(i,j,k))
838 s_eos(i) = 0.5*(tv%S(i,j,kmb) + tv%S(i,j,k))
840 t_eos(i) = 0.5*(tv%T(i,j,k-1) + tv%T(i,j,k))
841 s_eos(i) = 0.5*(tv%S(i,j,k-1) + tv%S(i,j,k))
845 drho_dt, drho_ds, is, ie-is+1, tv%eqn_of_state)
847 if ((k>kmb) .and. (k<kb(i)))
then ; diff_work(i,j,k) = 0.0
850 drho = drho_dt(i) * (tv%T(i,j,k)-tv%T(i,j,kmb)) + &
851 drho_ds(i) * (tv%S(i,j,k)-tv%S(i,j,kmb))
853 drho = drho_dt(i) * (tv%T(i,j,k)-tv%T(i,j,k-1)) + &
854 drho_ds(i) * (tv%S(i,j,k)-tv%S(i,j,k-1))
856 diff_work(i,j,k) = g_2dt * drho * &
857 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
858 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
863 do k=2,nz ;
do i=is,ie
864 diff_work(i,j,k) = g_2dt * (gv%Rlay(k)-gv%Rlay(k-1)) * &
865 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
866 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
871 if (
present(kb_out))
then
872 do i=is,ie ; kb_out(i,j) = kb(i) ;
enddo
878 if (cs%id_Kd > 0)
call post_data(cs%id_Kd, kd_eff, cs%diag)
879 if (cs%id_Kd > 0)
deallocate(kd_eff)
880 if (cs%id_diff_work > 0)
call post_data(cs%id_diff_work, diff_work, cs%diag)
881 if (cs%id_diff_work > 0)
deallocate(diff_work)
883 end subroutine entrainment_diffusive
888 subroutine f_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb, do_i_in)
891 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: F
895 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
897 integer,
dimension(SZI_(G)),
intent(in) :: kb
899 integer,
intent(in) :: kmb
900 integer,
intent(in) :: j
902 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: dsp1_ds
906 real,
dimension(SZI_(G)),
intent(in) :: eakb
908 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Ent_bl
911 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
914 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
917 logical,
dimension(SZI_(G)), &
918 optional,
intent(in) :: do_i_in
925 logical :: do_i(SZI_(G))
926 integer :: i, k, is, ie, nz
928 is = g%isc ; ie = g%iec ; nz = g%ke
930 if (
present(do_i_in))
then
931 do i=is,ie ; do_i(i) = do_i_in(i) ;
enddo
932 do i=g%isc,g%iec ;
if (do_i(i))
then
935 do i=g%iec,g%isc,-1 ;
if (do_i(i))
then
939 do i=is,ie ; do_i(i) = .true. ;
enddo
943 ea(i,j,nz) = 0.0 ; eb(i,j,nz) = 0.0
945 if (cs%bulkmixedlayer)
then
947 eb(i,j,kmb) = max(2.0*ent_bl(i,kmb+1) - eakb(i), 0.0)
949 do k=nz-1,kmb+1,-1 ;
do i=is,ie ;
if (do_i(i))
then
953 ea(i,j,k) = dsp1_ds(i,k)*f(i,k)
955 elseif (k == kb(i))
then
958 elseif (k == kb(i)-1)
then
959 ea(i,j,k) = ea(i,j,k+1)
960 eb(i,j,k) = eb(i,j,kmb)
962 ea(i,j,k) = ea(i,j,k+1)
965 eb(i,j,k) = eb(i,j,k+1) + max(0.0, h(i,j,k+1) - gv%Angstrom_H)
967 endif ;
enddo ;
enddo
969 do i=is,ie ;
if (do_i(i))
then
973 eb(i,j,k) = eb(i,j,k+1) + max(0.0, h(i,j,k+1) - gv%Angstrom_H)
976 h1 = (h(i,j,k) - gv%Angstrom_H) + (eb(i,j,k) - ea(i,j,k+1))
977 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
979 do k=kmb-1,2,-1 ;
do i=is,ie ;
if (do_i(i))
then
981 eb(i,j,k) = max(2.0*ent_bl(i,k+1) - ea(i,j,k+1), 0.0)
984 h1 = (h(i,j,k) - gv%Angstrom_H) + (eb(i,j,k) - ea(i,j,k+1))
985 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
989 endif ;
enddo ;
enddo
990 do i=is,ie ;
if (do_i(i))
then
991 eb(i,j,1) = max(2.0*ent_bl(i,2) - ea(i,j,2), 0.0)
999 ea(i,j,1) = 0.0 ; eb(i,j,1) = max(f(i,1),0.0)
1000 ea(i,j,2) = dsp1_ds(i,2)*f(i,2) - min(f(i,1),0.0)
1003 do k=2,nz-1 ;
do i=is,ie
1004 eb(i,j,k) = max(f(i,k),0.0)
1005 ea(i,j,k+1) = dsp1_ds(i,k+1)*f(i,k+1) - (f(i,k)-eb(i,j,k))
1006 if (ea(i,j,k+1) < 0.0)
then
1007 eb(i,j,k) = eb(i,j,k) - ea(i,j,k+1)
1012 end subroutine f_to_ent
1018 subroutine set_ent_bl(h, dtKd_int, tv, kb, kmb, do_i, G, GV, CS, j, Ent_bl, Sref, h_bl)
1021 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
1023 real,
dimension(SZI_(G),SZK_(G)+1), &
1024 intent(in) :: dtKd_int
1030 integer,
dimension(SZI_(G)),
intent(inout) :: kb
1033 integer,
intent(in) :: kmb
1034 logical,
dimension(SZI_(G)),
intent(in) :: do_i
1037 integer,
intent(in) :: j
1038 real,
dimension(SZI_(G),SZK_(G)+1), &
1039 intent(out) :: Ent_bl
1042 real,
dimension(SZI_(G),SZK_(G)),
intent(out) :: Sref
1044 real,
dimension(SZI_(G),SZK_(G)),
intent(out) :: h_bl
1053 real,
dimension(SZI_(G)) :: &
1060 real,
dimension(SZI_(G), SZK_(G)) :: &
1069 integer :: i, k, is, ie, nz
1070 is = g%isc ; ie = g%iec ; nz = g%ke
1073 max_ent = 1.0e4*gv%m_to_H
1074 h_neglect = gv%H_subroundoff
1076 do i=is,ie ; pres(i) = tv%P_Ref ;
enddo
1079 rcv(is:ie), 1, ie-is+1, tv%eqn_of_state)
1081 h_bl(i,k) = h(i,j,k) + h_neglect
1082 sref(i,k) = rcv(i) - 1000.0
1087 h_interior(i) = 0.0 ; ent_bl(i,1) = 0.0
1091 do k=2,kmb ;
do i=is,ie
1093 ent_bl(i,k) = min(2.0 * dtkd_int(i,k) / (h(i,j,k-1) + h(i,j,k) + h_neglect), &
1095 else ; ent_bl(i,k) = 0.0 ;
endif
1104 b1(i) = 1.0 / (h_bl(i,1) + ent_bl(i,2))
1105 d1(i) = h_bl(i,1) * b1(i)
1106 s_est(i,1) = (h_bl(i,1)*sref(i,1)) * b1(i)
1108 do k=2,kmb-1 ;
do i=is,ie
1109 b1(i) = 1.0 / ((h_bl(i,k) + ent_bl(i,k+1)) + d1(i)*ent_bl(i,k))
1110 d1(i) = (h_bl(i,k) + d1(i)*ent_bl(i,k)) * b1(i)
1111 s_est(i,k) = (h_bl(i,k)*sref(i,k) + ent_bl(i,k)*s_est(i,k-1)) * b1(i)
1114 s_est(i,kmb) = (h_bl(i,kmb)*sref(i,kmb) + ent_bl(i,kmb)*s_est(i,kmb-1)) / &
1115 (h_bl(i,kmb) + d1(i)*ent_bl(i,kmb))
1121 do i=is,ie ; kb(i) = nz+1 ;
if (do_i(i)) kb(i) = kmb+1 ;
enddo
1123 do k=kmb+1,nz ;
do i=is,ie ;
if (do_i(i))
then
1124 if ((k == kb(i)) .and. (s_est(i,kmb) > (gv%Rlay(k) - 1000.0)))
then
1125 if (4.0*dtkd_int(i,kmb+1)*frac_rem(i) > &
1126 (h_bl(i,kmb) + h(i,j,k)) * (h(i,j,k) - gv%Angstrom_H))
then
1128 dh = max((h(i,j,k) - gv%Angstrom_H), 0.0)
1130 frac_rem(i) = frac_rem(i) - ((h_bl(i,kmb) + h(i,j,k)) * dh) / &
1131 (4.0*dtkd_int(i,kmb+1))
1132 sref(i,kmb) = (h_bl(i,kmb)*sref(i,kmb) + dh*(gv%Rlay(k)-1000.0)) / &
1134 h_bl(i,kmb) = h_bl(i,kmb) + dh
1135 s_est(i,kmb) = (h_bl(i,kmb)*sref(i,kmb) + ent_bl(i,kmb)*s_est(i,kmb-1)) / &
1136 (h_bl(i,kmb) + d1(i)*ent_bl(i,kmb))
1141 endif ;
enddo ;
enddo
1145 do k=nz,kmb+1,-1 ;
do i=is,ie
1146 if (k >= kb(i)) h_interior(i) = h_interior(i) + (h(i,j,k)-gv%Angstrom_H)
1148 h_bl(i,kmb+1) = h(i,j,k) ; sref(i,kmb+1) = gv%Rlay(k) - 1000.0
1149 elseif (k==kb(i)+1)
then
1150 h_bl(i,kmb+2) = h(i,j,k) ; sref(i,kmb+2) = gv%Rlay(k) - 1000.0
1153 do i=is,ie ;
if (kb(i) >= nz)
then
1154 h_bl(i,kmb+1) = h(i,j,nz)
1155 sref(i,kmb+1) = gv%Rlay(nz) - 1000.0
1156 h_bl(i,kmb+2) = gv%Angstrom_H
1157 sref(i,kmb+2) = sref(i,kmb+1) + (gv%Rlay(nz) - gv%Rlay(nz-1))
1163 do i=is,ie ;
if (do_i(i))
then
1164 kd_x_dt = frac_rem(i) * dtkd_int(i,kmb+1)
1165 if ((kd_x_dt <= 0.0) .or. (h_interior(i) <= 0.0))
then
1166 ent_bl(i,kmb+1) = 0.0
1170 ent_bl(i,kmb+1) = min(0.5*h_interior(i), sqrt(kd_x_dt), &
1171 kd_x_dt / (0.5*(h_bl(i,kmb) + h_bl(i,kmb+1))))
1174 ent_bl(i,kmb+1) = 0.0
1177 end subroutine set_ent_bl
1191 subroutine determine_dskb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, &
1192 dSkb, ddSkb_dE, dSlay, ddSlay_dE, dS_anom_lim, do_i_in)
1196 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: h_bl
1197 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Sref
1198 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Ent_bl
1201 real,
dimension(SZI_(G)),
intent(in) :: E_kb
1203 integer,
intent(in) :: is
1204 integer,
intent(in) :: ie
1205 integer,
intent(in) :: kmb
1206 logical,
intent(in) :: limit
1208 real,
dimension(SZI_(G)),
intent(inout) :: dSkb
1213 real,
dimension(SZI_(G)),
optional,
intent(inout) :: ddSkb_dE
1215 real,
dimension(SZI_(G)),
optional,
intent(inout) :: dSlay
1218 real,
dimension(SZI_(G)),
optional,
intent(inout) :: ddSlay_dE
1220 real,
dimension(SZI_(G)),
optional,
intent(inout) :: dS_anom_lim
1223 logical,
dimension(SZI_(G)),
optional,
intent(in) :: do_i_in
1243 real,
dimension(SZI_(G),SZK_(G)) :: &
1248 real :: deriv_dSkb(SZI_(G))
1253 logical,
dimension(SZI_(G)) :: do_i
1260 real :: dS_kbp1, IdS_kbp1
1263 real :: f1, df1_drat
1264 real :: z, dz_drat, f2, df2_dz, expz
1265 real :: eps_dSLay, eps_dSkb
1268 if (
present(ddslay_de) .and. .not.
present(dslay))
call mom_error(fatal, &
1269 "In deterimine_dSkb, ddSLay_dE may only be present if dSlay is.")
1271 h_neglect = gv%H_subroundoff
1274 ea(i,kmb+1) = e_kb(i) ; dea_de(i,kmb+1) = 1.0
1275 s(i,kmb+1) = sref(i,kmb+1) ; ds_de(i,kmb+1) = 0.0
1280 if (
present(do_i_in))
then
1281 do i=is,ie ; do_i(i) = do_i_in(i) ;
enddo
1283 do k=kmb,1,-1 ;
do i=is,ie
1287 if (2.0*ent_bl(i,k+1) > ea(i,k+1))
then
1288 eb(i,k) = 2.0*ent_bl(i,k+1) - ea(i,k+1) ; deb_de(i,k) = -dea_de(i,k+1)
1290 eb(i,k) = 0.0 ; deb_de(i,k) = 0.0
1294 h1 = (h_bl(i,k) - gv%Angstrom_H) + (eb(i,k) - ea(i,k+1))
1296 ea(i,k) = ent_bl(i,k) ; dea_de(i,k) = 0.0
1297 elseif (ent_bl(i,k) + 0.5*h1 >= 0.0)
then
1298 ea(i,k) = ent_bl(i,k) - 0.5*h1
1299 dea_de(i,k) = 0.5*(dea_de(i,k+1) - deb_de(i,k))
1302 dea_de(i,k) = dea_de(i,k+1) - deb_de(i,k)
1305 ea(i,k) = 0.0 ; dea_de(i,k) = 0.0 ; eb(i,k) = 0.0 ; deb_de(i,k) = 0.0
1309 h_tr = h_bl(i,k) + h_neglect
1310 c1(i,k) = ea(i,k+1) * b1(i,k+1)
1311 b_denom_1 = (h_tr + d1(i)*eb(i,k))
1312 b1(i,k) = 1.0 / (b_denom_1 + ea(i,k))
1313 d1(i) = b_denom_1 * b1(i,k)
1315 s(i,k) = (h_tr*sref(i,k) + eb(i,k)*s(i,k+1)) * b1(i,k)
1317 do k=2,kmb ;
do i=is,ie
1318 s(i,k) = s(i,k) + c1(i,k-1)*s(i,k-1)
1321 if (
present(ddskb_de) .or.
present(ddslay_de))
then
1324 do k=kmb,2,-1 ;
do i=is,ie
1325 if (do_i(i) .and. (dea_de(i,k) - deb_de(i,k) > 0.0))
then
1326 src = (((s(i,k+1) - sref(i,k)) * (h_bl(i,k) + h_neglect) + &
1327 (s(i,k+1) - s(i,k-1)) * ea(i,k)) * deb_de(i,k) - &
1328 ((sref(i,k) - s(i,k-1)) * h_bl(i,k) + &
1329 (s(i,k+1) - s(i,k-1)) * eb(i,k)) * dea_de(i,k)) / &
1330 ((h_bl(i,k) + h_neglect + ea(i,k)) + eb(i,k))
1331 else ; src = 0.0 ;
endif
1332 ds_de(i,k) = (src + eb(i,k)*ds_de(i,k+1)) * b1(i,k)
1335 if (do_i(i) .and. (deb_de(i,1) < 0.0))
then
1336 src = (((s(i,2) - sref(i,1)) * (h_bl(i,1) + h_neglect)) * deb_de(i,1)) / &
1337 (h_bl(i,1) + h_neglect + eb(i,1))
1338 else ; src = 0.0 ;
endif
1339 ds_de(i,1) = (src + eb(i,1)*ds_de(i,2)) * b1(i,1)
1341 do k=2,kmb ;
do i=is,ie
1342 ds_de(i,k) = ds_de(i,k) + c1(i,k-1)*ds_de(i,k-1)
1349 if (.not.limit)
then
1350 do i=is,ie ;
if (do_i(i))
then
1351 dskb(i) = sref(i,kmb+1) - s(i,kmb)
1353 if (
present(ddskb_de))
then ;
do i=is,ie ;
if (do_i(i))
then
1354 ddskb_de(i) = -1.0*ds_de(i,kmb)
1355 endif ;
enddo ;
endif
1357 if (
present(dslay))
then ;
do i=is,ie ;
if (do_i(i))
then
1358 dslay(i) = 0.5 * (sref(i,kmb+2) - s(i,kmb))
1359 endif ;
enddo ;
endif
1360 if (
present(ddslay_de))
then ;
do i=is,ie ;
if (do_i(i))
then
1361 ddslay_de(i) = -0.5*ds_de(i,kmb)
1362 endif ;
enddo ;
endif
1364 do i=is,ie ;
if (do_i(i))
then
1366 if (sref(i,kmb+1) - s(i,kmb) < eps_dskb*(sref(i,kmb+2) - sref(i,kmb+1)))
then
1367 dskb(i) = eps_dskb * (sref(i,kmb+2) - sref(i,kmb+1)) ; deriv_dskb(i) = 0.0
1369 dskb(i) = sref(i,kmb+1) - s(i,kmb) ; deriv_dskb(i) = -1.0
1371 if (
present(ddskb_de)) ddskb_de(i) = deriv_dskb(i)*ds_de(i,kmb)
1374 if (
present(dslay))
then
1378 do i=is,ie ;
if (do_i(i))
then
1379 ds_kbp1 = sref(i,kmb+2) - sref(i,kmb+1)
1380 ids_kbp1 = 1.0 / (sref(i,kmb+2) - sref(i,kmb+1))
1381 rat = (sref(i,kmb+1) - s(i,kmb)) * ids_kbp1
1389 inv_term = 1.0 / (1.0-rat)
1390 f1 = 2.0 - 0.125*(inv_term**2)
1391 df1_drat = - 0.25*(inv_term**3)
1395 z = dz_drat * rat + 4.0
1396 if (z >= 18.0)
then ; f2 = 1.0 ; df2_dz = 0.0
1397 elseif (z <= -58.0)
then ; f2 = eps_dslay ; df2_dz = 0.0
1399 expz = exp(z) ; inv_term = 1.0 / (1.0 + expz)
1400 f2 = (eps_dslay + expz) * inv_term
1401 df2_dz = (1.0 - eps_dslay) * expz * inv_term**2
1404 dslay(i) = dskb(i) * f1 * f2
1405 deriv_dslay = deriv_dskb(i) * (f1 * f2) - (dskb(i)*ids_kbp1) * &
1406 (df1_drat*f2 + f1 * dz_drat * df2_dz)
1407 elseif (dskb(i) <= 3.0*ds_kbp1)
then
1409 dslay(i) = 0.5 * (dskb(i) + ds_kbp1)
1410 deriv_dslay = 0.5 * deriv_dskb(i)
1412 dslay(i) = 2.0*ds_kbp1
1415 if (
present(ddslay_de)) ddslay_de(i) = deriv_dslay*ds_de(i,kmb)
1420 if (
present(ds_anom_lim))
then ;
do i=is,ie ;
if (do_i(i))
then
1421 ds_anom_lim(i) = max(0.0, eps_dskb * (sref(i,kmb+2) - sref(i,kmb+1)) - &
1422 (sref(i,kmb+1) - s(i,kmb)) )
1423 endif ;
enddo ;
endif
1425 end subroutine determine_dskb
1431 subroutine f_kb_to_ea_kb(h_bl, Sref, Ent_bl, I_dSkbp1, F_kb, kmb, i, &
1432 G, GV, CS, ea_kb, tol_in)
1435 real,
dimension(SZI_(G),SZK_(G)), &
1438 real,
dimension(SZI_(G),SZK_(G)), &
1442 real,
dimension(SZI_(G),SZK_(G)), &
1443 intent(in) :: Ent_bl
1446 real,
dimension(SZI_(G)),
intent(in) :: I_dSkbp1
1449 real,
dimension(SZI_(G)),
intent(in) :: F_kb
1451 integer,
intent(in) :: kmb
1452 integer,
intent(in) :: i
1454 real,
dimension(SZI_(G)),
intent(inout) :: ea_kb
1456 real,
optional,
intent(in) :: tol_in
1459 real :: max_ea, min_ea
1460 real :: err, err_min, err_max
1462 real :: val, tolerance, tol1
1465 logical :: bisect_next, Newton
1466 real,
dimension(SZI_(G)) :: dS_kb
1467 real,
dimension(SZI_(G)) :: maxF, ent_maxF, zeros
1468 real,
dimension(SZI_(G)) :: ddSkb_dE
1470 integer,
parameter :: MAXIT = 30
1472 ds_kbp1 = sref(i,kmb+2) - sref(i,kmb+1)
1473 max_ea = ea_kb(i) ; min_ea = 0.0
1474 val = ds_kbp1 * f_kb(i)
1477 tolerance = cs%Tolerance_Ent
1478 if (
present(tol_in)) tolerance = tol_in
1479 bisect_next = .true.
1481 call determine_dskb(h_bl, sref, ent_bl, ea_kb, i, i, kmb, g, gv, .true., &
1484 err = ds_kb(i) * ea_kb(i) - val
1485 derr_dea = ds_kb(i) + ddskb_de(i) * ea_kb(i)
1488 if ((err <= 0.0) .and. (abs(err) <= tolerance*abs(derr_dea)))
return
1490 if (err == 0.0)
then ;
return
1491 elseif (err > 0.0)
then
1492 max_ea = ea_kb(i) ; err_max = err
1495 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i) - min_ea) > err) .and. &
1496 (derr_dea*(max_ea - ea_kb(i)) > -1.0*err))
then
1497 ea_kb(i) = ea_kb(i) - err / derr_dea
1499 ea_kb(i) = 0.5*(max_ea+min_ea)
1505 call find_maxf_kb(h_bl, sref, ent_bl, i_dskbp1, zeros, ea_kb, &
1506 kmb, i, i, g, gv, cs, maxf, ent_maxf, f_thresh = f_kb)
1507 err_max = ds_kbp1 * maxf(i) - val
1510 if (err_max <= 0.0)
then
1511 ea_kb(i) = ent_maxf(i) ;
return
1513 max_ea = ent_maxf(i)
1514 ea_kb(i) = 0.5*(max_ea+min_ea)
1522 call determine_dskb(h_bl, sref, ent_bl, ea_kb, i, i, kmb, g, gv, .true., &
1525 err = ds_kb(i) * ea_kb(i) - val
1526 derr_dea = ds_kb(i) + ddskb_de(i) * ea_kb(i)
1532 max_ea = ea_kb(i) ; err_max = err
1533 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i)-min_ea) > err)) newton = .true.
1535 min_ea = ea_kb(i) ; err_min = err
1536 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i)-max_ea) < err)) newton = .true.
1540 ea_kb(i) = ea_kb(i) - err / derr_dea
1541 elseif (bisect_next)
then
1542 ea_kb(i) = 0.5*(max_ea+min_ea)
1543 bisect_next = .false.
1545 ea_kb(i) = min_ea + (max_ea-min_ea) * (err_min/(err_min - err_max))
1546 bisect_next = .true.
1549 tol1 = tolerance ;
if (err > 0.0) tol1 = 0.099*tolerance
1550 if (ds_kb(i) <= ds_kbp1)
then
1551 if (abs(ea_kb(i) - ea_prev) <= tol1)
return
1553 if (ds_kbp1*abs(ea_kb(i) - ea_prev) <= ds_kb(i)*tol1)
return
1557 end subroutine f_kb_to_ea_kb
1563 subroutine determine_ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, &
1564 min_eakb, max_eakb, kmb, is, ie, do_i, G, GV, CS, Ent, &
1565 error, err_min_eakb0, err_max_eakb0, F_kb, dFdfm_kb)
1568 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: h_bl
1570 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Sref
1574 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Ent_bl
1577 real,
dimension(SZI_(G)),
intent(in) :: I_dSkbp1
1581 real,
dimension(SZI_(G)),
intent(in) :: dtKd_kb
1584 real,
dimension(SZI_(G)),
intent(in) :: ea_kbp1
1586 real,
dimension(SZI_(G)),
intent(in) :: min_eakb
1588 real,
dimension(SZI_(G)),
intent(in) :: max_eakb
1590 integer,
intent(in) :: kmb
1591 integer,
intent(in) :: is
1592 integer,
intent(in) :: ie
1593 logical,
dimension(SZI_(G)),
intent(in) :: do_i
1596 real,
dimension(SZI_(G)),
intent(inout) :: Ent
1599 real,
dimension(SZI_(G)),
optional,
intent(out) :: error
1602 real,
dimension(SZI_(G)),
optional,
intent(in) :: err_min_eakb0
1605 real,
dimension(SZI_(G)),
optional,
intent(in) :: err_max_eakb0
1608 real,
dimension(SZI_(G)),
optional,
intent(out) :: F_kb
1612 real,
dimension(SZI_(G)),
optional,
intent(out) :: dFdfm_kb
1620 real,
dimension(SZI_(G)) :: &
1627 ddskb_de, ddslay_de, &
1632 error_mine, error_maxe
1642 logical,
dimension(SZI_(G)) :: false_position
1644 logical,
dimension(SZI_(G)) :: redo_i
1648 integer,
parameter :: MAXIT = 30
1650 if (.not.cs%bulkmixedlayer)
then
1651 call mom_error(fatal,
"determine_Ea_kb should not be called "//&
1652 "unless BULKMIXEDLAYER is defined.")
1654 tolerance = cs%Tolerance_Ent
1655 large_err = gv%m_to_H**2 * 1.0e30
1657 do i=is,ie ; redo_i(i) = do_i(i) ;
enddo
1659 do i=is,ie ;
if (do_i(i))
then
1664 e_min(i) = min_eakb(i) ; e_max(i) = max_eakb(i)
1665 error_mine(i) = -large_err ; error_maxe(i) = large_err
1666 false_position(i) = .true.
1668 if (
present(err_min_eakb0)) error_mine(i) = err_min_eakb0(i) - e_min(i) * ea_kbp1(i)
1669 if (
present(err_max_eakb0)) error_maxe(i) = err_max_eakb0(i) - e_max(i) * ea_kbp1(i)
1671 if ((error_maxe(i) <= 0.0) .or. (error_mine(i) >= 0.0))
then
1673 if (error_maxe(i) <= 0.0)
then
1675 ent(i) = e_max(i) ; err(i) = error_maxe(i)
1677 ent(i) = e_min(i) ; err(i) = error_mine(i)
1685 do_any = .false. ;
do i=is,ie ;
if (redo_i(i)) do_any = .true. ;
enddo
1686 if (.not.do_any)
exit
1687 call determine_dskb(h_bl, sref, ent_bl, ent, is, ie, kmb, g, gv, .true., ds_kb, &
1688 ddskb_de, ds_lay, ddslay_de, do_i_in = redo_i)
1689 do i=is,ie ;
if (redo_i(i))
then
1692 el = 0.0 ;
if (2.0*ent_bl(i,kmb+1) >= ent(i)) el = 1.0
1693 fa = (1.0 + el) + ds_kb(i)*i_dskbp1(i)
1694 fk = dtkd_kb(i) * (ds_lay(i)/ds_kb(i))
1695 fm = (ea_kbp1(i) - h_bl(i,kmb+1)) + el*2.0*ent_bl(i,kmb+1)
1696 if (fm > -gv%Angstrom_H) fm = fm + gv%Angstrom_H
1697 err(i) = (fa * ent(i)**2 - fm * ent(i)) - fk
1698 derror_de(i) = ((2.0*fa + (ddskb_de(i)*i_dskbp1(i))*ent(i))*ent(i) - fm) - &
1699 dtkd_kb(i) * (ddslay_de(i)*ds_kb(i) - ddskb_de(i)*ds_lay(i))/(ds_kb(i)**2)
1701 if (err(i) == 0.0)
then
1702 redo_i(i) = .false. ; cycle
1703 elseif (err(i) > 0.0)
then
1704 e_max(i) = ent(i) ; error_maxe(i) = err(i)
1706 e_min(i) = ent(i) ; error_mine(i) = err(i)
1710 if ((it == 1) .or. (derror_de(i) <= 0.0))
then
1715 fr = sqrt(fm**2 + 4.0*fa*fk)
1717 ent(i) = (fm + fr) / (2.0 * fa)
1719 ent(i) = (2.0 * fk) / (fr - fm)
1722 if ((ent(i) > e_max(i)) .or. (ent(i) < e_min(i))) &
1723 ent(i) = 0.5*(e_max(i) + e_min(i))
1724 elseif (((e_max(i)-ent(i))*derror_de(i) > -err(i)) .and. &
1725 ((ent(i)-e_min(i))*derror_de(i) > err(i)) )
then
1728 ent(i) = ent(i) - err(i) / derror_de(i)
1729 elseif (false_position(i) .and. &
1730 (error_maxe(i) - error_mine(i) < 0.9*large_err))
then
1732 ent(i) = e_min(i) + (e_max(i)-e_min(i)) * &
1733 (-error_mine(i)/(error_maxe(i) - error_mine(i)))
1734 false_position(i) = .false.
1736 ent(i) = 0.5*(e_max(i) + e_min(i))
1737 false_position(i) = .true.
1740 if (abs(e_prev - ent(i)) < tolerance)
then
1741 err_est = err(i) + (ent(i) - e_prev) * derror_de(i)
1742 if ((it > 1) .or. (err_est*err(i) <= 0.0) .or. &
1743 (abs(err_est) < abs(tolerance*derror_de(i)))) redo_i(i) = .false.
1750 if (
present(f_kb) .or.
present(dfdfm_kb)) &
1751 call determine_dskb(h_bl, sref, ent_bl, ent, is, ie, kmb, g, gv, .true., &
1752 ds_kb, do_i_in = do_i)
1754 if (
present(f_kb))
then ;
do i=is,ie ;
if (do_i(i))
then
1755 f_kb(i) = ent(i) * (ds_kb(i) * i_dskbp1(i))
1756 endif ;
enddo ;
endif
1757 if (
present(error))
then ;
do i=is,ie ;
if (do_i(i))
then
1759 endif ;
enddo ;
endif
1760 if (
present(dfdfm_kb))
then ;
do i=is,ie ;
if (do_i(i))
then
1764 if (derror_de(i) > 0.0)
then
1765 dfdfm_kb(i) = ((ds_kb(i) + ent(i) * ddskb_de(i)) * i_dskbp1(i)) * &
1766 (ent(i) / derror_de(i))
1770 endif ;
enddo ;
endif
1772 end subroutine determine_ea_kb
1775 subroutine find_maxf_kb(h_bl, Sref, Ent_bl, I_dSkbp1, min_ent_in, max_ent_in, &
1776 kmb, is, ie, G, GV, CS, maxF, ent_maxF, do_i_in, &
1777 F_lim_maxent, F_thresh)
1780 real,
dimension(SZI_(G),SZK_(G)), &
1782 real,
dimension(SZI_(G),SZK_(G)), &
1784 real,
dimension(SZI_(G),SZK_(G)), &
1785 intent(in) :: Ent_bl
1788 real,
dimension(SZI_(G)),
intent(in) :: I_dSkbp1
1792 real,
dimension(SZI_(G)),
intent(in) :: min_ent_in
1794 real,
dimension(SZI_(G)),
intent(in) :: max_ent_in
1796 integer,
intent(in) :: kmb
1797 integer,
intent(in) :: is
1798 integer,
intent(in) :: ie
1800 real,
dimension(SZI_(G)),
intent(out) :: maxF
1803 real,
dimension(SZI_(G)), &
1804 optional,
intent(out) :: ent_maxF
1805 logical,
dimension(SZI_(G)), &
1806 optional,
intent(in) :: do_i_in
1808 real,
dimension(SZI_(G)), &
1809 optional,
intent(out) :: F_lim_maxent
1813 real,
dimension(SZI_(G)), &
1814 optional,
intent(in) :: F_thresh
1824 real,
dimension(SZI_(G)) :: &
1826 minent, maxent, ent_best, &
1828 F_maxent, F_minent, F, F_best, &
1829 dF_dent, dF_dE_max, dF_dE_min, dF_dE_best, &
1830 dS_kb, dS_kb_lim, ddSkb_dE, dS_anom_lim, &
1831 chg_prev, chg_pre_prev
1832 real :: dF_dE_mean, maxslope, minslope
1834 real :: ratio_select_end
1835 real :: rat, max_chg, min_chg, chg1, chg2, chg
1836 logical,
dimension(SZI_(G)) :: do_i, last_it, need_bracket, may_use_best
1837 logical :: doany, OK1, OK2, bisect, new_min_bound
1838 integer :: i, it, is1, ie1
1839 integer,
parameter :: MAXIT = 20
1841 tolerance = cs%Tolerance_Ent
1843 if (
present(do_i_in))
then
1844 do i=is,ie ; do_i(i) = do_i_in(i) ;
enddo
1846 do i=is,ie ; do_i(i) = .true. ;
enddo
1850 call determine_dskb(h_bl, sref, ent_bl, max_ent_in, is, ie, kmb, g, gv, .false., &
1851 ds_kb, ddskb_de , ds_anom_lim=ds_anom_lim)
1852 ie1 = is-1 ; doany = .false.
1854 ds_kb_lim(i) = ds_kb(i) + ds_anom_lim(i)
1855 f_max_ent_in(i) = max_ent_in(i)*ds_kb_lim(i)*i_dskbp1(i)
1856 maxent(i) = max_ent_in(i) ; minent(i) = min_ent_in(i)
1857 if ((abs(maxent(i) - minent(i)) < tolerance) .or. (.not.do_i(i)))
then
1858 f_best(i) = max_ent_in(i)*ds_kb(i)*i_dskbp1(i)
1859 ent_best(i) = max_ent_in(i) ; ent(i) = max_ent_in(i)
1862 f_maxent(i) = maxent(i) * ds_kb(i) * i_dskbp1(i)
1863 df_de_max(i) = (ds_kb(i) + maxent(i)*ddskb_de(i)) * i_dskbp1(i)
1864 doany = .true. ; last_it(i) = .false. ; need_bracket(i) = .true.
1869 ie1 = is-1 ;
do i=is,ie ;
if (do_i(i)) ie1 = i ;
enddo
1870 do i=ie1,is,-1 ;
if (do_i(i)) is1 = i ;
enddo
1872 call determine_dskb(h_bl, sref, ent_bl, minent, is1, ie1, kmb, g, gv, .false., &
1873 ds_kb, ddskb_de, do_i_in = do_i)
1874 do i=is1,ie1 ;
if (do_i(i))
then
1875 f_minent(i) = minent(i) * ds_kb(i) * i_dskbp1(i)
1876 df_de_min(i) = (ds_kb(i) + minent(i)*ddskb_de(i)) * i_dskbp1(i)
1879 ratio_select_end = 0.9
1881 ratio_select_end = 0.5*ratio_select_end
1882 do i=is1,ie1 ;
if (do_i(i))
then
1883 if (need_bracket(i))
then
1884 df_de_mean = (f_maxent(i) - f_minent(i)) / (maxent(i) - minent(i))
1885 maxslope = max(df_de_mean, df_de_min(i), df_de_max(i))
1886 minslope = min(df_de_mean, df_de_min(i), df_de_max(i))
1887 if (f_minent(i) >= f_maxent(i))
then
1888 if (df_de_min(i) > 0.0)
then ; rat = 0.02
1889 elseif (maxslope < ratio_select_end*minslope)
then
1891 f_best(i) = f_minent(i) ; ent_best(i) = minent(i) ; rat = 0.0
1893 else ; rat = 0.382 ;
endif
1895 if (df_de_max(i) < 0.0)
then ; rat = 0.98
1896 elseif (minslope > ratio_select_end*maxslope)
then
1898 f_best(i) = f_maxent(i) ; ent_best(i) = maxent(i) ; rat = 1.0
1900 else ; rat = 0.618 ;
endif
1903 if (rat >= 0.0) ent(i) = rat*maxent(i) + (1.0-rat)*minent(i)
1904 if (((maxent(i) - minent(i)) < tolerance) .or. (it==maxit)) &
1907 chg1 = 2.0*(maxent(i) - minent(i)) ; chg2 = chg1
1908 if (df_de_best(i) > 0)
then
1909 max_chg = maxent(i) - ent_best(i) ; min_chg = 0.0
1911 max_chg = 0.0 ; min_chg = minent(i) - ent_best(i)
1913 if (max_chg - min_chg < 2.0*tolerance) last_it(i) = .true.
1914 if (df_de_max(i) /= df_de_best(i)) &
1915 chg1 = (maxent(i) - ent_best(i))*df_de_best(i) / &
1916 (df_de_best(i) - df_de_max(i))
1917 if (df_de_min(i) /= df_de_best(i)) &
1918 chg2 = (minent(i) - ent_best(i))*df_de_best(i) / &
1919 (df_de_best(i) - df_de_min(i))
1920 ok1 = ((chg1 < max_chg) .and. (chg1 > min_chg))
1921 ok2 = ((chg2 < max_chg) .and. (chg2 > min_chg))
1922 if (.not.(ok1 .or. ok2))
then ; bisect = .true. ;
else
1923 if (ok1 .and. ok2)
then
1924 chg = chg1 ;
if (abs(chg2) < abs(chg1)) chg = chg2
1925 elseif (ok1)
then ; chg = chg1
1926 else ; chg = chg2 ;
endif
1927 if (abs(chg) > 0.5*abs(chg_pre_prev(i)))
then ; bisect = .true.
1928 else ; bisect = .false. ;
endif
1930 chg_pre_prev(i) = chg_prev(i)
1932 if (df_de_best(i) > 0.0)
then
1933 ent(i) = 0.5*(maxent(i) + ent_best(i))
1934 chg_prev(i) = 0.5*(maxent(i) - ent_best(i))
1936 ent(i) = 0.5*(minent(i) + ent_best(i))
1937 chg_prev(i) = 0.5*(minent(i) - ent_best(i))
1940 if (abs(chg) < tolerance) chg = sign(tolerance,chg)
1941 ent(i) = ent_best(i) + chg
1947 if (mod(it,3) == 0)
then
1948 ie1 = is-1 ;
do i=is1,ie ;
if (do_i(i)) ie1 = i ;
enddo
1949 do i=ie1,is,-1 ;
if (do_i(i)) is1 = i ;
enddo
1952 call determine_dskb(h_bl, sref, ent_bl, ent, is1, ie1, kmb, g, gv, .false., &
1953 ds_kb, ddskb_de, do_i_in = do_i)
1954 do i=is1,ie1 ;
if (do_i(i))
then
1955 f(i) = ent(i)*ds_kb(i)*i_dskbp1(i)
1956 df_dent(i) = (ds_kb(i) + ent(i)*ddskb_de(i)) * i_dskbp1(i)
1959 if (
present(f_thresh))
then ;
do i=is1,ie1 ;
if (do_i(i))
then
1960 if (f(i) >= f_thresh(i))
then
1961 f_best(i) = f(i) ; ent_best(i) = ent(i) ; do_i(i) = .false.
1963 endif ;
enddo ;
endif
1966 do i=is1,ie1 ;
if (do_i(i))
then
1967 if (.not.last_it(i)) doany = .true.
1968 if (last_it(i))
then
1969 if (need_bracket(i))
then
1970 if ((f(i) > f_maxent(i)) .and. (f(i) > f_minent(i)))
then
1971 f_best(i) = f(i) ; ent_best(i) = ent(i)
1972 elseif (f_maxent(i) > f_minent(i))
then
1973 f_best(i) = f_maxent(i) ; ent_best(i) = maxent(i)
1975 f_best(i) = f_minent(i) ; ent_best(i) = minent(i)
1977 elseif (f(i) > f_best(i))
then
1978 f_best(i) = f(i) ; ent_best(i) = ent(i)
1981 elseif (need_bracket(i))
then
1982 if ((f(i) > f_maxent(i)) .and. (f(i) > f_minent(i)))
then
1983 need_bracket(i) = .false.
1984 chg_prev(i) = (maxent(i) - minent(i))
1985 chg_pre_prev(i) = 2.0*chg_prev(i)
1986 ent_best(i) = ent(i) ; f_best(i) = f(i) ; df_de_best(i) = df_dent(i)
1987 elseif ((f(i) <= f_maxent(i)) .and. (f(i) > f_minent(i)))
then
1988 new_min_bound = .true.
1989 elseif ((f(i) <= f_maxent(i)) .and. (f(i) > f_minent(i)))
then
1990 new_min_bound = .false.
1996 new_min_bound = .true.
1997 if (df_de_min(i) > 0.0 .or. (f_minent(i) >= f_maxent(i))) &
1998 new_min_bound = .false.
2000 if (need_bracket(i))
then
2001 if (new_min_bound)
then
2002 minent(i) = ent(i) ; f_minent(i) = f(i) ; df_de_min(i) = df_dent(i)
2004 maxent(i) = ent(i) ; f_maxent(i) = f(i) ; df_de_max(i) = df_dent(i)
2008 if (f(i) >= f_best(i))
then
2009 if (ent(i) > ent_best(i))
then
2010 minent(i) = ent_best(i) ; f_minent(i) = f_best(i) ; df_de_min(i) = df_de_best(i)
2012 maxent(i) = ent_best(i) ; f_maxent(i) = f_best(i) ; df_de_max(i) = df_de_best(i)
2014 ent_best(i) = ent(i) ; f_best(i) = f(i) ; df_de_best(i) = df_dent(i)
2016 if (ent(i) < ent_best(i))
then
2017 minent(i) = ent(i) ; f_minent(i) = f(i) ; df_de_min(i) = df_dent(i)
2019 maxent(i) = ent(i) ; f_maxent(i) = f(i) ; df_de_max(i) = df_dent(i)
2022 if ((maxent(i) - minent(i)) <= tolerance) do_i(i) = .false.
2025 if (.not.doany)
exit
2029 if (
present(f_lim_maxent))
then
2033 f_lim_maxent(i) = f_max_ent_in(i)
2034 if (
present(ent_maxf)) ent_maxf(i) = ent_best(i)
2040 may_use_best(i) = (ent_best(i) /= max_ent_in(i))
2041 if (may_use_best(i)) doany = .true.
2045 call determine_dskb(h_bl, sref, ent_bl, ent_best, is, ie, kmb, g, gv, .true., &
2048 f_best(i) = ent_best(i)*ds_kb_lim(i)*i_dskbp1(i)
2051 if ((f_best(i) > f_max_ent_in(i)) .and. (may_use_best(i)))
then
2053 if (
present(ent_maxf)) ent_maxf(i) = ent_best(i)
2055 maxf(i) = f_max_ent_in(i)
2056 if (
present(ent_maxf)) ent_maxf(i) = max_ent_in(i)
2061 do i=is,ie ; maxf(i) = f_max_ent_in(i) ;
enddo
2062 if (
present(ent_maxf))
then
2063 do i=is,ie ; ent_maxf(i) = max_ent_in(i) ;
enddo
2068 end subroutine find_maxf_kb
2072 subroutine entrain_diffusive_init(Time, G, GV, US, param_file, diag, CS)
2073 type(time_type),
intent(in) :: time
2079 type(
diag_ctrl),
target,
intent(inout) :: diag
2092 real :: decay_length, dt, kd
2094 #include "version_variable.h"
2095 character(len=40) :: mdl =
"MOM_entrain_diffusive"
2097 if (
associated(cs))
then
2098 call mom_error(warning,
"entrain_diffusive_init called with an associated "// &
2099 "control structure.")
2106 cs%bulkmixedlayer = (gv%nkml > 0)
2110 call get_param(param_file, mdl,
"CORRECT_DENSITY", cs%correct_density, &
2111 "If true, and USE_EOS is true, the layer densities are "//&
2112 "restored toward their target values by the diapycnal "//&
2113 "mixing, as described in Hallberg (MWR, 2000).", &
2115 call get_param(param_file, mdl,
"MAX_ENT_IT", cs%max_ent_it, &
2116 "The maximum number of iterations that may be used to "//&
2117 "calculate the interior diapycnal entrainment.", default=5)
2119 call get_param(param_file, mdl,
"KD", kd, fail_if_missing=.true.)
2120 call get_param(param_file, mdl,
"DT", dt, &
2121 "The (baroclinic) dynamics time step.", units =
"s", &
2122 fail_if_missing=.true.)
2124 call get_param(param_file, mdl,
"TOLERANCE_ENT", cs%Tolerance_Ent, &
2125 "The tolerance with which to solve for entrainment values.", &
2126 units=
"m", default=max(100.0*gv%Angstrom_m,1.0e-4*sqrt(dt*kd)), scale=gv%m_to_H)
2128 cs%id_Kd = register_diag_field(
'ocean_model',
'Kd_effective', diag%axesTL, time, &
2129 'Diapycnal diffusivity as applied',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
2130 cs%id_diff_work = register_diag_field(
'ocean_model',
'diff_work', diag%axesTi, time, &
2131 'Work actually done by diapycnal diffusion across each interface',
'W m-2', &
2132 conversion=us%Z_to_m**3*us%s_to_T**3)
2134 end subroutine entrain_diffusive_init
2138 subroutine entrain_diffusive_end(CS)
2141 if (
associated(cs))
deallocate(cs)
2143 end subroutine entrain_diffusive_end