17 implicit none ;
private 19 #include <MOM_memory.h> 21 public entrainment_diffusive, entrain_diffusive_init, entrain_diffusive_end
30 logical :: bulkmixedlayer
40 integer :: id_diff_work = -1
50 subroutine entrainment_diffusive(h, tv, fluxes, dt, G, GV, US, CS, ea, eb, &
51 kb_out, Kd_Lay, Kd_int)
55 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
60 type(
forcing),
intent(in) :: fluxes
62 real,
intent(in) :: dt
65 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
68 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
71 integer,
dimension(SZI_(G),SZJ_(G)), &
72 optional,
intent(inout) :: kb_out
75 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
76 optional,
intent(in) :: Kd_Lay
78 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
79 optional,
intent(in) :: Kd_int
88 real,
dimension(SZI_(G),SZK_(G)) :: &
90 real,
dimension(SZI_(G),SZK_(G)+1) :: &
92 real,
dimension(SZI_(G),SZK_(G)) :: &
105 real,
dimension(SZI_(G),SZK_(G)+1) :: &
108 real,
allocatable,
dimension(:,:,:) :: &
115 real :: hm, fm, fr, fk
118 real :: c1(szi_(g),szk_(g))
120 real,
dimension(SZI_(G)) :: &
151 real,
dimension(SZI_(G),SZK_(G)) :: &
159 real,
dimension(SZI_(G),SZK_(G)) :: &
174 real,
dimension(SZI_(G)) :: &
198 logical :: do_entrain_eakb
199 logical :: do_i(szi_(g)), did_i(szi_(g)), reiterate
200 integer,
dimension(2) :: EOSdom
201 integer :: it, i, j, k, is, ie, js, je, nz, K2, kmb
202 integer :: kb(szi_(g))
204 integer :: kb_min_act
206 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
207 angstrom = gv%Angstrom_H
208 h_neglect = gv%H_subroundoff
210 if (.not.
associated(cs))
call mom_error(fatal, &
211 "MOM_entrain_diffusive: Module must be initialized before it is used.")
213 if (.not.(
present(kd_lay) .or.
present(kd_int)))
call mom_error(fatal, &
214 "MOM_entrain_diffusive: Either Kd_Lay or Kd_int must be present in call.")
216 if ((.not.cs%bulkmixedlayer .and. .not.
associated(fluxes%buoy)) .and. &
217 (
associated(fluxes%lprec) .or.
associated(fluxes%evap) .or. &
218 associated(fluxes%sens) .or.
associated(fluxes%sw)))
then 219 if (is_root_pe())
call mom_error(note,
"Calculate_Entrainment: & 220 &The code to handle evaporation and precipitation without & 221 &a bulk mixed layer has not been implemented.")
222 if (is_root_pe())
call mom_error(fatal, &
223 "Either define BULKMIXEDLAYER in MOM_input or use fluxes%buoy & 224 &and a linear equation of state to drive the model.")
227 tolerance = cs%Tolerance_Ent
228 kmb = gv%nk_rho_varies
229 k2 = max(kmb+1,2) ; kb_min = k2
230 if (.not. cs%bulkmixedlayer)
then 234 do i=is,ie ; ds_dsp1(i,nz) = 2.0 ; dsp1_ds(i,nz) = 0.5 ;
enddo 237 do i=is,ie ; ds_dsp1(i,nz) = 0.0 ; dsp1_ds(i,nz) = 0.0 ;
enddo 240 if (cs%id_diff_work > 0)
allocate(diff_work(g%isd:g%ied,g%jsd:g%jed,nz+1))
241 if (cs%id_Kd > 0)
allocate(kd_eff(g%isd:g%ied,g%jsd:g%jed,nz))
243 if (
associated(tv%eqn_of_state))
then 248 eosdom(:) = eos_domain(g%HI)
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, us, 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 do_entrain_eakb = .false.
360 if (do_i(i))
then ;
if (err_max_eakb0(i) < 0.0)
then 361 do_entrain_eakb = .true.
364 if (do_entrain_eakb)
then 365 eakb(i) = max_eakb(i) ; min_eakb(i) = max_eakb(i)
367 eakb(i) = 0.0 ; min_eakb(i) = 0.0
374 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, &
375 zeros, max_eakb, kmb, is, ie, do_i, g, gv, cs, min_eakb, &
376 error=err_min_eakb0, f_kb=f_kb, err_max_eakb0=err_max_eakb0)
378 do i=is,ie ;
if ((kb(i)<nz) .and. (kb_min>kb(i))) kb_min = kb(i) ;
enddo 387 htot(i) = h(i,j,1) - angstrom
389 if (
associated(fluxes%buoy))
then ;
do i=is,ie
390 maxf(i,1) = gv%Z_to_H * (dt*fluxes%buoy(i,j)) / gv%g_prime(2)
396 do k=kb_min,nz-1 ;
do i=is,ie
397 if ((k == kb(i)+1) .and. cs%bulkmixedlayer)
then 398 maxf(i,k) = ds_dsp1(i,k)*(f_kb_maxent(i) + htot(i))
399 htot(i) = htot(i) + (h(i,j,k) - angstrom)
400 elseif (k > kb(i))
then 401 maxf(i,k) = ds_dsp1(i,k)*(maxf(i,k-1) + htot(i))
402 htot(i) = htot(i) + (h(i,j,k) - angstrom)
407 if (.not.cs%bulkmixedlayer)
then 408 maxf_correct(i) = max(0.0, -(maxf(i,nz-1) + htot(i)))
410 htot(i) = h(i,j,nz) - angstrom
412 if (.not.cs%bulkmixedlayer)
then 413 do_any = .false. ;
do i=is,ie ;
if (maxf_correct(i) > 0.0) do_any = .true. ;
enddo 415 do k=nz-1,1,-1 ;
do i=is,ie
416 maxf(i,k) = maxf(i,k) + maxf_correct(i)
417 maxf_correct(i) = maxf_correct(i) * dsp1_ds(i,k)
421 do k=nz-1,kb_min,-1 ;
do i=is,ie ;
if (do_i(i))
then 423 maxf(i,k) = min(maxf(i,k),dsp1_ds(i,k+1)*maxf(i,k+1) + htot(i))
424 htot(i) = htot(i) + (h(i,j,k) - angstrom)
427 if ((maxf(i,k) < f_kb(i)) .or. (maxf(i,k) < maxf_kb(i)) &
428 .and. (eakb_maxf(i) <= max_eakb(i)))
then 433 if ((f_kb(i) <= maxf_kb(i)) .and. (eakb_maxf(i) <= max_eakb(i)))
then 434 eakb(i) = eakb_maxf(i)
436 eakb(i) = max_eakb(i)
438 call f_kb_to_ea_kb(h_bl, sref, ent_bl, i_dskbp1, f_kb, kmb, i, &
439 g, gv, cs, eakb, angstrom)
440 if ((eakb(i) < max_eakb(i)) .or. (eakb(i) < min_eakb(i)))
then 441 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, zeros, &
442 eakb, eakb, kmb, i, i, do_i, g, gv, cs, eakb, &
444 if (eakb(i) < max_eakb(i))
then 445 max_eakb(i) = eakb(i) ; err_max_eakb0(i) = err_eakb0(i)
447 if (eakb(i) < min_eakb(i))
then 448 min_eakb(i) = eakb(i) ; err_min_eakb0(i) = err_eakb0(i)
453 endif ;
enddo ;
enddo 454 if (.not.cs%bulkmixedlayer)
then 456 maxf(i,1) = min(maxf(i,1),dsp1_ds(i,2)*maxf(i,2) + htot(i))
467 f(i,nz) = maxf(i,nz) ; minf(i,nz) = 0.0
471 if ((k==kb(i)) .and. (do_i(i)))
then 472 eakb(i) = min_eakb(i)
474 elseif ((k>kb(i)) .and. (do_i(i)))
then 479 hm = h(i,j,k) + h_neglect
482 f(i,k) = min(maxf(i,k), sqrt(ds_dsp1(i,k)*dtkd(i,k)), &
483 0.5*(ds_dsp1(i,k)+1.0) * (dtkd(i,k) / hm))
488 fk = dtkd(i,k) * grats(i,k)
489 minf(i,k) = min(maxf(i,k), &
490 0.9*(i2p2dsp1_ds(i,k) * fk / (hm + sqrt(hm*hm + fk))))
491 if (k==kb(i)) minf(i,k) = 0.0
501 is1 = ie+1 ; ie1 = is-1
502 do i=is,ie ;
if (do_i(i))
then ; is1 = i ;
exit ;
endif ;
enddo 503 do i=ie,is,-1 ;
if (do_i(i))
then ; ie1 = i ;
exit ;
endif ;
enddo 505 if (cs%bulkmixedlayer)
then 508 if (do_i(i) .and. (kb(i) < kb_min_act)) kb_min_act = kb(i)
515 if (do_i(i) .and. (kb(i) < nz)) &
516 ea_kbp1(i) = dsp1_ds(i,kb(i)+1)*f(i,kb(i)+1)
518 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, min_eakb, &
519 max_eakb, kmb, is1, ie1, do_i, g, gv, cs, eakb, f_kb=f_kb, &
520 err_max_eakb0=err_max_eakb0, err_min_eakb0=err_min_eakb0, &
526 do it=0,cs%max_ent_it-1
527 do i=is1,ie1 ;
if (do_i(i))
then 528 if (.not.cs%bulkmixedlayer) f(i,1) = min(f(i,1),maxf(i,1))
534 do k=kb_min_act,nz-1 ;
do i=is1,ie1 ;
if (do_i(i) .and. (k>=kb(i)))
then 536 if (cs%bulkmixedlayer .and. (k==kb(i)))
then 538 dfdfm(i,k) = dfdfm_kb(i)
541 fm = (f(i,k-1) - h(i,j,k)) + dsp1_ds(i,k+1)*f(i,k+1)
542 fk = grats(i,k)*dtkd(i,k)
543 fr = sqrt(fm*fm + fk)
546 f(i,k) = min(maxf(i,k), i2p2dsp1_ds(i,k) * (fm+fr))
548 f(i,k) = min(maxf(i,k), i2p2dsp1_ds(i,k) * (fk / (-1.0*fm+fr)))
551 if ((f(i,k) >= maxf(i,k)) .or. (fr == 0.0))
then 554 dfdfm(i,k) = i2p2dsp1_ds(i,k) * ((fr + fm) / fr)
559 c1(i,k) = dfdfm(i,k-1)*(dsp1_ds(i,k)*b1(i))
560 b1(i) = 1.0 / (1.0 - c1(i,k)*dfdfm(i,k))
561 f(i,k) = min(b1(i)*(f(i,k)-fprev(i,k)) + fprev(i,k), maxf(i,k))
562 if (f(i,k) >= maxf(i,k)) dfdfm(i,k) = 0.0
565 endif ;
enddo ;
enddo 567 do k=nz-2,kb_min_act,-1 ;
do i=is1,ie1
568 if (do_i(i) .and. (k > kb(i))) &
569 f(i,k) = min((f(i,k)+c1(i,k+1)*(f(i,k+1)-fprev(i,k+1))),maxf(i,k))
572 if (cs%bulkmixedlayer)
then 574 if (do_i(i) .and. (kb(i) < nz))
then 576 ea_kbp1(i) = dsp1_ds(i,kb(i)+1)*max(f(i,kb(i)+1), minf(i,kb(i)+1))
581 call determine_ea_kb(h_bl, dtkd_kb, sref, i_dskbp1, ent_bl, ea_kbp1, min_eakb, &
582 max_eakb, kmb, is1, ie1, do_i, g, gv, cs, eakb, f_kb=f_kb, &
583 err_max_eakb0=err_max_eakb0, err_min_eakb0=err_min_eakb0, &
586 if (do_i(i) .and. (kb(i) < nz)) f(i,kb(i)) = f_kb(i)
591 if (it < cs%max_ent_it-1)
then 594 if (cs%bulkmixedlayer)
then ;
do i=is1,ie1 ;
if (do_i(i))
then 595 eb_kmb(i) = max(2.0*ent_bl(i,kmb+1) - eakb(i), 0.0)
596 endif ;
enddo ;
endif 598 did_i(i) = do_i(i) ; do_i(i) = .false.
600 do k=kb_min_act,nz-1 ;
do i=is1,ie1
601 if (did_i(i) .and. (k >= kb(i)))
then 602 if (f(i,k) < minf(i,k))
then 604 do_i(i) = .true. ; reiterate = .true.
605 elseif (k > kb(i))
then 606 if ((abs(f(i,k) - fprev(i,k)) > tolerance) .or. &
607 ((h(i,j,k) + ((1.0+dsp1_ds(i,k))*f(i,k) - &
608 (f(i,k-1) + dsp1_ds(i,k+1)*f(i,k+1)))) < 0.9*angstrom))
then 609 do_i(i) = .true. ; reiterate = .true.
615 if (h(i,j,k) + ((f(i,k) + eakb(i)) - &
616 (eb_kmb(i) + dsp1_ds(i,k+1)*f(i,k+1))) < 0.9*angstrom)
then 617 do_i(i) = .true. ; reiterate = .true.
622 if (.not.reiterate)
exit 628 if (it == (cs%max_ent_it))
then 631 do i=is1,ie1 ;
if (do_i(i))
then 632 f(i,nz-1) = max(f(i,nz-1), min(minf(i,nz-1), 0.0))
633 if (kb(i) >= nz-1)
then ; ea_kbp1(i) = 0.0 ;
endif 635 do k=nz-2,kb_min_act,-1 ;
do i=is1,ie1 ;
if (do_i(i))
then 637 f(i,k) = min(max(minf(i,k),f(i,k)), (dsp1_ds(i,k+1)*f(i,k+1) + &
638 max(((f(i,k+1)-dsp1_ds(i,k+2)*f(i,k+2)) + &
639 (h(i,j,k+1) - angstrom)), 0.5*(h(i,j,k+1)-angstrom))))
640 elseif (k==kb(i))
then 641 ea_kbp1(i) = dsp1_ds(i,k+1)*f(i,k+1)
642 h_avail = dsp1_ds(i,k+1)*f(i,k+1) + max(0.5*(h(i,j,k+1)-angstrom), &
643 ((f(i,k+1)-dsp1_ds(i,k+2)*f(i,k+2)) + (h(i,j,k+1) - angstrom)))
644 if ((f(i,k) > 0.0) .and. (f(i,k) > h_avail))
then 645 f_kb(i) = max(0.0, h_avail)
647 if ((f_kb(i) < maxf_kb(i)) .and. (eakb_maxf(i) <= eakb(i))) &
648 eakb(i) = eakb_maxf(i)
649 call f_kb_to_ea_kb(h_bl, sref, ent_bl, i_dskbp1, f_kb, kmb, i, &
653 endif ;
enddo ;
enddo 656 if (cs%bulkmixedlayer)
then ;
do i=is1,ie1
657 if (do_i(i) .and. (kb(i) < nz))
then 658 h_avail = eakb(i) + max(0.5*(h_bl(i,kmb+1)-angstrom), &
659 (f_kb(i)-ea_kbp1(i)) + (h_bl(i,kmb+1)-angstrom))
661 ent_bl(i,kmb+1) = min(ent_bl(i,kmb+1),0.5*(eakb(i) + h_avail))
663 eb_kmb(i) = max(2.0*ent_bl(i,kmb+1) - eakb(i), 0.0)
668 do k=kb_min_act+1,nz-1 ;
do i=is1,ie1 ;
if (do_i(i))
then 669 if ((.not.cs%bulkmixedlayer) .or. (k > kb(i)+1))
then 670 f(i,k) = min(f(i,k), ds_dsp1(i,k)*( ((f(i,k-1) + &
671 dsp1_ds(i,k-1)*f(i,k-1)) - f(i,k-2)) + (h(i,j,k-1) - angstrom)))
672 f(i,k) = max(f(i,k),min(minf(i,k),0.0))
673 elseif (k == kb(i)+1)
then 674 f(i,k) = min(f(i,k), ds_dsp1(i,k)*( ((f(i,k-1) + eakb(i)) - &
675 eb_kmb(i)) + (h(i,j,k-1) - angstrom)))
676 f(i,k) = max(f(i,k),min(minf(i,k),0.0))
678 endif ;
enddo ;
enddo 681 call f_to_ent(f, h, kb, kmb, j, g, gv, cs, dsp1_ds, eakb, ent_bl, ea, eb)
685 if (
associated(tv%eqn_of_state))
then 687 h_guess(i,1) = (h(i,j,1) - angstrom) + (eb(i,j,1) - ea(i,j,2))
688 h_guess(i,nz) = (h(i,j,nz) - angstrom) + (ea(i,j,nz) - eb(i,j,nz-1))
689 if (h_guess(i,1) < 0.0) h_guess(i,1) = 0.0
690 if (h_guess(i,nz) < 0.0) h_guess(i,nz) = 0.0
692 do k=2,nz-1 ;
do i=is,ie
693 h_guess(i,k) = (h(i,j,k) - angstrom) + ((ea(i,j,k) - eb(i,j,k-1)) + &
694 (eb(i,j,k) - ea(i,j,k+1)))
695 if (h_guess(i,k) < 0.0) h_guess(i,k) = 0.0
697 if (cs%bulkmixedlayer)
then 698 call determine_dskb(h_bl, sref, ent_bl, eakb, is, ie, kmb, g, gv, &
699 .true., ds_kb, ds_anom_lim=ds_anom_lim)
701 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pres, rcv, tv%eqn_of_state, eosdom)
703 if ((k>kb(i)) .and. (f(i,k) > 0.0))
then 710 f_cor = h(i,j,k) * min(1.0 , max(-ds_dsp1(i,k), &
711 (gv%Rlay(k) - rcv(i)) / (gv%Rlay(k+1)-gv%Rlay(k))) )
717 if (f_cor > 0.0)
then 718 f_cor = min(f_cor, 0.9*f(i,k), ds_dsp1(i,k)*0.5*h_guess(i,k), &
721 f_cor = -min(-f_cor, 0.9*f(i,k), 0.5*h_guess(i,k), &
722 0.25*ds_dsp1(i,k)*h_guess(i,k-1) )
725 ea(i,j,k) = ea(i,j,k) - dsp1_ds(i,k)*f_cor
726 eb(i,j,k) = eb(i,j,k) + f_cor
727 elseif ((k==kb(i)) .and. (f(i,k) > 0.0))
then 731 ds_kb_eff = 2.0*ds_kb(i) - ds_anom_lim(i)
732 rho_cor = h(i,j,k) * (gv%Rlay(k)-rcv(i)) + eakb(i)*ds_anom_lim(i)
735 if (abs(rho_cor) < abs(0.9*eakb(i)*ds_kb_eff))
then 736 ea_cor = -rho_cor / ds_kb_eff
738 ea_cor = sign(0.9*eakb(i),-rho_cor*ds_kb_eff)
741 if (ea_cor > 0.0)
then 743 ea_cor = min(ea_cor, 0.5*(max_eakb(i) - eakb(i)), &
744 0.5*h_guess(i,k) / (ds_kb(i) * i_dskbp1(i)))
747 ea_cor = -min(-ea_cor, 0.5*h_guess(i,k), &
748 0.25*h_guess(i,k+1) / (ds_kb(i) * i_dskbp1(i)))
751 ea(i,j,k) = ea(i,j,k) + ea_cor
752 eb(i,j,k) = eb(i,j,k) - (ds_kb(i) * i_dskbp1(i)) * ea_cor
753 elseif (k < kb(i))
then 755 ea(i,j,k) = ea(i,j,k+1)
759 do k=kb_min-1,k2,-1 ;
do i=is,ie
760 ea(i,j,k) = ea(i,j,k+1)
768 h1 = (h(i,j,k) - angstrom) + (eb(i,j,k) - ea(i,j,k+1))
769 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
771 do k=kmb-1,2,-1 ;
do i=is,ie
773 eb(i,j,k) = max(2.0*ent_bl(i,k+1) - ea(i,j,k+1), 0.0)
776 h1 = (h(i,j,k) - angstrom) + (eb(i,j,k) - ea(i,j,k+1))
777 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
780 eb(i,j,1) = max(2.0*ent_bl(i,2) - ea(i,j,2), 0.0)
785 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pres, rcv, tv%eqn_of_state, eosdom)
786 do i=is,ie ;
if (f(i,k) > 0.0)
then 791 f_cor = h(i,j,k) * min(dsp1_ds(i,k) , max(-1.0, &
792 (gv%Rlay(k) - rcv(i)) / (gv%Rlay(k+1)-gv%Rlay(k))) )
798 if (f_cor >= 0.0)
then 799 f_cor = min(f_cor, 0.9*f(i,k), 0.5*dsp1_ds(i,k)*h_guess(i,k), &
802 f_cor = -min(-f_cor, 0.9*f(i,k), 0.5*h_guess(i,k), &
803 0.25*ds_dsp1(i,k)*h_guess(i,k-1) )
806 ea(i,j,k) = ea(i,j,k) - dsp1_ds(i,k)*f_cor
807 eb(i,j,k) = eb(i,j,k) + f_cor
814 if (cs%id_Kd > 0)
then 815 idt = gv%H_to_Z**2 / dt
816 do k=2,nz-1 ;
do i=is,ie
817 if (k<kb(i))
then ; kd_here = 0.0 ;
else 818 kd_here = f(i,k) * ( h(i,j,k) + ((ea(i,j,k) - eb(i,j,k-1)) + &
819 (eb(i,j,k) - ea(i,j,k+1))) ) / (i2p2dsp1_ds(i,k) * grats(i,k))
822 kd_eff(i,j,k) = max(dtkd(i,k), kd_here)*idt
825 kd_eff(i,j,1) = dtkd(i,1)*idt
826 kd_eff(i,j,nz) = dtkd(i,nz)*idt
830 if (cs%id_diff_work > 0)
then 831 g_2dt = 0.5 * gv%H_to_Z**2*us%L_to_Z**2 * (gv%g_Earth / dt)
832 do i=is,ie ; diff_work(i,j,1) = 0.0 ; diff_work(i,j,nz+1) = 0.0 ;
enddo 833 if (
associated(tv%eqn_of_state))
then 834 if (
associated(fluxes%p_surf))
then 835 do i=is,ie ; pressure(i) = fluxes%p_surf(i,j) ;
enddo 837 do i=is,ie ; pressure(i) = 0.0 ;
enddo 840 do i=is,ie ; pressure(i) = pressure(i) + (gv%g_Earth*gv%H_to_RZ)*h(i,j,k-1) ;
enddo 843 t_eos(i) = 0.5*(tv%T(i,j,kmb) + tv%T(i,j,k))
844 s_eos(i) = 0.5*(tv%S(i,j,kmb) + tv%S(i,j,k))
846 t_eos(i) = 0.5*(tv%T(i,j,k-1) + tv%T(i,j,k))
847 s_eos(i) = 0.5*(tv%S(i,j,k-1) + tv%S(i,j,k))
851 tv%eqn_of_state, eosdom)
853 if ((k>kmb) .and. (k<kb(i)))
then ; diff_work(i,j,k) = 0.0
856 drho = drho_dt(i) * (tv%T(i,j,k)-tv%T(i,j,kmb)) + &
857 drho_ds(i) * (tv%S(i,j,k)-tv%S(i,j,kmb))
859 drho = drho_dt(i) * (tv%T(i,j,k)-tv%T(i,j,k-1)) + &
860 drho_ds(i) * (tv%S(i,j,k)-tv%S(i,j,k-1))
862 diff_work(i,j,k) = g_2dt * drho * &
863 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
864 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
869 do k=2,nz ;
do i=is,ie
870 diff_work(i,j,k) = g_2dt * (gv%Rlay(k)-gv%Rlay(k-1)) * &
871 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
872 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
877 if (
present(kb_out))
then 878 do i=is,ie ; kb_out(i,j) = kb(i) ;
enddo 884 if (cs%id_Kd > 0)
call post_data(cs%id_Kd, kd_eff, cs%diag)
885 if (cs%id_Kd > 0)
deallocate(kd_eff)
886 if (cs%id_diff_work > 0)
call post_data(cs%id_diff_work, diff_work, cs%diag)
887 if (cs%id_diff_work > 0)
deallocate(diff_work)
889 end subroutine entrainment_diffusive
894 subroutine f_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb, do_i_in)
897 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: F
901 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
903 integer,
dimension(SZI_(G)),
intent(in) :: kb
905 integer,
intent(in) :: kmb
906 integer,
intent(in) :: j
908 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: dsp1_ds
912 real,
dimension(SZI_(G)),
intent(in) :: eakb
914 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Ent_bl
917 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
920 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
923 logical,
dimension(SZI_(G)), &
924 optional,
intent(in) :: do_i_in
931 logical :: do_i(szi_(g))
932 integer :: i, k, is, ie, nz
934 is = g%isc ; ie = g%iec ; nz = g%ke
936 if (
present(do_i_in))
then 937 do i=is,ie ; do_i(i) = do_i_in(i) ;
enddo 938 do i=g%isc,g%iec ;
if (do_i(i))
then 941 do i=g%iec,g%isc,-1 ;
if (do_i(i))
then 945 do i=is,ie ; do_i(i) = .true. ;
enddo 949 ea(i,j,nz) = 0.0 ; eb(i,j,nz) = 0.0
951 if (cs%bulkmixedlayer)
then 953 eb(i,j,kmb) = max(2.0*ent_bl(i,kmb+1) - eakb(i), 0.0)
955 do k=nz-1,kmb+1,-1 ;
do i=is,ie ;
if (do_i(i))
then 959 ea(i,j,k) = dsp1_ds(i,k)*f(i,k)
961 elseif (k == kb(i))
then 964 elseif (k == kb(i)-1)
then 965 ea(i,j,k) = ea(i,j,k+1)
966 eb(i,j,k) = eb(i,j,kmb)
968 ea(i,j,k) = ea(i,j,k+1)
971 eb(i,j,k) = eb(i,j,k+1) + max(0.0, h(i,j,k+1) - gv%Angstrom_H)
973 endif ;
enddo ;
enddo 975 do i=is,ie ;
if (do_i(i))
then 979 eb(i,j,k) = eb(i,j,k+1) + max(0.0, h(i,j,k+1) - gv%Angstrom_H)
982 h1 = (h(i,j,k) - gv%Angstrom_H) + (eb(i,j,k) - ea(i,j,k+1))
983 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
985 do k=kmb-1,2,-1 ;
do i=is,ie ;
if (do_i(i))
then 987 eb(i,j,k) = max(2.0*ent_bl(i,k+1) - ea(i,j,k+1), 0.0)
990 h1 = (h(i,j,k) - gv%Angstrom_H) + (eb(i,j,k) - ea(i,j,k+1))
991 ea(i,j,k) = max(ent_bl(i,k), ent_bl(i,k)-0.5*h1, -h1)
995 endif ;
enddo ;
enddo 996 do i=is,ie ;
if (do_i(i))
then 997 eb(i,j,1) = max(2.0*ent_bl(i,2) - ea(i,j,2), 0.0)
1005 ea(i,j,1) = 0.0 ; eb(i,j,1) = max(f(i,1),0.0)
1006 ea(i,j,2) = dsp1_ds(i,2)*f(i,2) - min(f(i,1),0.0)
1009 do k=2,nz-1 ;
do i=is,ie
1010 eb(i,j,k) = max(f(i,k),0.0)
1011 ea(i,j,k+1) = dsp1_ds(i,k+1)*f(i,k+1) - (f(i,k)-eb(i,j,k))
1012 if (ea(i,j,k+1) < 0.0)
then 1013 eb(i,j,k) = eb(i,j,k) - ea(i,j,k+1)
1018 end subroutine f_to_ent
1024 subroutine set_ent_bl(h, dtKd_int, tv, kb, kmb, do_i, G, GV, US, CS, j, Ent_bl, Sref, h_bl)
1027 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
1029 real,
dimension(SZI_(G),SZK_(G)+1), &
1030 intent(in) :: dtKd_int
1036 integer,
dimension(SZI_(G)),
intent(inout) :: kb
1039 integer,
intent(in) :: kmb
1040 logical,
dimension(SZI_(G)),
intent(in) :: do_i
1044 integer,
intent(in) :: j
1045 real,
dimension(SZI_(G),SZK_(G)+1), &
1046 intent(out) :: Ent_bl
1049 real,
dimension(SZI_(G),SZK_(G)),
intent(out) :: Sref
1051 real,
dimension(SZI_(G),SZK_(G)),
intent(out) :: h_bl
1060 real,
dimension(SZI_(G)) :: &
1067 real,
dimension(SZI_(G), SZK_(G)) :: &
1076 integer,
dimension(2) :: EOSdom
1077 integer :: i, k, is, ie, nz
1078 is = g%isc ; ie = g%iec ; nz = g%ke
1081 max_ent = 1.0e4*gv%m_to_H
1082 h_neglect = gv%H_subroundoff
1084 do i=is,ie ; pres(i) = tv%P_Ref ;
enddo 1085 eosdom(:) = eos_domain(g%HI)
1087 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pres, rcv, tv%eqn_of_state, eosdom)
1089 h_bl(i,k) = h(i,j,k) + h_neglect
1090 sref(i,k) = rcv(i) - cs%Rho_sig_off
1095 h_interior(i) = 0.0 ; ent_bl(i,1) = 0.0
1099 do k=2,kmb ;
do i=is,ie
1101 ent_bl(i,k) = min(2.0 * dtkd_int(i,k) / (h(i,j,k-1) + h(i,j,k) + h_neglect), &
1103 else ; ent_bl(i,k) = 0.0 ;
endif 1112 b1(i) = 1.0 / (h_bl(i,1) + ent_bl(i,2))
1113 d1(i) = h_bl(i,1) * b1(i)
1114 s_est(i,1) = (h_bl(i,1)*sref(i,1)) * b1(i)
1116 do k=2,kmb-1 ;
do i=is,ie
1117 b1(i) = 1.0 / ((h_bl(i,k) + ent_bl(i,k+1)) + d1(i)*ent_bl(i,k))
1118 d1(i) = (h_bl(i,k) + d1(i)*ent_bl(i,k)) * b1(i)
1119 s_est(i,k) = (h_bl(i,k)*sref(i,k) + ent_bl(i,k)*s_est(i,k-1)) * b1(i)
1122 s_est(i,kmb) = (h_bl(i,kmb)*sref(i,kmb) + ent_bl(i,kmb)*s_est(i,kmb-1)) / &
1123 (h_bl(i,kmb) + d1(i)*ent_bl(i,kmb))
1129 do i=is,ie ; kb(i) = nz+1 ;
if (do_i(i)) kb(i) = kmb+1 ;
enddo 1131 do k=kmb+1,nz ;
do i=is,ie ;
if (do_i(i))
then 1132 if ((k == kb(i)) .and. (s_est(i,kmb) > (gv%Rlay(k) - cs%Rho_sig_off)))
then 1133 if (4.0*dtkd_int(i,kmb+1)*frac_rem(i) > &
1134 (h_bl(i,kmb) + h(i,j,k)) * (h(i,j,k) - gv%Angstrom_H))
then 1136 dh = max((h(i,j,k) - gv%Angstrom_H), 0.0)
1138 frac_rem(i) = frac_rem(i) - ((h_bl(i,kmb) + h(i,j,k)) * dh) / &
1139 (4.0*dtkd_int(i,kmb+1))
1140 sref(i,kmb) = (h_bl(i,kmb)*sref(i,kmb) + dh*(gv%Rlay(k)-cs%Rho_sig_off)) / &
1142 h_bl(i,kmb) = h_bl(i,kmb) + dh
1143 s_est(i,kmb) = (h_bl(i,kmb)*sref(i,kmb) + ent_bl(i,kmb)*s_est(i,kmb-1)) / &
1144 (h_bl(i,kmb) + d1(i)*ent_bl(i,kmb))
1149 endif ;
enddo ;
enddo 1153 do k=nz,kmb+1,-1 ;
do i=is,ie
1154 if (k >= kb(i)) h_interior(i) = h_interior(i) + (h(i,j,k)-gv%Angstrom_H)
1156 h_bl(i,kmb+1) = h(i,j,k) ; sref(i,kmb+1) = gv%Rlay(k) - cs%Rho_sig_off
1157 elseif (k==kb(i)+1)
then 1158 h_bl(i,kmb+2) = h(i,j,k) ; sref(i,kmb+2) = gv%Rlay(k) - cs%Rho_sig_off
1161 do i=is,ie ;
if (kb(i) >= nz)
then 1162 h_bl(i,kmb+1) = h(i,j,nz)
1163 sref(i,kmb+1) = gv%Rlay(nz) - cs%Rho_sig_off
1164 h_bl(i,kmb+2) = gv%Angstrom_H
1165 sref(i,kmb+2) = sref(i,kmb+1) + (gv%Rlay(nz) - gv%Rlay(nz-1))
1171 do i=is,ie ;
if (do_i(i))
then 1172 kd_x_dt = frac_rem(i) * dtkd_int(i,kmb+1)
1173 if ((kd_x_dt <= 0.0) .or. (h_interior(i) <= 0.0))
then 1174 ent_bl(i,kmb+1) = 0.0
1178 ent_bl(i,kmb+1) = min(0.5*h_interior(i), sqrt(kd_x_dt), &
1179 kd_x_dt / (0.5*(h_bl(i,kmb) + h_bl(i,kmb+1))))
1182 ent_bl(i,kmb+1) = 0.0
1185 end subroutine set_ent_bl
1199 subroutine determine_dskb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, &
1200 dSkb, ddSkb_dE, dSlay, ddSlay_dE, dS_anom_lim, do_i_in)
1204 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: h_bl
1205 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Sref
1206 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Ent_bl
1209 real,
dimension(SZI_(G)),
intent(in) :: E_kb
1211 integer,
intent(in) :: is
1212 integer,
intent(in) :: ie
1213 integer,
intent(in) :: kmb
1214 logical,
intent(in) :: limit
1216 real,
dimension(SZI_(G)),
intent(inout) :: dSkb
1221 real,
dimension(SZI_(G)),
optional,
intent(inout) :: ddSkb_dE
1223 real,
dimension(SZI_(G)),
optional,
intent(inout) :: dSlay
1226 real,
dimension(SZI_(G)),
optional,
intent(inout) :: ddSlay_dE
1228 real,
dimension(SZI_(G)),
optional,
intent(inout) :: dS_anom_lim
1231 logical,
dimension(SZI_(G)),
optional,
intent(in) :: do_i_in
1251 real,
dimension(SZI_(G),SZK_(G)) :: &
1256 real :: deriv_dSkb(szi_(g))
1261 logical,
dimension(SZI_(G)) :: do_i
1268 real :: dS_kbp1, IdS_kbp1
1271 real :: f1, df1_drat
1272 real :: z, dz_drat, f2, df2_dz, expz
1273 real :: eps_dSLay, eps_dSkb
1276 if (
present(ddslay_de) .and. .not.
present(dslay))
call mom_error(fatal, &
1277 "In deterimine_dSkb, ddSLay_dE may only be present if dSlay is.")
1279 h_neglect = gv%H_subroundoff
1282 ea(i,kmb+1) = e_kb(i) ; dea_de(i,kmb+1) = 1.0
1283 s(i,kmb+1) = sref(i,kmb+1) ; ds_de(i,kmb+1) = 0.0
1288 if (
present(do_i_in))
then 1289 do i=is,ie ; do_i(i) = do_i_in(i) ;
enddo 1291 do k=kmb,1,-1 ;
do i=is,ie
1295 if (2.0*ent_bl(i,k+1) > ea(i,k+1))
then 1296 eb(i,k) = 2.0*ent_bl(i,k+1) - ea(i,k+1) ; deb_de(i,k) = -dea_de(i,k+1)
1298 eb(i,k) = 0.0 ; deb_de(i,k) = 0.0
1302 h1 = (h_bl(i,k) - gv%Angstrom_H) + (eb(i,k) - ea(i,k+1))
1304 ea(i,k) = ent_bl(i,k) ; dea_de(i,k) = 0.0
1305 elseif (ent_bl(i,k) + 0.5*h1 >= 0.0)
then 1306 ea(i,k) = ent_bl(i,k) - 0.5*h1
1307 dea_de(i,k) = 0.5*(dea_de(i,k+1) - deb_de(i,k))
1310 dea_de(i,k) = dea_de(i,k+1) - deb_de(i,k)
1313 ea(i,k) = 0.0 ; dea_de(i,k) = 0.0 ; eb(i,k) = 0.0 ; deb_de(i,k) = 0.0
1317 h_tr = h_bl(i,k) + h_neglect
1318 c1(i,k) = ea(i,k+1) * b1(i,k+1)
1319 b_denom_1 = (h_tr + d1(i)*eb(i,k))
1320 b1(i,k) = 1.0 / (b_denom_1 + ea(i,k))
1321 d1(i) = b_denom_1 * b1(i,k)
1323 s(i,k) = (h_tr*sref(i,k) + eb(i,k)*s(i,k+1)) * b1(i,k)
1325 do k=2,kmb ;
do i=is,ie
1326 s(i,k) = s(i,k) + c1(i,k-1)*s(i,k-1)
1329 if (
present(ddskb_de) .or.
present(ddslay_de))
then 1332 do k=kmb,2,-1 ;
do i=is,ie
1333 if (do_i(i) .and. (dea_de(i,k) - deb_de(i,k) > 0.0))
then 1334 src = (((s(i,k+1) - sref(i,k)) * (h_bl(i,k) + h_neglect) + &
1335 (s(i,k+1) - s(i,k-1)) * ea(i,k)) * deb_de(i,k) - &
1336 ((sref(i,k) - s(i,k-1)) * h_bl(i,k) + &
1337 (s(i,k+1) - s(i,k-1)) * eb(i,k)) * dea_de(i,k)) / &
1338 ((h_bl(i,k) + h_neglect + ea(i,k)) + eb(i,k))
1339 else ; src = 0.0 ;
endif 1340 ds_de(i,k) = (src + eb(i,k)*ds_de(i,k+1)) * b1(i,k)
1343 if (do_i(i) .and. (deb_de(i,1) < 0.0))
then 1344 src = (((s(i,2) - sref(i,1)) * (h_bl(i,1) + h_neglect)) * deb_de(i,1)) / &
1345 (h_bl(i,1) + h_neglect + eb(i,1))
1346 else ; src = 0.0 ;
endif 1347 ds_de(i,1) = (src + eb(i,1)*ds_de(i,2)) * b1(i,1)
1349 do k=2,kmb ;
do i=is,ie
1350 ds_de(i,k) = ds_de(i,k) + c1(i,k-1)*ds_de(i,k-1)
1357 if (.not.limit)
then 1358 do i=is,ie ;
if (do_i(i))
then 1359 dskb(i) = sref(i,kmb+1) - s(i,kmb)
1361 if (
present(ddskb_de))
then ;
do i=is,ie ;
if (do_i(i))
then 1362 ddskb_de(i) = -1.0*ds_de(i,kmb)
1363 endif ;
enddo ;
endif 1365 if (
present(dslay))
then ;
do i=is,ie ;
if (do_i(i))
then 1366 dslay(i) = 0.5 * (sref(i,kmb+2) - s(i,kmb))
1367 endif ;
enddo ;
endif 1368 if (
present(ddslay_de))
then ;
do i=is,ie ;
if (do_i(i))
then 1369 ddslay_de(i) = -0.5*ds_de(i,kmb)
1370 endif ;
enddo ;
endif 1372 do i=is,ie ;
if (do_i(i))
then 1374 if (sref(i,kmb+1) - s(i,kmb) < eps_dskb*(sref(i,kmb+2) - sref(i,kmb+1)))
then 1375 dskb(i) = eps_dskb * (sref(i,kmb+2) - sref(i,kmb+1)) ; deriv_dskb(i) = 0.0
1377 dskb(i) = sref(i,kmb+1) - s(i,kmb) ; deriv_dskb(i) = -1.0
1379 if (
present(ddskb_de)) ddskb_de(i) = deriv_dskb(i)*ds_de(i,kmb)
1382 if (
present(dslay))
then 1386 do i=is,ie ;
if (do_i(i))
then 1387 ds_kbp1 = sref(i,kmb+2) - sref(i,kmb+1)
1388 ids_kbp1 = 1.0 / (sref(i,kmb+2) - sref(i,kmb+1))
1389 rat = (sref(i,kmb+1) - s(i,kmb)) * ids_kbp1
1397 inv_term = 1.0 / (1.0-rat)
1398 f1 = 2.0 - 0.125*(inv_term**2)
1399 df1_drat = - 0.25*(inv_term**3)
1403 z = dz_drat * rat + 4.0
1404 if (z >= 18.0)
then ; f2 = 1.0 ; df2_dz = 0.0
1405 elseif (z <= -58.0)
then ; f2 = eps_dslay ; df2_dz = 0.0
1407 expz = exp(z) ; inv_term = 1.0 / (1.0 + expz)
1408 f2 = (eps_dslay + expz) * inv_term
1409 df2_dz = (1.0 - eps_dslay) * expz * inv_term**2
1412 dslay(i) = dskb(i) * f1 * f2
1413 deriv_dslay = deriv_dskb(i) * (f1 * f2) - (dskb(i)*ids_kbp1) * &
1414 (df1_drat*f2 + f1 * dz_drat * df2_dz)
1415 elseif (dskb(i) <= 3.0*ds_kbp1)
then 1417 dslay(i) = 0.5 * (dskb(i) + ds_kbp1)
1418 deriv_dslay = 0.5 * deriv_dskb(i)
1420 dslay(i) = 2.0*ds_kbp1
1423 if (
present(ddslay_de)) ddslay_de(i) = deriv_dslay*ds_de(i,kmb)
1428 if (
present(ds_anom_lim))
then ;
do i=is,ie ;
if (do_i(i))
then 1429 ds_anom_lim(i) = max(0.0, eps_dskb * (sref(i,kmb+2) - sref(i,kmb+1)) - &
1430 (sref(i,kmb+1) - s(i,kmb)) )
1431 endif ;
enddo ;
endif 1433 end subroutine determine_dskb
1439 subroutine f_kb_to_ea_kb(h_bl, Sref, Ent_bl, I_dSkbp1, F_kb, kmb, i, &
1440 G, GV, CS, ea_kb, tol_in)
1443 real,
dimension(SZI_(G),SZK_(G)), &
1446 real,
dimension(SZI_(G),SZK_(G)), &
1450 real,
dimension(SZI_(G),SZK_(G)), &
1451 intent(in) :: Ent_bl
1454 real,
dimension(SZI_(G)),
intent(in) :: I_dSkbp1
1457 real,
dimension(SZI_(G)),
intent(in) :: F_kb
1459 integer,
intent(in) :: kmb
1460 integer,
intent(in) :: i
1462 real,
dimension(SZI_(G)),
intent(inout) :: ea_kb
1464 real,
optional,
intent(in) :: tol_in
1467 real :: max_ea, min_ea
1468 real :: err, err_min, err_max
1470 real :: val, tolerance, tol1
1473 logical :: bisect_next, Newton
1474 real,
dimension(SZI_(G)) :: dS_kb
1475 real,
dimension(SZI_(G)) :: maxF, ent_maxF, zeros
1476 real,
dimension(SZI_(G)) :: ddSkb_dE
1478 integer,
parameter :: MAXIT = 30
1480 ds_kbp1 = sref(i,kmb+2) - sref(i,kmb+1)
1481 max_ea = ea_kb(i) ; min_ea = 0.0
1482 val = ds_kbp1 * f_kb(i)
1485 tolerance = cs%Tolerance_Ent
1486 if (
present(tol_in)) tolerance = tol_in
1487 bisect_next = .true.
1489 call determine_dskb(h_bl, sref, ent_bl, ea_kb, i, i, kmb, g, gv, .true., &
1492 err = ds_kb(i) * ea_kb(i) - val
1493 derr_dea = ds_kb(i) + ddskb_de(i) * ea_kb(i)
1496 if ((err <= 0.0) .and. (abs(err) <= tolerance*abs(derr_dea)))
return 1498 if (err == 0.0)
then ;
return 1499 elseif (err > 0.0)
then 1500 max_ea = ea_kb(i) ; err_max = err
1503 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i) - min_ea) > err) .and. &
1504 (derr_dea*(max_ea - ea_kb(i)) > -1.0*err))
then 1505 ea_kb(i) = ea_kb(i) - err / derr_dea
1507 ea_kb(i) = 0.5*(max_ea+min_ea)
1513 call find_maxf_kb(h_bl, sref, ent_bl, i_dskbp1, zeros, ea_kb, &
1514 kmb, i, i, g, gv, cs, maxf, ent_maxf, f_thresh = f_kb)
1515 err_max = ds_kbp1 * maxf(i) - val
1518 if (err_max <= 0.0)
then 1519 ea_kb(i) = ent_maxf(i) ;
return 1521 max_ea = ent_maxf(i)
1522 ea_kb(i) = 0.5*(max_ea+min_ea)
1530 call determine_dskb(h_bl, sref, ent_bl, ea_kb, i, i, kmb, g, gv, .true., &
1533 err = ds_kb(i) * ea_kb(i) - val
1534 derr_dea = ds_kb(i) + ddskb_de(i) * ea_kb(i)
1540 max_ea = ea_kb(i) ; err_max = err
1541 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i)-min_ea) > err)) newton = .true.
1543 min_ea = ea_kb(i) ; err_min = err
1544 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i)-max_ea) < err)) newton = .true.
1548 ea_kb(i) = ea_kb(i) - err / derr_dea
1549 elseif (bisect_next)
then 1550 ea_kb(i) = 0.5*(max_ea+min_ea)
1551 bisect_next = .false.
1553 ea_kb(i) = min_ea + (max_ea-min_ea) * (err_min/(err_min - err_max))
1554 bisect_next = .true.
1557 tol1 = tolerance ;
if (err > 0.0) tol1 = 0.099*tolerance
1558 if (ds_kb(i) <= ds_kbp1)
then 1559 if (abs(ea_kb(i) - ea_prev) <= tol1)
return 1561 if (ds_kbp1*abs(ea_kb(i) - ea_prev) <= ds_kb(i)*tol1)
return 1565 end subroutine f_kb_to_ea_kb
1571 subroutine determine_ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, &
1572 min_eakb, max_eakb, kmb, is, ie, do_i, G, GV, CS, Ent, &
1573 error, err_min_eakb0, err_max_eakb0, F_kb, dFdfm_kb)
1576 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: h_bl
1578 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Sref
1582 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: Ent_bl
1585 real,
dimension(SZI_(G)),
intent(in) :: I_dSkbp1
1589 real,
dimension(SZI_(G)),
intent(in) :: dtKd_kb
1592 real,
dimension(SZI_(G)),
intent(in) :: ea_kbp1
1594 real,
dimension(SZI_(G)),
intent(in) :: min_eakb
1596 real,
dimension(SZI_(G)),
intent(in) :: max_eakb
1598 integer,
intent(in) :: kmb
1599 integer,
intent(in) :: is
1600 integer,
intent(in) :: ie
1601 logical,
dimension(SZI_(G)),
intent(in) :: do_i
1604 real,
dimension(SZI_(G)),
intent(inout) :: Ent
1607 real,
dimension(SZI_(G)),
optional,
intent(out) :: error
1610 real,
dimension(SZI_(G)),
optional,
intent(in) :: err_min_eakb0
1613 real,
dimension(SZI_(G)),
optional,
intent(in) :: err_max_eakb0
1616 real,
dimension(SZI_(G)),
optional,
intent(out) :: F_kb
1620 real,
dimension(SZI_(G)),
optional,
intent(out) :: dFdfm_kb
1628 real,
dimension(SZI_(G)) :: &
1635 ddskb_de, ddslay_de, &
1640 error_mine, error_maxe
1650 logical,
dimension(SZI_(G)) :: false_position
1652 logical,
dimension(SZI_(G)) :: redo_i
1656 integer,
parameter :: MAXIT = 30
1658 if (.not.cs%bulkmixedlayer)
then 1659 call mom_error(fatal,
"determine_Ea_kb should not be called "//&
1660 "unless BULKMIXEDLAYER is defined.")
1662 tolerance = cs%Tolerance_Ent
1663 large_err = gv%m_to_H**2 * 1.0e30
1665 do i=is,ie ; redo_i(i) = do_i(i) ;
enddo 1667 do i=is,ie ;
if (do_i(i))
then 1672 e_min(i) = min_eakb(i) ; e_max(i) = max_eakb(i)
1673 error_mine(i) = -large_err ; error_maxe(i) = large_err
1674 false_position(i) = .true.
1676 if (
present(err_min_eakb0)) error_mine(i) = err_min_eakb0(i) - e_min(i) * ea_kbp1(i)
1677 if (
present(err_max_eakb0)) error_maxe(i) = err_max_eakb0(i) - e_max(i) * ea_kbp1(i)
1679 if ((error_maxe(i) <= 0.0) .or. (error_mine(i) >= 0.0))
then 1681 if (error_maxe(i) <= 0.0)
then 1683 ent(i) = e_max(i) ; err(i) = error_maxe(i)
1685 ent(i) = e_min(i) ; err(i) = error_mine(i)
1693 do_any = .false. ;
do i=is,ie ;
if (redo_i(i)) do_any = .true. ;
enddo 1694 if (.not.do_any)
exit 1695 call determine_dskb(h_bl, sref, ent_bl, ent, is, ie, kmb, g, gv, .true., ds_kb, &
1696 ddskb_de, ds_lay, ddslay_de, do_i_in = redo_i)
1697 do i=is,ie ;
if (redo_i(i))
then 1700 el = 0.0 ;
if (2.0*ent_bl(i,kmb+1) >= ent(i)) el = 1.0
1701 fa = (1.0 + el) + ds_kb(i)*i_dskbp1(i)
1702 fk = dtkd_kb(i) * (ds_lay(i)/ds_kb(i))
1703 fm = (ea_kbp1(i) - h_bl(i,kmb+1)) + el*2.0*ent_bl(i,kmb+1)
1704 if (fm > -gv%Angstrom_H) fm = fm + gv%Angstrom_H
1705 err(i) = (fa * ent(i)**2 - fm * ent(i)) - fk
1706 derror_de(i) = ((2.0*fa + (ddskb_de(i)*i_dskbp1(i))*ent(i))*ent(i) - fm) - &
1707 dtkd_kb(i) * (ddslay_de(i)*ds_kb(i) - ddskb_de(i)*ds_lay(i))/(ds_kb(i)**2)
1709 if (err(i) == 0.0)
then 1710 redo_i(i) = .false. ; cycle
1711 elseif (err(i) > 0.0)
then 1712 e_max(i) = ent(i) ; error_maxe(i) = err(i)
1714 e_min(i) = ent(i) ; error_mine(i) = err(i)
1718 if ((it == 1) .or. (derror_de(i) <= 0.0))
then 1723 fr = sqrt(fm**2 + 4.0*fa*fk)
1725 ent(i) = (fm + fr) / (2.0 * fa)
1727 ent(i) = (2.0 * fk) / (fr - fm)
1730 if ((ent(i) > e_max(i)) .or. (ent(i) < e_min(i))) &
1731 ent(i) = 0.5*(e_max(i) + e_min(i))
1732 elseif (((e_max(i)-ent(i))*derror_de(i) > -err(i)) .and. &
1733 ((ent(i)-e_min(i))*derror_de(i) > err(i)) )
then 1736 ent(i) = ent(i) - err(i) / derror_de(i)
1737 elseif (false_position(i) .and. &
1738 (error_maxe(i) - error_mine(i) < 0.9*large_err))
then 1740 ent(i) = e_min(i) + (e_max(i)-e_min(i)) * &
1741 (-error_mine(i)/(error_maxe(i) - error_mine(i)))
1742 false_position(i) = .false.
1744 ent(i) = 0.5*(e_max(i) + e_min(i))
1745 false_position(i) = .true.
1748 if (abs(e_prev - ent(i)) < tolerance)
then 1749 err_est = err(i) + (ent(i) - e_prev) * derror_de(i)
1750 if ((it > 1) .or. (err_est*err(i) <= 0.0) .or. &
1751 (abs(err_est) < abs(tolerance*derror_de(i)))) redo_i(i) = .false.
1758 if (
present(f_kb) .or.
present(dfdfm_kb)) &
1759 call determine_dskb(h_bl, sref, ent_bl, ent, is, ie, kmb, g, gv, .true., &
1760 ds_kb, do_i_in = do_i)
1762 if (
present(f_kb))
then ;
do i=is,ie ;
if (do_i(i))
then 1763 f_kb(i) = ent(i) * (ds_kb(i) * i_dskbp1(i))
1764 endif ;
enddo ;
endif 1765 if (
present(error))
then ;
do i=is,ie ;
if (do_i(i))
then 1767 endif ;
enddo ;
endif 1768 if (
present(dfdfm_kb))
then ;
do i=is,ie ;
if (do_i(i))
then 1772 if (derror_de(i) > 0.0)
then 1773 dfdfm_kb(i) = ((ds_kb(i) + ent(i) * ddskb_de(i)) * i_dskbp1(i)) * &
1774 (ent(i) / derror_de(i))
1778 endif ;
enddo ;
endif 1780 end subroutine determine_ea_kb
1783 subroutine find_maxf_kb(h_bl, Sref, Ent_bl, I_dSkbp1, min_ent_in, max_ent_in, &
1784 kmb, is, ie, G, GV, CS, maxF, ent_maxF, do_i_in, &
1785 F_lim_maxent, F_thresh)
1788 real,
dimension(SZI_(G),SZK_(G)), &
1790 real,
dimension(SZI_(G),SZK_(G)), &
1792 real,
dimension(SZI_(G),SZK_(G)), &
1793 intent(in) :: Ent_bl
1796 real,
dimension(SZI_(G)),
intent(in) :: I_dSkbp1
1800 real,
dimension(SZI_(G)),
intent(in) :: min_ent_in
1802 real,
dimension(SZI_(G)),
intent(in) :: max_ent_in
1804 integer,
intent(in) :: kmb
1805 integer,
intent(in) :: is
1806 integer,
intent(in) :: ie
1808 real,
dimension(SZI_(G)),
intent(out) :: maxF
1811 real,
dimension(SZI_(G)), &
1812 optional,
intent(out) :: ent_maxF
1813 logical,
dimension(SZI_(G)), &
1814 optional,
intent(in) :: do_i_in
1816 real,
dimension(SZI_(G)), &
1817 optional,
intent(out) :: F_lim_maxent
1821 real,
dimension(SZI_(G)), &
1822 optional,
intent(in) :: F_thresh
1832 real,
dimension(SZI_(G)) :: &
1834 minent, maxent, ent_best, &
1836 F_maxent, F_minent, F, F_best, &
1837 dF_dent, dF_dE_max, dF_dE_min, dF_dE_best, &
1838 dS_kb, dS_kb_lim, ddSkb_dE, dS_anom_lim, &
1839 chg_prev, chg_pre_prev
1840 real :: dF_dE_mean, maxslope, minslope
1842 real :: ratio_select_end
1843 real :: rat, max_chg, min_chg, chg1, chg2, chg
1844 logical,
dimension(SZI_(G)) :: do_i, last_it, need_bracket, may_use_best
1845 logical :: doany, OK1, OK2, bisect, new_min_bound
1846 integer :: i, it, is1, ie1
1847 integer,
parameter :: MAXIT = 20
1849 tolerance = cs%Tolerance_Ent
1851 if (
present(do_i_in))
then 1852 do i=is,ie ; do_i(i) = do_i_in(i) ;
enddo 1854 do i=is,ie ; do_i(i) = .true. ;
enddo 1858 call determine_dskb(h_bl, sref, ent_bl, max_ent_in, is, ie, kmb, g, gv, .false., &
1859 ds_kb, ddskb_de, ds_anom_lim=ds_anom_lim)
1860 ie1 = is-1 ; doany = .false.
1862 ds_kb_lim(i) = ds_kb(i) + ds_anom_lim(i)
1863 f_max_ent_in(i) = max_ent_in(i)*ds_kb_lim(i)*i_dskbp1(i)
1864 maxent(i) = max_ent_in(i) ; minent(i) = min_ent_in(i)
1865 if ((abs(maxent(i) - minent(i)) < tolerance) .or. (.not.do_i(i)))
then 1866 f_best(i) = max_ent_in(i)*ds_kb(i)*i_dskbp1(i)
1867 ent_best(i) = max_ent_in(i) ; ent(i) = max_ent_in(i)
1870 f_maxent(i) = maxent(i) * ds_kb(i) * i_dskbp1(i)
1871 df_de_max(i) = (ds_kb(i) + maxent(i)*ddskb_de(i)) * i_dskbp1(i)
1872 doany = .true. ; last_it(i) = .false. ; need_bracket(i) = .true.
1877 ie1 = is-1 ;
do i=is,ie ;
if (do_i(i)) ie1 = i ;
enddo 1878 do i=ie1,is,-1 ;
if (do_i(i)) is1 = i ;
enddo 1880 call determine_dskb(h_bl, sref, ent_bl, minent, is1, ie1, kmb, g, gv, .false., &
1881 ds_kb, ddskb_de, do_i_in = do_i)
1882 do i=is1,ie1 ;
if (do_i(i))
then 1883 f_minent(i) = minent(i) * ds_kb(i) * i_dskbp1(i)
1884 df_de_min(i) = (ds_kb(i) + minent(i)*ddskb_de(i)) * i_dskbp1(i)
1887 ratio_select_end = 0.9
1889 ratio_select_end = 0.5*ratio_select_end
1890 do i=is1,ie1 ;
if (do_i(i))
then 1891 if (need_bracket(i))
then 1892 df_de_mean = (f_maxent(i) - f_minent(i)) / (maxent(i) - minent(i))
1893 maxslope = max(df_de_mean, df_de_min(i), df_de_max(i))
1894 minslope = min(df_de_mean, df_de_min(i), df_de_max(i))
1895 if (f_minent(i) >= f_maxent(i))
then 1896 if (df_de_min(i) > 0.0)
then ; rat = 0.02
1897 elseif (maxslope < ratio_select_end*minslope)
then 1899 f_best(i) = f_minent(i) ; ent_best(i) = minent(i) ; rat = 0.0
1901 else ; rat = 0.382 ;
endif 1903 if (df_de_max(i) < 0.0)
then ; rat = 0.98
1904 elseif (minslope > ratio_select_end*maxslope)
then 1906 f_best(i) = f_maxent(i) ; ent_best(i) = maxent(i) ; rat = 1.0
1908 else ; rat = 0.618 ;
endif 1911 if (rat >= 0.0) ent(i) = rat*maxent(i) + (1.0-rat)*minent(i)
1912 if (((maxent(i) - minent(i)) < tolerance) .or. (it==maxit)) &
1915 chg1 = 2.0*(maxent(i) - minent(i)) ; chg2 = chg1
1916 if (df_de_best(i) > 0)
then 1917 max_chg = maxent(i) - ent_best(i) ; min_chg = 0.0
1919 max_chg = 0.0 ; min_chg = minent(i) - ent_best(i)
1921 if (max_chg - min_chg < 2.0*tolerance) last_it(i) = .true.
1922 if (df_de_max(i) /= df_de_best(i)) &
1923 chg1 = (maxent(i) - ent_best(i))*df_de_best(i) / &
1924 (df_de_best(i) - df_de_max(i))
1925 if (df_de_min(i) /= df_de_best(i)) &
1926 chg2 = (minent(i) - ent_best(i))*df_de_best(i) / &
1927 (df_de_best(i) - df_de_min(i))
1928 ok1 = ((chg1 < max_chg) .and. (chg1 > min_chg))
1929 ok2 = ((chg2 < max_chg) .and. (chg2 > min_chg))
1930 if (.not.(ok1 .or. ok2))
then ; bisect = .true. ;
else 1931 if (ok1 .and. ok2)
then 1932 chg = chg1 ;
if (abs(chg2) < abs(chg1)) chg = chg2
1933 elseif (ok1)
then ; chg = chg1
1934 else ; chg = chg2 ;
endif 1935 if (abs(chg) > 0.5*abs(chg_pre_prev(i)))
then ; bisect = .true.
1936 else ; bisect = .false. ;
endif 1938 chg_pre_prev(i) = chg_prev(i)
1940 if (df_de_best(i) > 0.0)
then 1941 ent(i) = 0.5*(maxent(i) + ent_best(i))
1942 chg_prev(i) = 0.5*(maxent(i) - ent_best(i))
1944 ent(i) = 0.5*(minent(i) + ent_best(i))
1945 chg_prev(i) = 0.5*(minent(i) - ent_best(i))
1948 if (abs(chg) < tolerance) chg = sign(tolerance,chg)
1949 ent(i) = ent_best(i) + chg
1955 if (mod(it,3) == 0)
then 1956 ie1 = is-1 ;
do i=is1,ie ;
if (do_i(i)) ie1 = i ;
enddo 1957 do i=ie1,is,-1 ;
if (do_i(i)) is1 = i ;
enddo 1960 call determine_dskb(h_bl, sref, ent_bl, ent, is1, ie1, kmb, g, gv, .false., &
1961 ds_kb, ddskb_de, do_i_in = do_i)
1962 do i=is1,ie1 ;
if (do_i(i))
then 1963 f(i) = ent(i)*ds_kb(i)*i_dskbp1(i)
1964 df_dent(i) = (ds_kb(i) + ent(i)*ddskb_de(i)) * i_dskbp1(i)
1967 if (
present(f_thresh))
then ;
do i=is1,ie1 ;
if (do_i(i))
then 1968 if (f(i) >= f_thresh(i))
then 1969 f_best(i) = f(i) ; ent_best(i) = ent(i) ; do_i(i) = .false.
1971 endif ;
enddo ;
endif 1974 do i=is1,ie1 ;
if (do_i(i))
then 1975 if (.not.last_it(i)) doany = .true.
1976 if (last_it(i))
then 1977 if (need_bracket(i))
then 1978 if ((f(i) > f_maxent(i)) .and. (f(i) > f_minent(i)))
then 1979 f_best(i) = f(i) ; ent_best(i) = ent(i)
1980 elseif (f_maxent(i) > f_minent(i))
then 1981 f_best(i) = f_maxent(i) ; ent_best(i) = maxent(i)
1983 f_best(i) = f_minent(i) ; ent_best(i) = minent(i)
1985 elseif (f(i) > f_best(i))
then 1986 f_best(i) = f(i) ; ent_best(i) = ent(i)
1989 elseif (need_bracket(i))
then 1990 if ((f(i) > f_maxent(i)) .and. (f(i) > f_minent(i)))
then 1991 need_bracket(i) = .false.
1992 chg_prev(i) = (maxent(i) - minent(i))
1993 chg_pre_prev(i) = 2.0*chg_prev(i)
1994 ent_best(i) = ent(i) ; f_best(i) = f(i) ; df_de_best(i) = df_dent(i)
1995 elseif ((f(i) <= f_maxent(i)) .and. (f(i) > f_minent(i)))
then 1996 new_min_bound = .true.
1997 elseif ((f(i) <= f_maxent(i)) .and. (f(i) > f_minent(i)))
then 1998 new_min_bound = .false.
2004 new_min_bound = .true.
2005 if (df_de_min(i) > 0.0 .or. (f_minent(i) >= f_maxent(i))) &
2006 new_min_bound = .false.
2008 if (need_bracket(i))
then 2009 if (new_min_bound)
then 2010 minent(i) = ent(i) ; f_minent(i) = f(i) ; df_de_min(i) = df_dent(i)
2012 maxent(i) = ent(i) ; f_maxent(i) = f(i) ; df_de_max(i) = df_dent(i)
2016 if (f(i) >= f_best(i))
then 2017 if (ent(i) > ent_best(i))
then 2018 minent(i) = ent_best(i) ; f_minent(i) = f_best(i) ; df_de_min(i) = df_de_best(i)
2020 maxent(i) = ent_best(i) ; f_maxent(i) = f_best(i) ; df_de_max(i) = df_de_best(i)
2022 ent_best(i) = ent(i) ; f_best(i) = f(i) ; df_de_best(i) = df_dent(i)
2024 if (ent(i) < ent_best(i))
then 2025 minent(i) = ent(i) ; f_minent(i) = f(i) ; df_de_min(i) = df_dent(i)
2027 maxent(i) = ent(i) ; f_maxent(i) = f(i) ; df_de_max(i) = df_dent(i)
2030 if ((maxent(i) - minent(i)) <= tolerance) do_i(i) = .false.
2033 if (.not.doany)
exit 2037 if (
present(f_lim_maxent))
then 2041 f_lim_maxent(i) = f_max_ent_in(i)
2042 if (
present(ent_maxf)) ent_maxf(i) = ent_best(i)
2048 may_use_best(i) = (ent_best(i) /= max_ent_in(i))
2049 if (may_use_best(i)) doany = .true.
2053 call determine_dskb(h_bl, sref, ent_bl, ent_best, is, ie, kmb, g, gv, .true., &
2056 f_best(i) = ent_best(i)*ds_kb_lim(i)*i_dskbp1(i)
2059 if ((f_best(i) > f_max_ent_in(i)) .and. (may_use_best(i)))
then 2061 if (
present(ent_maxf)) ent_maxf(i) = ent_best(i)
2063 maxf(i) = f_max_ent_in(i)
2064 if (
present(ent_maxf)) ent_maxf(i) = max_ent_in(i)
2069 do i=is,ie ; maxf(i) = f_max_ent_in(i) ;
enddo 2070 if (
present(ent_maxf))
then 2071 do i=is,ie ; ent_maxf(i) = max_ent_in(i) ;
enddo 2076 end subroutine find_maxf_kb
2080 subroutine entrain_diffusive_init(Time, G, GV, US, param_file, diag, CS, just_read_params)
2081 type(time_type),
intent(in) :: Time
2087 type(
diag_ctrl),
target,
intent(inout) :: diag
2091 logical,
optional,
intent(in) :: just_read_params
2098 logical :: just_read
2100 # include "version_variable.h" 2101 character(len=40) :: mdl =
"MOM_entrain_diffusive" 2103 if (
associated(cs))
then 2104 call mom_error(warning,
"entrain_diffusive_init called with an associated "// &
2105 "control structure.")
2110 just_read = .false. ;
if (
present(just_read_params)) just_read = just_read_params
2114 cs%bulkmixedlayer = (gv%nkml > 0)
2117 if (.not.just_read)
call log_version(param_file, mdl, version,
"")
2118 call get_param(param_file, mdl,
"MAX_ENT_IT", cs%max_ent_it, &
2119 "The maximum number of iterations that may be used to "//&
2120 "calculate the interior diapycnal entrainment.", default=5, do_not_log=just_read)
2122 call get_param(param_file, mdl,
"KD", kd, default=0.0)
2123 call get_param(param_file, mdl,
"DT", dt, &
2124 "The (baroclinic) dynamics time step.", units =
"s", &
2125 fail_if_missing=.true., do_not_log=just_read)
2126 call get_param(param_file, mdl,
"TOLERANCE_ENT", cs%Tolerance_Ent, &
2127 "The tolerance with which to solve for entrainment values.", &
2128 units=
"m", default=max(100.0*gv%Angstrom_m,1.0e-4*sqrt(dt*kd)), scale=gv%m_to_H, &
2129 do_not_log=just_read)
2131 cs%Rho_sig_off = 1000.0*us%kg_m3_to_R
2133 if (.not.just_read)
then 2134 cs%id_Kd = register_diag_field(
'ocean_model',
'Kd_effective', diag%axesTL, time, &
2135 'Diapycnal diffusivity as applied',
'm2 s-1', conversion=us%Z2_T_to_m2_s)
2136 cs%id_diff_work = register_diag_field(
'ocean_model',
'diff_work', diag%axesTi, time, &
2137 'Work actually done by diapycnal diffusion across each interface', &
2138 'W m-2', conversion=us%RZ3_T3_to_W_m2)
2141 if (just_read)
deallocate(cs)
2143 end subroutine entrain_diffusive_init
2147 subroutine entrain_diffusive_end(CS)
2150 if (
associated(cs))
deallocate(cs)
2152 end subroutine entrain_diffusive_end
This module implements boundary forcing for MOM6.
Ocean grid type. See mom_grid for details.
Calculates density of sea water from T, S and P.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
The MOM6 facility to parse input files for runtime parameters.
Make a diagnostic available for averaging or output.
Describes various unit conversion factors.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Diapycnal mixing and advection in isopycnal mode.
Routines for error handling and I/O management.
The control structure holding parametes for the MOM_entrain_diffusive module.
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Calculate the derivatives of density with temperature and salinity from T, S, and P...
Provides subroutines for quantities specific to the equation of state.
An overloaded interface to log version information about modules.
Describes the vertical ocean grid, including unit conversion factors.
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Provides a transparent vertical ocean grid type and supporting routines.
Provides transparent structures with groups of MOM6 variables and supporting routines.
An overloaded interface to read and log the values of various types of parameters.