7 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
8 use mom_cpu_clock,
only : clock_module_driver, clock_module, clock_routine
25 use time_interp_external_mod,
only : init_external_field, time_interp_external
26 use time_interp_external_mod,
only : time_interp_external_init
28 implicit none ;
private
30 #include <MOM_memory.h>
32 public diabatic_aux_init, diabatic_aux_end
33 public make_frazil, adjust_salt, differential_diffuse_t_s, tridiagts
34 public find_uv_at_h, diagnosemldbydensitydifference, applyboundaryfluxesinout, set_pen_shortwave
35 public diagnosemldbyenergy
44 logical :: do_rivermix = .false.
46 real :: rivermix_depth = 0.0
47 logical :: reclaim_frazil
50 logical :: pressure_dependent_frazil
54 logical :: ignore_fluxes_over_land
58 logical :: use_river_heat_content
61 logical :: use_calving_heat_content
68 logical :: chl_from_file
70 type(time_type),
pointer :: time => null()
74 integer :: id_createdh = -1
75 integer :: id_brine_lay = -1
76 integer :: id_pensw_diag = -1
77 integer :: id_penswflux_diag = -1
78 integer :: id_nonpensw_diag = -1
79 integer :: id_chl = -1
82 real,
allocatable,
dimension(:,:) :: createdh
84 real,
allocatable,
dimension(:,:,:) :: pensw_diag
86 real,
allocatable,
dimension(:,:,:) :: penswflux_diag
88 real,
allocatable,
dimension(:,:) :: nonpensw_diag
94 integer :: id_clock_uv_at_h, id_clock_frazil
103 subroutine make_frazil(h, tv, G, GV, US, CS, p_surf, halo)
106 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
113 real,
dimension(SZI_(G),SZJ_(G)), &
114 optional,
intent(in) :: p_surf
115 integer,
optional,
intent(in) :: halo
118 real,
dimension(SZI_(G)) :: &
122 real,
dimension(SZI_(G),SZK_(G)) :: &
128 integer :: i, j, k, is, ie, js, je, nz
130 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
131 if (
present(halo))
then
132 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
135 call cpu_clock_begin(id_clock_frazil)
137 if (.not.cs%pressure_dependent_frazil)
then
138 do k=1,nz ;
do i=is,ie ; pressure(i,k) = 0.0 ;
enddo ;
enddo
140 h_to_rl2_t2 = gv%H_to_RZ * gv%g_Earth
146 if (
PRESENT(p_surf))
then ;
do i=is,ie
150 do i=is,ie ; fraz_col(i) = 0.0 ;
enddo
152 if (cs%pressure_dependent_frazil)
then
154 pressure(i,1) = ps(i) + (0.5*h_to_rl2_t2)*h(i,j,1)
156 do k=2,nz ;
do i=is,ie
157 pressure(i,k) = pressure(i,k-1) + &
158 (0.5*h_to_rl2_t2) * (h(i,j,k) + h(i,j,k-1))
162 if (cs%reclaim_frazil)
then
164 do i=is,ie ;
if (tv%frazil(i,j) > 0.0)
then
165 if (.not.t_fr_set)
then
167 1, ie-i+1, tv%eqn_of_state, pres_scale=us%RL2_T2_to_Pa)
171 if (tv%T(i,j,1) > t_freeze(i))
then
174 hc = (tv%C_p*gv%H_to_RZ) * h(i,j,1)
175 if (tv%frazil(i,j) - hc * (tv%T(i,j,1) - t_freeze(i)) <= 0.0)
then
176 tv%T(i,j,1) = tv%T(i,j,1) - tv%frazil(i,j) / hc
179 tv%frazil(i,j) = tv%frazil(i,j) - hc * (tv%T(i,j,1) - t_freeze(i))
180 tv%T(i,j,1) = t_freeze(i)
189 if ((g%mask2dT(i,j) > 0.0) .and. &
190 ((tv%T(i,j,k) < 0.0) .or. (fraz_col(i) > 0.0)))
then
191 if (.not.t_fr_set)
then
193 1, ie-i+1, tv%eqn_of_state, pres_scale=us%RL2_T2_to_Pa)
197 hc = (tv%C_p*gv%H_to_RZ) * h(i,j,k)
198 if (h(i,j,k) <= 10.0*(gv%Angstrom_H + gv%H_subroundoff))
then
200 if (tv%T(i,j,k) < t_freeze(i))
then
201 fraz_col(i) = fraz_col(i) + hc * (t_freeze(i) - tv%T(i,j,k))
202 tv%T(i,j,k) = t_freeze(i)
204 elseif ((fraz_col(i) > 0.0) .or. (tv%T(i,j,k) < t_freeze(i)))
then
205 if (fraz_col(i) + hc * (t_freeze(i) - tv%T(i,j,k)) < 0.0)
then
206 tv%T(i,j,k) = tv%T(i,j,k) - fraz_col(i) / hc
209 fraz_col(i) = fraz_col(i) + hc * (t_freeze(i) - tv%T(i,j,k))
210 tv%T(i,j,k) = t_freeze(i)
217 tv%frazil(i,j) = tv%frazil(i,j) + fraz_col(i)
220 call cpu_clock_end(id_clock_frazil)
222 end subroutine make_frazil
226 subroutine differential_diffuse_t_s(h, T, S, Kd_T, Kd_S, dt, G, GV)
229 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
231 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
233 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
235 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
236 intent(inout) :: kd_t
239 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), &
243 real,
intent(in) :: dt
246 real,
dimension(SZI_(G)) :: &
249 real,
dimension(SZI_(G),SZK_(G)) :: &
251 real,
dimension(SZI_(G),SZK_(G)+1) :: &
261 integer :: i, j, k, is, ie, js, je, nz
263 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
264 h_neglect = gv%H_subroundoff
269 i_h_int = 1.0 / (0.5 * (h(i,j,1) + h(i,j,2)) + h_neglect)
270 mix_t(i,2) = ((dt * kd_t(i,j,2)) * gv%Z_to_H**2) * i_h_int
271 mix_s(i,2) = ((dt * kd_s(i,j,2)) * gv%Z_to_H**2) * i_h_int
273 h_tr = h(i,j,1) + h_neglect
274 b1_t(i) = 1.0 / (h_tr + mix_t(i,2))
275 b1_s(i) = 1.0 / (h_tr + mix_s(i,2))
276 d1_t(i) = h_tr * b1_t(i)
277 d1_s(i) = h_tr * b1_s(i)
278 t(i,j,1) = (b1_t(i)*h_tr)*t(i,j,1)
279 s(i,j,1) = (b1_s(i)*h_tr)*s(i,j,1)
281 do k=2,nz-1 ;
do i=is,ie
283 i_h_int = 1.0 / (0.5 * (h(i,j,k) + h(i,j,k+1)) + h_neglect)
284 mix_t(i,k+1) = ((dt * kd_t(i,j,k+1)) * gv%Z_to_H**2) * i_h_int
285 mix_s(i,k+1) = ((dt * kd_s(i,j,k+1)) * gv%Z_to_H**2) * i_h_int
287 c1_t(i,k) = mix_t(i,k) * b1_t(i)
288 c1_s(i,k) = mix_s(i,k) * b1_s(i)
290 h_tr = h(i,j,k) + h_neglect
291 b_denom_t = h_tr + d1_t(i)*mix_t(i,k)
292 b_denom_s = h_tr + d1_s(i)*mix_s(i,k)
293 b1_t(i) = 1.0 / (b_denom_t + mix_t(i,k+1))
294 b1_s(i) = 1.0 / (b_denom_s + mix_s(i,k+1))
295 d1_t(i) = b_denom_t * b1_t(i)
296 d1_s(i) = b_denom_s * b1_s(i)
298 t(i,j,k) = b1_t(i) * (h_tr*t(i,j,k) + mix_t(i,k)*t(i,j,k-1))
299 s(i,j,k) = b1_s(i) * (h_tr*s(i,j,k) + mix_s(i,k)*s(i,j,k-1))
302 c1_t(i,nz) = mix_t(i,nz) * b1_t(i)
303 c1_s(i,nz) = mix_s(i,nz) * b1_s(i)
305 h_tr = h(i,j,nz) + h_neglect
306 b1_t(i) = 1.0 / (h_tr + d1_t(i)*mix_t(i,nz))
307 b1_s(i) = 1.0 / (h_tr + d1_s(i)*mix_s(i,nz))
309 t(i,j,nz) = b1_t(i) * (h_tr*t(i,j,nz) + mix_t(i,nz)*t(i,j,nz-1))
310 s(i,j,nz) = b1_s(i) * (h_tr*s(i,j,nz) + mix_s(i,nz)*s(i,j,nz-1))
312 do k=nz-1,1,-1 ;
do i=is,ie
313 t(i,j,k) = t(i,j,k) + c1_t(i,k+1)*t(i,j,k+1)
314 s(i,j,k) = s(i,j,k) + c1_s(i,k+1)*s(i,j,k+1)
317 end subroutine differential_diffuse_t_s
322 subroutine adjust_salt(h, tv, G, GV, CS, halo)
325 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
331 integer,
optional,
intent(in) :: halo
334 real :: salt_add_col(szi_(g),szj_(g))
337 integer :: i, j, k, is, ie, js, je, nz
339 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
340 if (
present(halo))
then
341 is = g%isc-halo ; ie = g%iec+halo ; js = g%jsc-halo ; je = g%jec+halo
346 s_min = tv%min_salinity
348 salt_add_col(:,:) = 0.0
352 do k=nz,1,-1 ;
do i=is,ie
353 if ( (g%mask2dT(i,j) > 0.0) .and. &
354 ((tv%S(i,j,k) < s_min) .or. (salt_add_col(i,j) > 0.0)) )
then
355 mc = gv%H_to_RZ * h(i,j,k)
356 if (h(i,j,k) <= 10.0*gv%Angstrom_H)
then
358 if (tv%S(i,j,k) < s_min)
then
359 salt_add_col(i,j) = salt_add_col(i,j) + mc * (s_min - tv%S(i,j,k))
362 elseif (salt_add_col(i,j) + mc * (s_min - tv%S(i,j,k)) <= 0.0)
then
363 tv%S(i,j,k) = tv%S(i,j,k) - salt_add_col(i,j) / mc
364 salt_add_col(i,j) = 0.0
366 salt_add_col(i,j) = salt_add_col(i,j) + mc * (s_min - tv%S(i,j,k))
372 tv%salt_deficit(i,j) = tv%salt_deficit(i,j) + salt_add_col(i,j)
377 end subroutine adjust_salt
381 subroutine tridiagts(G, GV, is, ie, js, je, hold, ea, eb, T, S)
384 integer,
intent(in) :: is
385 integer,
intent(in) :: ie
386 integer,
intent(in) :: js
387 integer,
intent(in) :: je
388 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: hold
390 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: ea
392 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: eb
394 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: t
395 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(inout) :: s
398 real :: b1(szib_(g)), d1(szib_(g))
399 real :: c1(szib_(g),szk_(g))
400 real :: h_tr, b_denom_1
406 h_tr = hold(i,j,1) + gv%H_subroundoff
407 b1(i) = 1.0 / (h_tr + eb(i,j,1))
409 t(i,j,1) = (b1(i)*h_tr)*t(i,j,1)
410 s(i,j,1) = (b1(i)*h_tr)*s(i,j,1)
412 do k=2,g%ke ;
do i=is,ie
413 c1(i,k) = eb(i,j,k-1) * b1(i)
414 h_tr = hold(i,j,k) + gv%H_subroundoff
415 b_denom_1 = h_tr + d1(i)*ea(i,j,k)
416 b1(i) = 1.0 / (b_denom_1 + eb(i,j,k))
417 d1(i) = b_denom_1 * b1(i)
418 t(i,j,k) = b1(i) * (h_tr*t(i,j,k) + ea(i,j,k)*t(i,j,k-1))
419 s(i,j,k) = b1(i) * (h_tr*s(i,j,k) + ea(i,j,k)*s(i,j,k-1))
421 do k=g%ke-1,1,-1 ;
do i=is,ie
422 t(i,j,k) = t(i,j,k) + c1(i,k+1)*t(i,j,k+1)
423 s(i,j,k) = s(i,j,k) + c1(i,k+1)*s(i,j,k+1)
426 end subroutine tridiagts
430 subroutine find_uv_at_h(u, v, h, u_h, v_h, G, GV, US, ea, eb)
434 real,
dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
436 real,
dimension(SZI_(G),SZJB_(G),SZK_(G)), &
438 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
440 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
442 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
444 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
445 optional,
intent(in) :: ea
448 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
449 optional,
intent(in) :: eb
457 real :: b1(szi_(g)), d1(szi_(g)), c1(szi_(g),szk_(g))
458 real :: a_n(szi_(g)), a_s(szi_(g))
459 real :: a_e(szi_(g)), a_w(szi_(g))
461 real :: sum_area, idenom
462 logical :: mix_vertically
463 integer :: i, j, k, is, ie, js, je, nz
464 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
465 call cpu_clock_begin(id_clock_uv_at_h)
466 h_neglect = gv%H_subroundoff
468 mix_vertically =
present(ea)
469 if (
present(ea) .neqv.
present(eb))
call mom_error(fatal, &
470 "find_uv_at_h: Either both ea and eb or neither one must be present "// &
471 "in call to find_uv_at_h.")
477 sum_area = g%areaCu(i-1,j) + g%areaCu(i,j)
478 if (sum_area>0.0)
then
479 idenom = sqrt(0.5*g%IareaT(i,j) / sum_area)
480 a_w(i) = g%areaCu(i-1,j) * idenom
481 a_e(i) = g%areaCu(i,j) * idenom
483 a_w(i) = 0.0 ; a_e(i) = 0.0
486 sum_area = g%areaCv(i,j-1) + g%areaCv(i,j)
487 if (sum_area>0.0)
then
488 idenom = sqrt(0.5*g%IareaT(i,j) / sum_area)
489 a_s(i) = g%areaCv(i,j-1) * idenom
490 a_n(i) = g%areaCv(i,j) * idenom
492 a_s(i) = 0.0 ; a_n(i) = 0.0
496 if (mix_vertically)
then
498 b_denom_1 = h(i,j,1) + h_neglect
499 b1(i) = 1.0 / (b_denom_1 + eb(i,j,1))
500 d1(i) = b_denom_1 * b1(i)
501 u_h(i,j,1) = (h(i,j,1)*b1(i)) * (a_e(i)*u(i,j,1) + a_w(i)*u(i-1,j,1))
502 v_h(i,j,1) = (h(i,j,1)*b1(i)) * (a_n(i)*v(i,j,1) + a_s(i)*v(i,j-1,1))
504 do k=2,nz ;
do i=is,ie
505 c1(i,k) = eb(i,j,k-1) * b1(i)
506 b_denom_1 = h(i,j,k) + d1(i)*ea(i,j,k) + h_neglect
507 b1(i) = 1.0 / (b_denom_1 + eb(i,j,k))
508 d1(i) = b_denom_1 * b1(i)
509 u_h(i,j,k) = (h(i,j,k) * (a_e(i)*u(i,j,k) + a_w(i)*u(i-1,j,k)) + &
510 ea(i,j,k)*u_h(i,j,k-1))*b1(i)
511 v_h(i,j,k) = (h(i,j,k) * (a_n(i)*v(i,j,k) + a_s(i)*v(i,j-1,k)) + &
512 ea(i,j,k)*v_h(i,j,k-1))*b1(i)
514 do k=nz-1,1,-1 ;
do i=is,ie
515 u_h(i,j,k) = u_h(i,j,k) + c1(i,k+1)*u_h(i,j,k+1)
516 v_h(i,j,k) = v_h(i,j,k) + c1(i,k+1)*v_h(i,j,k+1)
519 do k=1,nz ;
do i=is,ie
520 u_h(i,j,k) = a_e(i)*u(i,j,k) + a_w(i)*u(i-1,j,k)
521 v_h(i,j,k) = a_n(i)*v(i,j,k) + a_s(i)*v(i,j-1,k)
526 call cpu_clock_end(id_clock_uv_at_h)
527 end subroutine find_uv_at_h
530 subroutine set_pen_shortwave(optics, fluxes, G, GV, US, CS, opacity_CSp, tracer_flow_CSp)
533 type(
forcing),
intent(inout) :: fluxes
544 real,
dimension(SZI_(G),SZJ_(G)) :: chl_2d
545 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: chl_3d
546 character(len=128) :: mesg
547 integer :: i, j, k, is, ie, js, je
548 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
550 if (.not.
associated(optics))
return
552 if (cs%var_pen_sw)
then
553 if (cs%chl_from_file)
then
556 call time_interp_external(cs%sbc_chl, cs%Time, chl_2d)
557 do j=js,je ;
do i=is,ie
558 if ((g%mask2dT(i,j) > 0.5) .and. (chl_2d(i,j) < 0.0))
then
559 write(mesg,
'(" Time_interp negative chl of ",(1pe12.4)," at i,j = ",&
560 & 2(i3), "lon/lat = ",(1pe12.4)," E ", (1pe12.4), " N.")') &
561 chl_2d(i,j), i, j, g%geoLonT(i,j), g%geoLatT(i,j)
562 call mom_error(fatal,
"MOM_diabatic_aux set_pen_shortwave: "//trim(mesg))
566 if (cs%id_chl > 0)
call post_data(cs%id_chl, chl_2d, cs%diag)
568 call set_opacity(optics, fluxes%sw, fluxes%sw_vis_dir, fluxes%sw_vis_dif, &
569 fluxes%sw_nir_dir, fluxes%sw_nir_dif, g, gv, us, opacity_csp, chl_2d=chl_2d)
571 if (.not.
associated(tracer_flow_csp))
call mom_error(fatal, &
572 "The tracer flow control structure must be associated when the model sets "//&
573 "the chlorophyll internally in set_pen_shortwave.")
574 call get_chl_from_model(chl_3d, g, tracer_flow_csp)
576 if (cs%id_chl > 0)
call post_data(cs%id_chl, chl_3d(:,:,1), cs%diag)
578 call set_opacity(optics, fluxes%sw, fluxes%sw_vis_dir, fluxes%sw_vis_dif, &
579 fluxes%sw_nir_dir, fluxes%sw_nir_dif, g, gv, us, opacity_csp, chl_3d=chl_3d)
582 call set_opacity(optics, fluxes%sw, fluxes%sw_vis_dir, fluxes%sw_vis_dif, &
583 fluxes%sw_nir_dir, fluxes%sw_nir_dif, g, gv, us, opacity_csp)
586 end subroutine set_pen_shortwave
591 subroutine diagnosemldbydensitydifference(id_MLD, h, tv, densityDiff, G, GV, US, diagPtr, &
592 id_N2subML, id_MLDsq, dz_subML)
596 integer,
intent(in) :: id_mld
597 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
601 real,
intent(in) :: densitydiff
603 integer,
optional,
intent(in) :: id_n2subml
604 integer,
optional,
intent(in) :: id_mldsq
605 real,
optional,
intent(in) :: dz_subml
609 real,
dimension(SZI_(G)) :: deltarhoatkm1, deltarhoatk
610 real,
dimension(SZI_(G)) :: pref_mld, pref_n2
611 real,
dimension(SZI_(G)) :: h_subml, dh_n2
612 real,
dimension(SZI_(G)) :: t_subml, t_deeper
613 real,
dimension(SZI_(G)) :: s_subml, s_deeper
614 real,
dimension(SZI_(G)) :: rho_subml, rho_deeper
615 real,
dimension(SZI_(G)) :: dk, dkm1
616 real,
dimension(SZI_(G)) :: rhosurf
617 real,
dimension(SZI_(G), SZJ_(G)) :: mld
618 real,
dimension(SZI_(G), SZJ_(G)) :: submln2
619 real,
dimension(SZI_(G), SZJ_(G)) :: mld2
620 logical,
dimension(SZI_(G)) :: n2_region_set
626 integer,
dimension(2) :: eosdom
627 integer :: i, j, is, ie, js, je, k, nz, id_n2, id_sq
629 id_n2 = -1 ;
if (
PRESENT(id_n2subml)) id_n2 = id_n2subml
631 id_sq = -1 ;
if (
PRESENT(id_mldsq)) id_sq = id_mldsq
633 ge_rho0 = us%L_to_Z**2*gv%g_Earth / (gv%Rho0)
634 dh_subml = 50.*gv%m_to_H ;
if (
present(dz_subml)) dh_subml = gv%Z_to_H*dz_subml
636 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
639 eosdom(:) = eos_domain(g%HI)
641 do i=is,ie ; dk(i) = 0.5 * h(i,j,1) * gv%H_to_Z ;
enddo
642 call calculate_density(tv%T(:,j,1), tv%S(:,j,1), pref_mld, rhosurf, tv%eqn_of_state, eosdom)
648 h_subml(i) = h(i,j,1) ; dh_n2(i) = 0.0
649 t_subml(i) = 0.0 ; s_subml(i) = 0.0 ; t_deeper(i) = 0.0 ; s_deeper(i) = 0.0
650 n2_region_set(i) = (g%mask2dT(i,j)<0.5)
656 dk(i) = dk(i) + 0.5 * ( h(i,j,k) + h(i,j,k-1) ) * gv%H_to_Z
663 if (mld(i,j)==0.0)
then
664 h_subml(i) = h_subml(i) + h(i,j,k)
665 elseif (.not.n2_region_set(i))
then
666 if (dh_n2(i)==0.0)
then
667 t_subml(i) = tv%T(i,j,k) ; s_subml(i) = tv%S(i,j,k)
668 h_subml(i) = h_subml(i) + 0.5 * h(i,j,k)
669 dh_n2(i) = 0.5 * h(i,j,k)
670 elseif (dh_n2(i) + h(i,j,k) < dh_subml)
then
671 dh_n2(i) = dh_n2(i) + h(i,j,k)
673 t_deeper(i) = tv%T(i,j,k) ; s_deeper(i) = tv%S(i,j,k)
674 dh_n2(i) = dh_n2(i) + 0.5 * h(i,j,k)
675 n2_region_set(i) = .true.
682 do i=is,ie ; deltarhoatkm1(i) = deltarhoatk(i) ;
enddo
683 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pref_mld, deltarhoatk, tv%eqn_of_state, eosdom)
685 deltarhoatk(i) = deltarhoatk(i) - rhosurf(i)
686 ddrho = deltarhoatk(i) - deltarhoatkm1(i)
687 if ((mld(i,j)==0.) .and. (ddrho>0.) .and. &
688 (deltarhoatkm1(i)<densitydiff) .and. (deltarhoatk(i)>=densitydiff))
then
689 afac = ( densitydiff - deltarhoatkm1(i) ) / ddrho
690 mld(i,j) = dk(i) * afac + dkm1(i) * (1. - afac)
692 if (id_sq > 0) mld2(i,j) = mld(i,j)**2
696 if ((mld(i,j)==0.) .and. (deltarhoatk(i)<densitydiff)) mld(i,j) = dk(i)
700 do i=is,ie ; pref_n2(i) = (gv%g_Earth * gv%H_to_RZ) * (h_subml(i) + 0.5*dh_n2(i)) ;
enddo
706 call calculate_density(t_subml, s_subml, pref_n2, rho_subml, tv%eqn_of_state, eosdom)
707 call calculate_density(t_deeper, s_deeper, pref_n2, rho_deeper, tv%eqn_of_state, eosdom)
708 do i=is,ie ;
if ((g%mask2dT(i,j)>0.5) .and. n2_region_set(i))
then
709 submln2(i,j) = ge_rho0 * (rho_deeper(i) - rho_subml(i)) / (gv%H_to_z * dh_n2(i))
714 if (id_mld > 0)
call post_data(id_mld, mld, diagptr)
715 if (id_n2 > 0)
call post_data(id_n2, submln2, diagptr)
716 if (id_sq > 0)
call post_data(id_sq, mld2, diagptr)
718 end subroutine diagnosemldbydensitydifference
722 subroutine diagnosemldbyenergy(id_MLD, h, tv, G, GV, US, Mixing_Energy, diagPtr)
744 integer,
dimension(3),
intent(in) :: id_mld
748 real,
dimension(3),
intent(in) :: mixing_energy
749 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
756 real,
dimension(SZI_(G), SZJ_(G),3) :: mld
757 real,
dimension(SZK_(G)) :: z_l, z_u, dz, rho_c, pref_mld
758 real,
dimension(3) :: pe_threshold
761 real :: pe_threshold_fraction, pe, pe_mixed, pe_mixed_tst
762 real :: rhodz_ml, h_ml, rhodz_ml_tst, h_ml_tst
765 real :: r1, d1, r2, d2
766 real :: ca, cb,d ,cc, cd, ca2, cb2, c, cc2
767 real :: gx, gpx, hx, ihx, hpx, ix, ipx, fgx, fpx, x, x2
770 integer :: i, j, is, ie, js, je, k, nz
772 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
776 pe_threshold_fraction = 1.e-4
779 pe_threshold(im) = mixing_energy(im)/gv%g_earth
782 do j=js,je;
do i=is,ie
783 if (g%mask2dT(i,j) > 0.0)
then
785 call calculate_density(tv%T(i,j,:), tv%S(i,j,:), pref_mld, rho_c, 1, nz, &
786 tv%eqn_of_state, scale=us%kg_m3_to_R)
789 dz(k) = h(i,j,k) * gv%H_to_Z
795 z_l(k) = z_l(k-1)-dz(k)
811 pe = pe + 0.5 * rho_c(k) * (z_u(k)**2 - z_l(k)**2)
814 h_ml_tst = h_ml + dz(k)
815 rhodz_ml_tst = rhodz_ml + rho_c(k) * dz(k)
818 rho_ml = rhodz_ml_tst/h_ml_tst
823 pe_mixed_tst = 0.5 * rho_ml * (0.**2 - (0. - h_ml_tst)**2)
826 if (pe_mixed_tst - pe <= pe_threshold(im))
then
828 rhodz_ml = rhodz_ml_tst
853 cb = -(r1 * d1 + r2 * (2. * d1))
855 cc = -(r1 * d1 * (2. * d1) + (r2 * d))
859 c = d2**2 + d1**2 + 2. * (d1 * d2)
874 gx = 0.5 * (ca * (x*x*x) + cb * x**2 + cc * x + cd)
875 gpx = 0.5 * (3. * (ca * x**2) + 2. * (cb * x) + cc)
881 ix = 0.5 * (ca2 * x**2 + cb2 * x + cc2)
882 ipx = 0.5 * (2. * ca2 * x + cb2)
885 pe_mixed = gx * ihx + ix
886 fgx = pe_mixed - (pe + pe_threshold(im))
887 fpx = (gpx * hx - hpx * gx) * ihx**2 + ipx
892 if (abs(fgx) > pe_threshold(im) * pe_threshold_fraction)
then
895 if (x2 < 0. .or. x2 > dz(k))
then
919 if (id_mld(1) > 0)
call post_data(id_mld(1), mld(:,:,1), diagptr)
920 if (id_mld(2) > 0)
call post_data(id_mld(2), mld(:,:,2), diagptr)
921 if (id_mld(3) > 0)
call post_data(id_mld(3), mld(:,:,3), diagptr)
923 end subroutine diagnosemldbyenergy
928 subroutine applyboundaryfluxesinout(CS, G, GV, US, dt, fluxes, optics, nsw, h, tv, &
929 aggregate_FW_forcing, evap_CFL_limit, &
930 minimum_forcing_depth, cTKE, dSV_dT, dSV_dS, &
936 real,
intent(in) :: dt
937 type(
forcing),
intent(inout) :: fluxes
939 integer,
intent(in) :: nsw
941 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
945 logical,
intent(in) :: aggregate_fw_forcing
946 real,
intent(in) :: evap_cfl_limit
948 real,
intent(in) :: minimum_forcing_depth
950 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
951 optional,
intent(out) :: ctke
953 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
954 optional,
intent(out) :: dsv_dt
956 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
957 optional,
intent(out) :: dsv_ds
959 real,
dimension(SZI_(G),SZJ_(G)), &
960 optional,
intent(out) :: skinbuoyflux
963 integer,
parameter :: maxgroundings = 5
964 integer :: numberofgroundings, iground(maxgroundings), jground(maxgroundings)
965 real :: h_limit_fluxes
966 real :: iforcingdepthscale
968 real :: dthickness, dtemp, dsalt
969 real :: fractionofforcing, hold, ithickness
970 real :: rivermixconst
972 real,
dimension(SZI_(G)) :: &
992 real,
dimension(SZI_(G), SZK_(G)) :: &
998 real,
dimension(SZI_(G)) :: &
1001 real,
dimension(max(nsw,1),SZI_(G)) :: &
1006 real,
dimension(max(nsw,1),SZI_(G),SZK_(G)) :: &
1009 real,
dimension(maxGroundings) :: hgrounding
1010 real :: temp_in, salin_in
1015 logical :: calculate_energetics
1016 logical :: calculate_buoyancy
1017 integer,
dimension(2) :: eosdom
1018 integer :: i, j, is, ie, js, je, k, nz, n, nb
1019 character(len=45) :: mesg
1021 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1025 calculate_energetics = (
present(ctke) .and.
present(dsv_dt) .and.
present(dsv_ds))
1026 calculate_buoyancy =
present(skinbuoyflux)
1027 if (calculate_buoyancy) skinbuoyflux(:,:) = 0.0
1028 if (
present(ctke)) ctke(:,:,:) = 0.0
1029 g_hconv2 = (us%L_to_Z**2*gv%g_Earth * gv%H_to_RZ) * gv%H_to_RZ
1030 eosdom(:) = eos_domain(g%HI)
1033 if (.not.
associated(fluxes%sw) .and. .not.calculate_energetics)
return
1035 if (calculate_buoyancy)
then
1036 surfpressure(:) = 0.0
1037 gorho = us%L_to_Z**2*gv%g_Earth / gv%Rho0
1045 h_limit_fluxes = max(gv%Angstrom_H, 1.e-30*gv%m_to_H)
1048 if (cs%id_createdH>0) cs%createdH(:,:) = 0.
1049 numberofgroundings = 0
1070 do k=1,nz ;
do i=is,ie
1072 t2d(i,k) = tv%T(i,j,k)
1075 if (calculate_energetics)
then
1079 if (
associated(tv%p_surf))
then
1080 do i=is,ie ; pres(i) = tv%p_surf(i,j) ;
enddo
1082 do i=is,ie ; pres(i) = 0.0 ;
enddo
1086 d_pres(i) = (gv%g_Earth * gv%H_to_RZ) * h2d(i,k)
1087 p_lay(i) = pres(i) + 0.5*d_pres(i)
1088 pres(i) = pres(i) + d_pres(i)
1091 dsv_dt(:,j,k), dsv_ds(:,j,k), tv%eqn_of_state, eosdom)
1092 do i=is,ie ; dsv_dt_2d(i,k) = dsv_dt(i,j,k) ;
enddo
1094 pen_tke_2d(:,:) = 0.0
1098 if (.not.
associated(fluxes%sw)) cycle
1100 if (nsw>0)
call extract_optics_slice(optics, j, g, gv, opacity=opacityband, opacity_scale=(1.0/gv%m_to_H))
1145 if (calculate_buoyancy)
then
1146 call extractfluxes1d(g, gv, us, fluxes, optics, nsw, j, dt, &
1147 h_limit_fluxes, cs%use_river_heat_content, cs%use_calving_heat_content, &
1148 h2d, t2d, netmassinout, netmassout, netheat, netsalt, &
1149 pen_sw_bnd, tv, aggregate_fw_forcing, nonpensw=nonpensw, &
1150 net_heat_rate=netheat_rate, net_salt_rate=netsalt_rate, &
1151 netmassinout_rate=netmassinout_rate, pen_sw_bnd_rate=pen_sw_bnd_rate)
1153 call extractfluxes1d(g, gv, us, fluxes, optics, nsw, j, dt, &
1154 h_limit_fluxes, cs%use_river_heat_content, cs%use_calving_heat_content, &
1155 h2d, t2d, netmassinout, netmassout, netheat, netsalt, &
1156 pen_sw_bnd, tv, aggregate_fw_forcing, nonpensw=nonpensw)
1161 if (aggregate_fw_forcing)
then
1162 netmassout(i) = netmassinout(i)
1165 netmassin(i) = netmassinout(i) - netmassout(i)
1167 if (g%mask2dT(i,j)>0.0)
then
1168 fluxes%netMassOut(i,j) = netmassout(i)
1169 fluxes%netMassIn(i,j) = netmassin(i)
1171 fluxes%netMassOut(i,j) = 0.0
1172 fluxes%netMassIn(i,j) = 0.0
1182 if (g%mask2dT(i,j)>0.)
then
1188 dthickness = netmassin(i)
1194 netmassin(i) = netmassin(i) - dthickness
1198 dtemp = dtemp + dthickness*temp_in
1201 if (
associated(fluxes%heat_content_massin)) &
1202 fluxes%heat_content_massin(i,j) = fluxes%heat_content_massin(i,j) + &
1203 t2d(i,k) * max(0.,dthickness) * gv%H_to_RZ * fluxes%C_p * idt
1204 if (
associated(fluxes%heat_content_massout)) &
1205 fluxes%heat_content_massout(i,j) = fluxes%heat_content_massout(i,j) + &
1206 t2d(i,k) * min(0.,dthickness) * gv%H_to_RZ * fluxes%C_p * idt
1207 if (
associated(tv%TempxPmE)) tv%TempxPmE(i,j) = tv%TempxPmE(i,j) + &
1208 t2d(i,k) * dthickness * gv%H_to_RZ
1211 if (calculate_energetics .and.
associated(fluxes%lrunoff) .and. cs%do_rivermix)
then
1222 if (gv%Boussinesq)
then
1223 rivermixconst = -0.5*(cs%rivermix_depth*dt) * ( us%L_to_Z**2*gv%g_Earth ) * gv%Rho0
1225 rivermixconst = -0.5*(cs%rivermix_depth*dt) * gv%Rho0 * ( us%L_to_Z**2*gv%g_Earth )
1227 ctke(i,j,k) = ctke(i,j,k) + max(0.0, rivermixconst*dsv_ds(i,j,1) * &
1228 (fluxes%lrunoff(i,j) + fluxes%frunoff(i,j)) * tv%S(i,j,1))
1233 h2d(i,k) = h2d(i,k) + dthickness
1234 if (h2d(i,k) > 0.0)
then
1235 if (calculate_energetics .and. (dthickness > 0.))
then
1238 ctke(i,j,k) = ctke(i,j,k) + 0.5*g_hconv2*(hold*dthickness) * &
1239 ((t2d(i,k) - temp_in) * dsv_dt(i,j,k) + (tv%S(i,j,k) - salin_in) * dsv_ds(i,j,k))
1241 ithickness = 1.0/h2d(i,k)
1243 if (dthickness /= 0. .or. dtemp /= 0.) t2d(i,k) = (hold*t2d(i,k) + dtemp)*ithickness
1244 if (dthickness /= 0. .or. dsalt /= 0.) tv%S(i,j,k) = (hold*tv%S(i,j,k) + dsalt)*ithickness
1256 iforcingdepthscale = 1. / max(gv%H_subroundoff, minimum_forcing_depth - netmassout(i) )
1258 fractionofforcing = min(1.0, h2d(i,k)*iforcingdepthscale)
1263 if (-fractionofforcing*netmassout(i) > evap_cfl_limit*h2d(i,k))
then
1264 fractionofforcing = -evap_cfl_limit*h2d(i,k)/netmassout(i)
1269 dthickness = max( fractionofforcing*netmassout(i), -h2d(i,k) )
1270 dtemp = fractionofforcing*netheat(i)
1272 dsalt = max( fractionofforcing*netsalt(i), -0.9999*h2d(i,k)*tv%S(i,j,k))
1276 netmassout(i) = netmassout(i) - dthickness
1277 netheat(i) = netheat(i) - dtemp
1278 netsalt(i) = netsalt(i) - dsalt
1281 dtemp = dtemp + dthickness*t2d(i,k)
1284 if (
associated(fluxes%heat_content_massin)) &
1285 fluxes%heat_content_massin(i,j) = fluxes%heat_content_massin(i,j) + &
1286 t2d(i,k) * max(0.,dthickness) * gv%H_to_RZ * fluxes%C_p * idt
1287 if (
associated(fluxes%heat_content_massout)) &
1288 fluxes%heat_content_massout(i,j) = fluxes%heat_content_massout(i,j) + &
1289 t2d(i,k) * min(0.,dthickness) * gv%H_to_RZ * fluxes%C_p * idt
1290 if (
associated(tv%TempxPmE)) tv%TempxPmE(i,j) = tv%TempxPmE(i,j) + &
1291 t2d(i,k) * dthickness * gv%H_to_RZ
1295 h2d(i,k) = h2d(i,k) + dthickness
1297 if (h2d(i,k) > 0.)
then
1298 if (calculate_energetics)
then
1304 ctke(i,j,k) = ctke(i,j,k) - (0.5*h2d(i,k)*g_hconv2) * &
1305 ((dtemp - dthickness*t2d(i,k)) * dsv_dt(i,j,k) + &
1306 (dsalt - dthickness*tv%S(i,j,k)) * dsv_ds(i,j,k))
1308 ithickness = 1.0/h2d(i,k)
1309 t2d(i,k) = (hold*t2d(i,k) + dtemp)*ithickness
1310 tv%S(i,j,k) = (hold*tv%S(i,j,k) + dsalt)*ithickness
1311 elseif (h2d(i,k) < 0.0)
then
1312 call forcing_singlepointprint(fluxes,g,i,j,
'applyBoundaryFluxesInOut (h<0)')
1313 write(0,*)
'applyBoundaryFluxesInOut(): lon,lat=',g%geoLonT(i,j),g%geoLatT(i,j)
1314 write(0,*)
'applyBoundaryFluxesInOut(): netT,netS,netH=',netheat(i),netsalt(i),netmassinout(i)
1315 write(0,*)
'applyBoundaryFluxesInOut(): dT,dS,dH=',dtemp,dsalt,dthickness
1316 write(0,*)
'applyBoundaryFluxesInOut(): h(n),h(n+1),k=',hold,h2d(i,k),k
1317 call mom_error(fatal,
"MOM_diabatic_driver.F90, applyBoundaryFluxesInOut(): "//&
1318 "Complete mass loss in column!")
1324 elseif ((abs(netheat(i))+abs(netsalt(i))+abs(netmassin(i))+abs(netmassout(i)))>0.)
then
1326 if (.not. cs%ignore_fluxes_over_land)
then
1327 call forcing_singlepointprint(fluxes,g,i,j,
'applyBoundaryFluxesInOut (land)')
1328 write(0,*)
'applyBoundaryFluxesInOut(): lon,lat=',g%geoLonT(i,j),g%geoLatT(i,j)
1329 write(0,*)
'applyBoundaryFluxesInOut(): netHeat,netSalt,netMassIn,netMassOut=',&
1330 netheat(i),netsalt(i),netmassin(i),netmassout(i)
1332 call mom_error(fatal,
"MOM_diabatic_driver.F90, applyBoundaryFluxesInOut(): "//&
1333 "Mass loss over land?")
1339 if (netmassin(i)+netmassout(i) /= 0.0)
then
1341 numberofgroundings = numberofgroundings +1
1342 if (numberofgroundings<=maxgroundings)
then
1343 iground(numberofgroundings) = i
1344 jground(numberofgroundings) = j
1345 hgrounding(numberofgroundings) = netmassin(i)+netmassout(i)
1348 if (cs%id_createdH>0) cs%createdH(i,j) = cs%createdH(i,j) - (netmassin(i)+netmassout(i))/dt
1359 if (cs%id_penSW_diag > 0 .or. cs%id_penSWflux_diag > 0)
then
1360 do k=1,nz ;
do i=is,ie
1361 cs%penSW_diag(i,j,k) = t2d(i,k)
1362 cs%penSWflux_diag(i,j,k) = 0.0
1365 cs%penSWflux_diag(i,j,k) = 0.0
1369 if (calculate_energetics)
then
1370 call absorbremainingsw(g, gv, us, h2d, opacityband, nsw, optics, j, dt, h_limit_fluxes, &
1371 .false., .true., t2d, pen_sw_bnd, tke=pen_tke_2d, dsv_dt=dsv_dt_2d)
1373 do k=1,nz ;
do i=is,ie
1374 ctke(i,j,k) = ctke(i,j,k) + pen_tke_2d(i,k)
1377 call absorbremainingsw(g, gv, us, h2d, opacityband, nsw, optics, j, dt, h_limit_fluxes, &
1378 .false., .true., t2d, pen_sw_bnd)
1384 do k=1,nz ;
do i=is,ie
1386 tv%T(i,j,k) = t2d(i,k)
1391 if (cs%id_penSW_diag > 0 .or. cs%id_penSWflux_diag > 0)
then
1394 do k=1,nz ;
do i=is,ie
1395 cs%penSW_diag(i,j,k) = (t2d(i,k)-cs%penSW_diag(i,j,k))*h(i,j,k) * idt * tv%C_p * gv%H_to_RZ
1404 if (cs%id_penSWflux_diag > 0)
then
1405 do k=nz,1,-1 ;
do i=is,ie
1406 cs%penSWflux_diag(i,j,k) = cs%penSW_diag(i,j,k) + cs%penSWflux_diag(i,j,k+1)
1413 if (cs%id_nonpenSW_diag > 0)
then
1415 cs%nonpenSW_diag(i,j) = nonpensw(i) * idt * tv%C_p * gv%H_to_RZ
1424 if (calculate_buoyancy)
then
1427 netpen_rate(:) = 0.0
1434 do i=is,ie ;
do nb=1,nsw ; netpen_rate(i) = netpen_rate(i) + pen_sw_bnd_rate(nb,i) ;
enddo ;
enddo
1437 if (
associated(tv%p_surf))
then ;
do i=is,ie ; surfpressure(i) = tv%p_surf(i,j) ;
enddo ;
endif
1439 tv%eqn_of_state, eosdom)
1446 skinbuoyflux(i,j) = - gorho * gv%H_to_Z * &
1447 (drhods(i) * (netsalt_rate(i) - tv%S(i,j,1)*netmassinout_rate(i)) + &
1448 drhodt(i) * ( netheat_rate(i) + netpen_rate(i)) )
1455 if (cs%id_createdH > 0)
call post_data(cs%id_createdH , cs%createdH , cs%diag)
1456 if (cs%id_penSW_diag > 0)
call post_data(cs%id_penSW_diag , cs%penSW_diag , cs%diag)
1457 if (cs%id_penSWflux_diag > 0)
call post_data(cs%id_penSWflux_diag, cs%penSWflux_diag, cs%diag)
1458 if (cs%id_nonpenSW_diag > 0)
call post_data(cs%id_nonpenSW_diag , cs%nonpenSW_diag , cs%diag)
1461 if (numberofgroundings>0 .and. .not. cs%ignore_fluxes_over_land)
then
1462 do i = 1, min(numberofgroundings, maxgroundings)
1463 call forcing_singlepointprint(fluxes,g,iground(i),jground(i),
'applyBoundaryFluxesInOut (grounding)')
1464 write(mesg(1:45),
'(3es15.3)') g%geoLonT( iground(i), jground(i) ), &
1465 g%geoLatT( iground(i), jground(i)), hgrounding(i)*gv%H_to_m
1466 call mom_error(warning,
"MOM_diabatic_driver.F90, applyBoundaryFluxesInOut(): "//&
1467 "Mass created. x,y,dh= "//trim(mesg), all_print=.true.)
1470 if (numberofgroundings - maxgroundings > 0)
then
1471 write(mesg,
'(i4)') numberofgroundings - maxgroundings
1472 call mom_error(warning,
"MOM_diabatic_driver:F90, applyBoundaryFluxesInOut(): "//&
1473 trim(mesg) //
" groundings remaining")
1477 end subroutine applyboundaryfluxesinout
1480 subroutine diabatic_aux_init(Time, G, GV, US, param_file, diag, CS, useALEalgorithm, use_ePBL)
1481 type(time_type),
target,
intent(in) :: time
1486 type(
diag_ctrl),
target,
intent(inout) :: diag
1489 logical,
intent(in) :: usealealgorithm
1491 logical,
intent(in) :: use_epbl
1496 #include "version_variable.h"
1497 character(len=40) :: mdl =
"MOM_diabatic_aux"
1498 character(len=48) :: thickness_units
1499 character(len=200) :: inputdir
1500 character(len=240) :: chl_filename
1501 character(len=128) :: chl_file
1503 character(len=32) :: chl_varname
1504 logical :: use_temperature
1505 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb, nz, nbands
1506 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
1507 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
1509 if (
associated(cs))
then
1510 call mom_error(warning,
"diabatic_aux_init called with an "// &
1511 "associated control structure.")
1522 "The following parameters are used for auxiliary diabatic processes.")
1524 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", use_temperature, &
1525 "If true, temperature and salinity are used as state "//&
1526 "variables.", default=.true.)
1528 call get_param(param_file, mdl,
"RECLAIM_FRAZIL", cs%reclaim_frazil, &
1529 "If true, try to use any frazil heat deficit to cool any "//&
1530 "overlying layers down to the freezing point, thereby "//&
1531 "avoiding the creation of thin ice when the SST is above "//&
1532 "the freezing point.", default=.true.)
1533 call get_param(param_file, mdl,
"PRESSURE_DEPENDENT_FRAZIL", &
1534 cs%pressure_dependent_frazil, &
1535 "If true, use a pressure dependent freezing temperature "//&
1536 "when making frazil. The default is false, which will be "//&
1537 "faster but is inappropriate with ice-shelf cavities.", &
1541 call get_param(param_file, mdl,
"IGNORE_FLUXES_OVER_LAND", cs%ignore_fluxes_over_land,&
1542 "If true, the model does not check if fluxes are being applied "//&
1543 "over land points. This is needed when the ocean is coupled "//&
1544 "with ice shelves and sea ice, since the sea ice mask needs to "//&
1545 "be different than the ocean mask to avoid sea ice formation "//&
1546 "under ice shelves. This flag only works when use_ePBL = True.", default=.false.)
1547 call get_param(param_file, mdl,
"DO_RIVERMIX", cs%do_rivermix, &
1548 "If true, apply additional mixing wherever there is "//&
1549 "runoff, so that it is mixed down to RIVERMIX_DEPTH "//&
1550 "if the ocean is that deep.", default=.false.)
1551 if (cs%do_rivermix) &
1552 call get_param(param_file, mdl,
"RIVERMIX_DEPTH", cs%rivermix_depth, &
1553 "The depth to which rivers are mixed if DO_RIVERMIX is "//&
1554 "defined.", units=
"m", default=0.0, scale=us%m_to_Z)
1556 cs%do_rivermix = .false. ; cs%rivermix_depth = 0.0 ; cs%ignore_fluxes_over_land = .false.
1559 if (gv%nkml == 0)
then
1560 call get_param(param_file, mdl,
"USE_RIVER_HEAT_CONTENT", cs%use_river_heat_content, &
1561 "If true, use the fluxes%runoff_Hflx field to set the "//&
1562 "heat carried by runoff, instead of using SST*CP*liq_runoff.", &
1564 call get_param(param_file, mdl,
"USE_CALVING_HEAT_CONTENT", cs%use_calving_heat_content, &
1565 "If true, use the fluxes%calving_Hflx field to set the "//&
1566 "heat carried by runoff, instead of using SST*CP*froz_runoff.", &
1569 cs%use_river_heat_content = .false.
1570 cs%use_calving_heat_content = .false.
1573 if (usealealgorithm)
then
1574 cs%id_createdH = register_diag_field(
'ocean_model',
"created_H",diag%axesT1, &
1575 time,
"The volume flux added to stop the ocean from drying out and becoming negative in depth", &
1576 "m s-1", conversion=gv%H_to_m*us%s_to_T)
1577 if (cs%id_createdH>0)
allocate(cs%createdH(isd:ied,jsd:jed))
1580 cs%id_penSW_diag = register_diag_field(
'ocean_model',
'rsdoabsorb', &
1581 diag%axesTL, time,
'Convergence of Penetrative Shortwave Flux in Sea Water Layer',&
1582 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1583 standard_name=
'net_rate_of_absorption_of_shortwave_energy_in_ocean_layer', v_extensive=.true.)
1587 cs%id_penSWflux_diag = register_diag_field(
'ocean_model',
'rsdo', &
1588 diag%axesTi, time,
'Downwelling Shortwave Flux in Sea Water at Grid Cell Upper Interface',&
1589 'W m-2', conversion=us%QRZ_T_to_W_m2, standard_name=
'downwelling_shortwave_flux_in_sea_water')
1592 if (cs%id_penSW_diag>0 .or. cs%id_penSWflux_diag>0)
then
1593 allocate(cs%penSW_diag(isd:ied,jsd:jed,nz)) ; cs%penSW_diag(:,:,:) = 0.0
1594 allocate(cs%penSWflux_diag(isd:ied,jsd:jed,nz+1)) ; cs%penSWflux_diag(:,:,:) = 0.0
1598 cs%id_nonpenSW_diag = register_diag_field(
'ocean_model',
'nonpenSW', &
1599 diag%axesT1, time, &
1600 'Non-downwelling SW radiation (i.e., SW absorbed in ocean surface with LW,SENS,LAT)',&
1601 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1602 standard_name=
'nondownwelling_shortwave_flux_in_sea_water')
1603 if (cs%id_nonpenSW_diag > 0)
then
1604 allocate(cs%nonpenSW_diag(isd:ied,jsd:jed)) ; cs%nonpenSW_diag(:,:) = 0.0
1608 if (use_temperature)
then
1609 call get_param(param_file, mdl,
"VAR_PEN_SW", cs%var_pen_sw, &
1610 "If true, use one of the CHL_A schemes specified by "//&
1611 "OPACITY_SCHEME to determine the e-folding depth of "//&
1612 "incoming short wave radiation.", default=.false.)
1613 if (cs%var_pen_sw)
then
1615 call get_param(param_file, mdl,
"CHL_FROM_FILE", cs%chl_from_file, &
1616 "If true, chl_a is read from a file.", default=.true.)
1617 if (cs%chl_from_file)
then
1618 call time_interp_external_init()
1620 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
1621 call get_param(param_file, mdl,
"CHL_FILE", chl_file, &
1622 "CHL_FILE is the file containing chl_a concentrations in "//&
1623 "the variable CHL_A. It is used when VAR_PEN_SW and "//&
1624 "CHL_FROM_FILE are true.", fail_if_missing=.true.)
1625 chl_filename = trim(slasher(inputdir))//trim(chl_file)
1626 call log_param(param_file, mdl,
"INPUTDIR/CHL_FILE", chl_filename)
1627 call get_param(param_file, mdl,
"CHL_VARNAME", chl_varname, &
1628 "Name of CHL_A variable in CHL_FILE.", default=
'CHL_A')
1629 cs%sbc_chl = init_external_field(chl_filename, trim(chl_varname), domain=g%Domain%mpp_domain)
1632 cs%id_chl = register_diag_field(
'ocean_model',
'Chl_opac', diag%axesT1, time, &
1633 'Surface chlorophyll A concentration used to find opacity',
'mg m-3')
1637 id_clock_uv_at_h = cpu_clock_id(
'(Ocean find_uv_at_h)', grain=clock_routine)
1638 id_clock_frazil = cpu_clock_id(
'(Ocean frazil)', grain=clock_routine)
1640 end subroutine diabatic_aux_init
1644 subroutine diabatic_aux_end(CS)
1648 if (.not.
associated(cs))
return
1650 if (cs%id_createdH >0)
deallocate(cs%createdH)
1651 if (cs%id_penSW_diag >0)
deallocate(cs%penSW_diag)
1652 if (cs%id_penSWflux_diag >0)
deallocate(cs%penSWflux_diag)
1653 if (cs%id_nonpenSW_diag >0)
deallocate(cs%nonpenSW_diag)
1655 if (
associated(cs))
deallocate(cs)
1657 end subroutine diabatic_aux_end