27 implicit none ;
private 29 #include <MOM_memory.h> 38 real,
pointer,
dimension(:,:,:,:) :: &
39 opacity_band => null()
42 real,
pointer,
dimension(:,:,:) :: &
47 real,
pointer,
dimension(:) :: &
48 min_wavelength_band => null(), &
49 max_wavelength_band => null()
57 subroutine absorbremainingsw(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, &
58 adjustAbsorptionProfile, absorbAllSW, T, Pen_SW_bnd, &
59 eps, ksort, htot, Ttot, TKE, dSV_dT)
71 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: h
73 real,
dimension(:,:,:),
intent(in) :: opacity_band
76 integer,
intent(in) :: nsw
78 integer,
intent(in) :: j
79 real,
intent(in) :: dt
80 real,
intent(in) :: H_limit_fluxes
86 logical,
intent(in) :: adjustAbsorptionProfile
92 logical,
intent(in) :: absorbAllSW
98 real,
dimension(SZI_(G),SZK_(G)),
intent(inout) :: T
100 real,
dimension(:,:),
intent(inout) :: Pen_SW_bnd
105 real,
dimension(SZI_(G),SZK_(G)), &
106 optional,
intent(in) :: eps
109 integer,
dimension(SZI_(G),SZK_(G)), &
110 optional,
intent(in) :: ksort
111 real,
dimension(SZI_(G)), &
112 optional,
intent(in) :: htot
113 real,
dimension(SZI_(G)), &
114 optional,
intent(inout) :: Ttot
116 real,
dimension(SZI_(G),SZK_(G)), &
117 optional,
intent(in) :: dSV_dT
120 real,
dimension(SZI_(G),SZK_(G)), &
121 optional,
intent(inout) :: TKE
159 real,
dimension(SZI_(G),SZK_(G)) :: &
167 real,
dimension(SZI_(G)) :: &
190 real :: min_SW_heating
198 logical :: SW_Remains
203 integer :: is, ie, nz, i, k, ks, n
206 min_sw_heating = 2.5e-11
208 h_min_heat = 2.0*gv%Angstrom + gv%H_subroundoff
209 is = g%isc ; ie = g%iec ; nz = g%ke
210 c1_6 = 1.0 / 6.0 ; c1_60 = 1.0 / 60.0
212 tke_calc = (
present(tke) .and.
present(dsv_dt))
213 g_hconv2 = gv%g_Earth * gv%H_to_kg_m2**2
216 if (
present(htot))
then ;
do i=is,ie ; h_heat(i) = htot(i) ;
enddo ;
endif 220 do ks=1,nz ;
do i=is,ie
222 if (
present(ksort))
then 223 if (ksort(i,ks) <= 0) cycle
226 epsilon = 0.0 ;
if (
present(eps)) epsilon = eps(i,k)
228 t_chg_above(i,k) = 0.0
230 if (h(i,k) > 1.5*epsilon)
then 231 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 233 opt_depth = h(i,k) * opacity_band(n,i,k)
234 exp_od = exp(-opt_depth)
241 if (nsw*pen_sw_bnd(n,i)*sw_trans < &
242 dt*min_sw_heating*min(gv%m_to_H,1e3*h(i,k)) ) sw_trans = 0.0
244 heat_bnd = pen_sw_bnd(n,i) * (1.0 - sw_trans)
245 if (adjustabsorptionprofile .and. (h_heat(i) > 0.0))
then 256 if (opt_depth > 1e-5)
then 257 swa = ((opt_depth + (opt_depth + 2.0)*exp_od) - 2.0) / &
258 ((opt_depth + opacity_band(n,i,k) * h_heat(i)) * &
263 swa = h(i,k) * (opt_depth * (1.0 - opt_depth)) / &
264 ((h_heat(i) + h(i,k)) * (6.0 - 3.0*opt_depth))
267 if (swa*(h_heat(i) + h(i,k)) > h_heat(i))
then 268 coswa_frac = (swa*(h_heat(i) + h(i,k)) - h_heat(i) ) / &
269 (swa*(h_heat(i) + h(i,k)))
270 swa = h_heat(i) / (h_heat(i) + h(i,k))
273 t_chg_above(i,k) = t_chg_above(i,k) + (swa * heat_bnd) / h_heat(i)
274 t(i,k) = t(i,k) + ((1.0 - swa) * heat_bnd) / h(i,k)
277 t(i,k) = t(i,k) + pen_sw_bnd(n,i) * (1.0 - sw_trans) / h(i,k)
281 if (opt_depth > 1e-2)
then 282 tke(i,k) = tke(i,k) - coswa_frac*heat_bnd*dsv_dt(i,k)* &
283 (0.5*h(i,k)*g_hconv2) * &
284 (opt_depth*(1.0+exp_od) - 2.0*(1.0-exp_od)) / (opt_depth*(1.0-exp_od))
288 tke(i,k) = tke(i,k) - coswa_frac*heat_bnd*dsv_dt(i,k)* &
289 (0.5*h(i,k)*g_hconv2) * &
290 (c1_6*opt_depth * (1.0 - c1_60*opt_depth**2))
294 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
300 if (h(i,k) >= 2.0*h_min_heat)
then 301 h_heat(i) = h_heat(i) + h(i,k)
302 elseif (h(i,k) > h_min_heat)
then 303 h_heat(i) = h_heat(i) + (2.0*h(i,k) - 2.0*h_min_heat)
311 do i=is,ie ; t_chg(i) = 0.0 ;
enddo 313 if (absorballsw)
then 318 pen_sw_rem(i) = pen_sw_bnd(1,i)
319 do n=2,nsw ; pen_sw_rem(i) = pen_sw_rem(i) + pen_sw_bnd(n,i) ;
enddo 321 do i=is,ie ;
if (pen_sw_rem(i) > 0.0) sw_remains = .true. ;
enddo 323 ih_limit = 1.0 / h_limit_fluxes
324 do i=is,ie ;
if ((pen_sw_rem(i) > 0.0) .and. (h_heat(i) > 0.0))
then 325 if (h_heat(i)*ih_limit >= 1.0)
then 326 t_chg(i) = pen_sw_rem(i) / h_heat(i) ; unabsorbed = 0.0
328 t_chg(i) = pen_sw_rem(i) * ih_limit
329 unabsorbed = 1.0 - h_heat(i)*ih_limit
331 do n=1,nsw ; pen_sw_bnd(n,i) = unabsorbed * pen_sw_bnd(n,i) ;
enddo 335 if (absorballsw .or. adjustabsorptionprofile)
then 336 do ks=nz,1,-1 ;
do i=is,ie
338 if (
present(ksort))
then 339 if (ksort(i,ks) <= 0) cycle
343 if (t_chg(i) > 0.0)
then 345 if (h(i,k) >= 2.0*h_min_heat)
then ; t(i,k) = t(i,k) + t_chg(i)
346 elseif (h(i,k) > h_min_heat)
then 347 t(i,k) = t(i,k) + t_chg(i) * (2.0 - 2.0*h_min_heat/h(i,k))
351 t_chg(i) = t_chg(i) + t_chg_above(i,k)
353 if (
present(htot) .and.
present(ttot))
then 354 do i=is,ie ; ttot(i) = ttot(i) + t_chg(i) * htot(i) ;
enddo 362 H_limit_fluxes, absorbAllSW, iPen_SW_bnd, netPen)
368 real,
dimension(SZI_(G),SZK_(G)),
intent(in) :: h
370 real,
dimension(:,:,:),
intent(in) :: opacity_band
373 integer,
intent(in) :: nsw
375 integer,
intent(in) :: j
376 real,
intent(in) :: dt
377 real,
intent(in) :: H_limit_fluxes
378 logical,
intent(in) :: absorbAllSW
379 real,
dimension(:,:),
intent(in) :: iPen_SW_bnd
380 real,
dimension(SZI_(G),SZK_(G)+1),
intent(inout) :: netPen
397 real :: h_heat(szi_(g))
399 real :: Pen_SW_rem(szi_(g))
404 real,
dimension(size(iPen_SW_bnd,1),size(iPen_SW_bnd,2)) :: Pen_SW_bnd
414 logical :: SW_Remains
417 integer :: is, ie, nz, i, k, ks, n
420 h_min_heat = 2.0*gv%Angstrom + gv%H_subroundoff
421 is = g%isc ; ie = g%iec ; nz = g%ke
423 pen_sw_bnd(:,:) = ipen_sw_bnd(:,:)
424 do i=is,ie ; h_heat(i) = 0.0 ;
enddo 425 netpen(:,1) = sum( pen_sw_bnd(:,:), dim=1 )
434 if (h(i,k) > 0.0)
then 435 do n=1,nsw ;
if (pen_sw_bnd(n,i) > 0.0)
then 437 opt_depth = h(i,k)*gv%H_to_m * opacity_band(n,i,k)
438 exp_od = exp(-opt_depth)
444 if ((nsw*pen_sw_bnd(n,i)*sw_trans < gv%m_to_H*2.5e-11*dt) .and. &
445 (nsw*pen_sw_bnd(n,i)*sw_trans < h(i,k)*dt*2.5e-8)) &
448 pen_sw_bnd(n,i) = pen_sw_bnd(n,i) * sw_trans
449 netpen(i,k+1) = netpen(i,k+1) + pen_sw_bnd(n,i)
455 if (h(i,k) >= 2.0*h_min_heat)
then 456 h_heat(i) = h_heat(i) + h(i,k)
457 elseif (h(i,k) > h_min_heat)
then 458 h_heat(i) = h_heat(i) + (2.0*h(i,k) - 2.0*h_min_heat)
463 if (absorballsw)
then 469 pen_sw_rem(i) = pen_sw_bnd(1,i)
470 do n=2,nsw ; pen_sw_rem(i) = pen_sw_rem(i) + pen_sw_bnd(n,i) ;
enddo 472 do i=is,ie ;
if (pen_sw_rem(i) > 0.0) sw_remains = .true. ;
enddo 474 ih_limit = 1.0 / h_limit_fluxes
475 do i=is,ie ;
if ((pen_sw_rem(i) > 0.0) .and. (h_heat(i) > 0.0))
then 476 if (h_heat(i)*ih_limit < 1.0)
then 477 unabsorbed = 1.0 - h_heat(i)*ih_limit
481 do n=1,nsw ; pen_sw_bnd(n,i) = unabsorbed * pen_sw_bnd(n,i) ;
enddo Ocean grid type. See mom_grid for details.
Provides the ocean grid type.
subroutine, public absorbremainingsw(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, adjustAbsorptionProfile, absorbAllSW, T, Pen_SW_bnd, eps, ksort, htot, Ttot, TKE, dSV_dT)
Apply shortwave heating below surface boundary layer.
subroutine, public sumswoverbands(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, absorbAllSW, iPen_SW_bnd, netPen)
subroutine, public mom_error(level, message, all_print)