← back to index

src/parameterizations/vertical/MOM_entrain_diffusive.F90

portedportable, not yet portedexecuted, not portableexecutable, not hit by this run

1! This file is part of MOM6, the Modular Ocean Model version 6.
2! See the LICENSE file for licensing information.
3! SPDX-License-Identifier: Apache-2.0
4
5!> Diapycnal mixing and advection in isopycnal mode
6module MOM_entrain_diffusive
7
8use MOM_diag_mediator, only : post_data, register_diag_field, safe_alloc_ptr
9use MOM_diag_mediator, only : diag_ctrl, time_type
10use MOM_EOS, only : calculate_density, calculate_density_derivs
11use MOM_EOS, only : calculate_specific_vol_derivs, EOS_domain
12use MOM_error_handler, only : MOM_error, is_root_pe, FATAL, WARNING, NOTE
13use MOM_file_parser, only : get_param, log_version, param_file_type
14use MOM_forcing_type, only : forcing
15use MOM_grid, only : ocean_grid_type
16use MOM_unit_scaling, only : unit_scale_type
17use MOM_variables, only : thermo_var_ptrs
18use MOM_verticalGrid, only : verticalGrid_type
19
20implicit none ; private
21
22#include <MOM_memory.h>
23
24public entrainment_diffusive, entrain_diffusive_init
25
26! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional
27! consistency testing. These are noted in comments with units like Z, H, L, and T, along with
28! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units
29! vary with the Boussinesq approximation, the Boussinesq variant is given first.
30
31!> The control structure holding parametes for the MOM_entrain_diffusive module
32type, public :: entrain_diffusive_CS ; private
33 logical :: initialized = .false. !< True if this control structure has been initialized.
34 logical :: bulkmixedlayer !< If true, a refined bulk mixed layer is used with
35 !! GV%nk_rho_varies variable density mixed & buffer layers.
36 integer :: max_ent_it !< The maximum number of iterations that may be used to
37 !! calculate the diapycnal entrainment.
38 real :: Tolerance_Ent !< The tolerance with which to solve for entrainment values
39 !! [H ~> m or kg m-2].
40 real :: max_Ent !< A large ceiling on the maximum permitted amount of entrainment
41 !! across each interface between the mixed and buffer layers within
42 !! a timestep [H ~> m or kg m-2].
43 real :: Rho_sig_off !< The offset between potential density and a sigma value [R ~> kg m-3]
44 type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to
45 !! regulate the timing of diagnostic output.
46 integer :: id_Kd = -1 !< Diagnostic ID for diffusivity
47 integer :: id_diff_work = -1 !< Diagnostic ID for mixing work
48end type entrain_diffusive_CS
49
50contains
51
52!> This subroutine calculates ea and eb, the rates at which a layer entrains
53!! from the layers above and below. The entrainment rates are proportional to
54!! the buoyancy flux in a layer and inversely proportional to the density
55!! differences between layers. The scheme that is used here is described in
56!! detail in Hallberg, Mon. Wea. Rev. 2000.
570subroutine entrainment_diffusive(h, tv, fluxes, dt, G, GV, US, CS, ea, eb, &
580 kb_out, Kd_Lay, Kd_int)
59 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
60 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
61 type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
62 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
63 intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2].
64 type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any available
65 !! thermodynamic fields. Absent fields have NULL
66 !! ptrs.
67 type(forcing), intent(in) :: fluxes !< A structure of surface fluxes that may
68 !! be used.
69 real, intent(in) :: dt !< The time increment [T ~> s].
70 type(entrain_diffusive_CS), intent(in) :: CS !< The control structure returned by a previous
71 !! call to entrain_diffusive_init.
72 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
73 intent(out) :: ea !< The amount of fluid entrained from the layer
74 !! above within this time step [H ~> m or kg m-2].
75 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
76 intent(out) :: eb !< The amount of fluid entrained from the layer
77 !! below within this time step [H ~> m or kg m-2].
78 integer, dimension(SZI_(G),SZJ_(G)), &
79 intent(inout) :: kb_out !< The index of the lightest layer denser than
80 !! the buffer layer.
81 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
82 intent(in) :: Kd_Lay !< The diapycnal diffusivity of layers
83 !! [H Z T-1 ~> m2 s-1 or kg m-1 s-1].
84 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), &
85 intent(in) :: Kd_int !< The diapycnal diffusivity of interfaces
86 !! [H Z T-1 ~> m2 s-1 or kg m-1 s-1].
87
88! This subroutine calculates ea and eb, the rates at which a layer entrains
89! from the layers above and below. The entrainment rates are proportional to
90! the buoyancy flux in a layer and inversely proportional to the density
91! differences between layers. The scheme that is used here is described in
92! detail in Hallberg, Mon. Wea. Rev. 2000.
93
94 real, dimension(SZI_(G),SZK_(GV)) :: &
950 dtKd ! The layer diapycnal diffusivity times the time step [H2 ~> m2 or kg2 m-4].
96 real, dimension(SZI_(G),SZK_(GV)+1) :: &
970 dtKd_int ! The diapycnal diffusivity at the interfaces times the time step [H2 ~> m2 or kg2 m-4]
98 real, dimension(SZI_(G),SZK_(GV)) :: &
990 F, & ! The density flux through a layer within a time step divided by the
100 ! density difference across the interface below the layer [H ~> m or kg m-2].
1010 maxF, & ! maxF is the maximum value of F that will not deplete all of the
102 ! layers above or below a layer within a timestep [H ~> m or kg m-2].
1030 minF, & ! minF is the minimum flux that should be expected in the absence of
104 ! interactions between layers [H ~> m or kg m-2].
1050 Fprev, &! The previous estimate of F [H ~> m or kg m-2].
1060 dFdfm, &! The partial derivative of F with respect to changes in F of the
107 ! neighboring layers. [nondim]
1080 h_guess ! An estimate of the layer thicknesses after entrainment, but
109 ! before the entrainments are adjusted to drive the layer
110 ! densities toward their target values [H ~> m or kg m-2].
111 real, dimension(SZI_(G),SZK_(GV)+1) :: &
1120 Ent_bl ! The average entrainment upward and downward across
113 ! each interface around the buffer layers [H ~> m or kg m-2].
114 real, allocatable, dimension(:,:,:) :: &
1150 Kd_eff, & ! The effective diffusivity that actually applies to each
116 ! layer after the effects of boundary conditions are
117 ! considered [H Z T-1 ~> m2 s-1 or kg m-1 s-1].
1180 diff_work ! The work actually done by diffusion across each
119 ! interface [R Z3 T-3 ~> W m-2]. Sum vertically for the total work.
120
121 real :: hm, fm, fr ! Work variables with units of [H ~> m or kg m-2].
122 real :: fk ! A Work variable with units of [H2 ~> m2 or kg2 m-4]
123
1240 real :: b1(SZI_(G)) ! A variable used by the tridiagonal solver [H ~> m or kg m-2]
1250 real :: c1(SZI_(G),SZK_(GV)) ! A variable used by the tridiagonal solver [nondim]
126
127 real, dimension(SZI_(G)) :: &
1280 htot, & ! The total thickness above or below a layer [H ~> m or kg m-2].
1290 Rcv, & ! Value of the coordinate variable (potential density)
130 ! based on the simulated T and S and P_Ref [R ~> kg m-3].
1310 pres, & ! Reference pressure (P_Ref) [R L2 T-2 ~> Pa].
1320 eakb, & ! The entrainment from above by the layer below the buffer
133 ! layer (i.e. layer kb) [H ~> m or kg m-2].
1340 ea_kbp1, & ! The entrainment from above by layer kb+1 [H ~> m or kg m-2].
1350 eb_kmb, & ! The entrainment from below by the deepest buffer layer [H ~> m or kg m-2].
1360 dS_kb, & ! The reference potential density difference across the
137 ! interface between the buffer layers and layer kb [R ~> kg m-3].
1380 dS_anom_lim, &! The amount by which dS_kb is reduced when limits are
139 ! applied [R ~> kg m-3].
1400 I_dSkbp1, & ! The inverse of the potential density difference across the
141 ! interface below layer kb [R-1 ~> m3 kg-1].
1420 dtKd_kb, & ! The diapycnal diffusivity in layer kb times the time step
143 ! [H2 ~> m2 or kg2 m-4].
1440 maxF_correct, & ! An amount by which to correct maxF due to excessive
145 ! surface heat loss [H ~> m or kg m-2].
1460 zeros, & ! An array of all zeros. (Usually used with [H ~> m or kg m-2].)
1470 max_eakb, & ! The maximum value of eakb that might be realized [H ~> m or kg m-2].
1480 min_eakb, & ! The minimum value of eakb that might be realized [H ~> m or kg m-2].
1490 err_max_eakb0, & ! The value of error returned by determine_Ea_kb when eakb = max_eakb
150 ! and ea_kbp1 = 0 [H2 ~> m2 or kg2 m-4].
1510 err_min_eakb0, & ! The value of error returned by determine_Ea_kb when eakb = min_eakb
152 ! and ea_kbp1 = 0 [H2 ~> m2 or kg2 m-4].
1530 err_eakb0, & ! A value of error returned by determine_Ea_kb [H2 ~> m2 or kg2 m-4].
1540 F_kb, & ! The value of F in layer kb, or equivalently the entrainment
155 ! from below by layer kb [H ~> m or kg m-2].
1560 dFdfm_kb, & ! The partial derivative of F with fm [nondim]. See dFdfm.
1570 maxF_kb, & ! The maximum value of F_kb that might be realized [H ~> m or kg m-2].
1580 eakb_maxF, & ! The value of eakb that gives F_kb=maxF_kb [H ~> m or kg m-2].
1590 F_kb_maxEnt ! The value of F_kb when eakb = max_eakb [H ~> m or kg m-2].
160 real, dimension(SZI_(G),SZK_(GV)) :: &
1610 Sref, & ! The reference potential density of the mixed and buffer layers,
162 ! and of the two lightest interior layers (kb and kb+1) copied
163 ! into layers kmb+1 and kmb+2 [R ~> kg m-3].
1640 h_bl ! The thicknesses of the mixed and buffer layers, and of the two
165 ! lightest interior layers (kb and kb+1) copied into layers kmb+1
166 ! and kmb+2 [H ~> m or kg m-2].
167
168 real, dimension(SZI_(G),SZK_(GV)) :: &
1690 ds_dsp1, & ! The coordinate variable (sigma-2) difference across an
170 ! interface divided by the difference across the interface
171 ! below it. [nondim]
1720 dsp1_ds, & ! The inverse coordinate variable (sigma-2) difference
173 ! across an interface times the difference across the
174 ! interface above it. [nondim]
1750 I2p2dsp1_ds, & ! 1 / (2 + 2 * ds_k+1 / ds_k). [nondim]
1760 grats ! 2*(2 + ds_k+1 / ds_k + ds_k / ds_k+1) =
177 ! 4*ds_Lay*(1/ds_k + 1/ds_k+1). [nondim]
178
179 real :: dRho ! The change in locally referenced potential density between
180 ! the layers above and below an interface [R ~> kg m-3]
181 real :: dSpV ! The change in locally referenced specific volume between
182 ! the layers above and below an interface [R-1 ~> m3 kg-1]
183 real :: g_2dt ! 0.5 * G_Earth / dt, times unit conversion factors
184 ! [Z3 H-2 T-3 or R2 Z3 H-2 T-3 ~> m s-3].
185 real, dimension(SZI_(G)) :: &
1860 pressure, & ! The pressure at an interface [R L2 T-2 ~> Pa].
1870 T_eos, S_eos, & ! The potential temperature and salinity at which to
188 ! evaluate dRho_dT and dRho_dS [C ~> degC] and [S ~> ppt].
1890 dRho_dT, & ! The partial derivative of potential density with temperature [R C-1 ~> kg m-3 degC-1]
1900 dRho_dS, & ! The partial derivative of potential density with salinity [R S-1 ~> kg m-3 ppt-1]
1910 dSpV_dT, & ! The partial derivative of specific volume with temperature [R-1 C-1 ~> m3 kg-1 degC-1]
1920 dSpV_dS ! The partial derivative of specific volume with salinity [R-1 S-1 ~> m3 kg-1 ppt-1]
193
194 real :: tolerance ! The tolerance within which E must be converged [H ~> m or kg m-2].
195 real :: Angstrom ! The minimum layer thickness [H ~> m or kg m-2].
196 real :: h_neglect ! A thickness that is so small it is usually lost
197 ! in roundoff and can be neglected [H ~> m or kg m-2].
198 real :: F_cor ! A correction to the amount of F that is used to
199 ! entrain from the layer above [H ~> m or kg m-2].
200 real :: Kd_here ! The effective diapycnal diffusivity times the timestep [H2 ~> m2 or kg2 m-4].
201 real :: h_avail ! The thickness that is available for entrainment [H ~> m or kg m-2].
202 real :: dS_kb_eff ! The value of dS_kb after limiting is taken into account [R ~> kg m-3].
203 real :: Rho_cor ! The depth-integrated potential density anomaly that
204 ! needs to be corrected for [H R ~> kg m-2 or kg2 m-5].
205 real :: ea_cor ! The corrective adjustment to eakb [H ~> m or kg m-2].
206 real :: h1 ! The layer thickness after entrainment through the
207 ! interface below is taken into account [H ~> m or kg m-2].
208 real :: Idt ! The inverse of the time step [Z H-1 T-1 ~> s-1 or m3 kg-1 s-1].
209
210 logical :: do_any
211 logical :: do_entrain_eakb ! True if buffer layer is entrained
2120 logical :: do_i(SZI_(G)), did_i(SZI_(G)), reiterate
213 integer, dimension(2) :: EOSdom ! The i-computational domain for the equation of state
214 integer :: it, i, j, k, is, ie, js, je, nz, K2, kmb
2150 integer :: kb(SZI_(G)) ! The value of kb in row j.
216 integer :: kb_min ! The minimum value of kb in the current j-row.
217 integer :: kb_min_act ! The minimum active value of kb in the current j-row.
218 integer :: is1, ie1 ! The minimum and maximum active values of i in the current j-row.
2190 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
2200 Angstrom = GV%Angstrom_H
2210 h_neglect = GV%H_subroundoff
222
2230 if (.not. CS%initialized) call MOM_error(FATAL, &
2240 "MOM_entrain_diffusive: Module must be initialized before it is used.")
225
2260 if ((.not.CS%bulkmixedlayer .and. .not.associated(fluxes%buoy)) .and. &
227 (associated(fluxes%lprec) .or. associated(fluxes%evap) .or. &
228 associated(fluxes%sens) .or. associated(fluxes%sw))) then
2290 if (is_root_pe()) call MOM_error(NOTE, "Calculate_Entrainment: &
230 &The code to handle evaporation and precipitation without &
2310 &a bulk mixed layer has not been implemented.")
2320 if (is_root_pe()) call MOM_error(FATAL, &
233 "Either define BULKMIXEDLAYER in MOM_input or use fluxes%buoy &
2340 &and a linear equation of state to drive the model.")
235 endif
236
2370 tolerance = CS%Tolerance_Ent
2380 kmb = GV%nk_rho_varies
2390 K2 = max(kmb+1,2) ; kb_min = K2
2400 if (.not. CS%bulkmixedlayer) then
2410 kb(:) = 1
242 ! These lines fill in values that are arbitrary, but needed because
243 ! they are used to normalize the buoyancy flux in layer nz.
2440 do i=is,ie ; ds_dsp1(i,nz) = 2.0 ; dsp1_ds(i,nz) = 0.5 ; enddo
245 else
2460 kb(:) = 0
2470 do i=is,ie ; ds_dsp1(i,nz) = 0.0 ; dsp1_ds(i,nz) = 0.0 ; enddo
248 endif
249
2500 if (CS%id_diff_work > 0) allocate(diff_work(G%isd:G%ied,G%jsd:G%jed,nz+1))
2510 if (CS%id_Kd > 0) allocate(Kd_eff(G%isd:G%ied,G%jsd:G%jed,nz))
252
2530 if (associated(tv%eqn_of_state)) then
2540 pres(:) = tv%P_Ref
255 else
2560 pres(:) = 0.0
257 endif
2580 EOSdom(:) = EOS_domain(G%HI)
259
260 !$OMP parallel do default(private) shared(is,ie,js,je,nz,Kd_Lay,G,GV,US,dt,CS,h,tv, &
261 !$OMP kmb,Angstrom,fluxes,K2,h_neglect,tolerance, &
262 !$OMP ea,eb,Kd_int,Kd_eff,EOSdom,diff_work,g_2dt, kb_out) &
263 !$OMP firstprivate(kb,ds_dsp1,dsp1_ds,pres,kb_min)
2640 do j=js,je
2650 do i=is,ie ; kb(i) = 1 ; enddo
266
2670 if (allocated(tv%SpV_avg)) then
2680 do k=1,nz ; do i=is,ie
2690 dtKd(i,k) = GV%RZ_to_H * (dt * Kd_lay(i,j,k)) / tv%SpV_avg(i,j,k)
270 enddo ; enddo
2710 do i=is,ie
2720 dtKd_int(i,1) = GV%RZ_to_H * (dt * Kd_int(i,j,1)) / tv%SpV_avg(i,j,1)
2730 dtKd_int(i,nz+1) = GV%RZ_to_H * (dt * Kd_int(i,j,nz+1)) / tv%SpV_avg(i,j,nz)
274 enddo
275 ! Use the mass-weighted average specific volume to translate thicknesses to verti distances.
2760 do K=2,nz ; do i=is,ie
277 dtKd_int(i,K) = GV%RZ_to_H * (dt * Kd_int(i,j,K)) * &
278 ( (h(i,j,k-1) + h(i,j,k) + 2.0*h_neglect) / &
279 ((h(i,j,k-1)+h_neglect) * tv%SpV_avg(i,j,k-1) + &
2800 (h(i,j,k)+h_neglect) * tv%SpV_avg(i,j,k)) )
281 enddo ; enddo
282 else
2830 do k=1,nz ; do i=is,ie
2840 dtKd(i,k) = GV%Z_to_H * (dt * Kd_lay(i,j,k))
285 enddo ; enddo
2860 do K=1,nz+1 ; do i=is,ie
2870 dtKd_int(i,K) = GV%Z_to_H * (dt * Kd_int(i,j,K))
288 enddo ; enddo
289 endif
290
2910 do i=is,ie ; do_i(i) = (G%mask2dT(i,j) > 0.0) ; enddo
2920 do i=is,ie ; ds_dsp1(i,nz) = 0.0 ; enddo
2930 do i=is,ie ; dsp1_ds(i,nz) = 0.0 ; enddo
294
2950 if (GV%Boussinesq .or. GV%Semi_Boussinesq) then
2960 do k=2,nz-1 ; do i=is,ie
2970 ds_dsp1(i,k) = GV%g_prime(k) / GV%g_prime(k+1)
298 enddo ; enddo
299 else ! Use a mathematically equivalent form that avoids any dependency on RHO_0.
3000 do k=2,nz-1 ; do i=is,ie
3010 ds_dsp1(i,k) = (GV%Rlay(k) - GV%Rlay(k-1)) / (GV%Rlay(k+1) - GV%Rlay(k))
302 enddo ; enddo
303 endif
304
3050 if (CS%bulkmixedlayer) then
306 ! This subroutine determines the averaged entrainment across each
307 ! interface and causes thin and relatively light interior layers to be
308 ! entrained by the deepest buffer layer. This also determines kb.
3090 call set_Ent_bl(h, dtKd_int, tv, kb, kmb, do_i, G, GV, US, CS, j, Ent_bl, Sref, h_bl)
310
3110 do i=is,ie
3120 dtKd_kb(i) = 0.0 ; if (kb(i) < nz) dtKd_kb(i) = dtKd(i,kb(i))
313 enddo
314 else
3150 do i=is,ie ; Ent_bl(i,Kmb+1) = 0.0 ; enddo
316 endif
317
3180 do k=2,nz-1 ; do i=is,ie
3190 dsp1_ds(i,k) = 1.0 / ds_dsp1(i,k)
3200 I2p2dsp1_ds(i,k) = 0.5/(1.0+dsp1_ds(i,k))
3210 grats(i,k) = 2.0*(2.0+(dsp1_ds(i,k)+ds_dsp1(i,k)))
322 enddo ; enddo
323
324! Determine the maximum flux, maxF, for each of the isopycnal layers.
325! Also determine when the fluxes start entraining
326! from various buffer or mixed layers, where appropriate.
3270 if (CS%bulkmixedlayer) then
3280 kb_min = nz
3290 do i=is,ie
3300 htot(i) = h(i,j,1) - Angstrom
331 enddo
3320 do k=2,kmb ; do i=is,ie
3330 htot(i) = htot(i) + (h(i,j,k) - Angstrom)
334 enddo ; enddo
3350 do i=is,ie
3360 max_eakb(i) = MAX(Ent_bl(i,Kmb+1) + 0.5*htot(i), htot(i))
3370 I_dSkbp1(i) = 1.0 / (Sref(i,kmb+2) - Sref(i,kmb+1))
3380 zeros(i) = 0.0
339 enddo
340
341 ! Find the maximum amount of entrainment from below that the top
342 ! interior layer could exhibit (maxF(i,kb)), approximating that
343 ! entrainment by (eakb*max(dS_kb/dSkbp1,0)). eakb is in the range
344 ! from 0 to max_eakb.
345 call find_maxF_kb(h_bl, Sref, Ent_bl, I_dSkbp1, zeros, max_eakb, kmb, &
3460 is, ie, G, GV, CS, maxF_kb, eakb_maxF, do_i, F_kb_maxent)
3470 do i=is,ie ; if (kb(i) <= nz) then
3480 maxF(i,kb(i)) = MAX(0.0, maxF_kb(i), F_kb_maxent(i))
3490 if ((maxF_kb(i) > F_kb_maxent(i)) .and. (eakb_maxF(i) >= htot(i))) &
3500 max_eakb(i) = eakb_maxF(i)
351 endif ; enddo
352
3530 do i=is,ie ; ea_kbp1(i) = 0.0 ; eakb(i) = max_eakb(i) ; enddo
354 call determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, &
355 max_eakb, max_eakb, kmb, is, ie, do_i, G, GV, CS, eakb, &
3560 error=err_max_eakb0, F_kb=F_kb)
357
358 ! The maximum value of F(kb) between htot and max_eakb determines
359 ! what maxF(kb+1) should be.
3600 do i=is,ie ; min_eakb(i) = MIN(htot(i), max_eakb(i)) ; enddo
361 call find_maxF_kb(h_bl, Sref, Ent_bl, I_dSkbp1, min_eakb, max_eakb, &
3620 kmb, is, ie, G, GV, CS, F_kb_maxEnt, do_i_in=do_i)
363
3640 do i=is,ie
3650 do_entrain_eakb = .false.
366 ! If error_max_eakb0 < 0, then buffer layers are always all entrained
3670 if (do_i(i)) then ; if (err_max_eakb0(i) < 0.0) then
3680 do_entrain_eakb = .true.
369 endif ; endif
370
3710 if (do_entrain_eakb) then
3720 eakb(i) = max_eakb(i) ; min_eakb(i) = max_eakb(i)
373 else
3740 eakb(i) = 0.0 ; min_eakb(i) = 0.0
375 endif
376 enddo
377
378 ! Find the amount of entrainment of the buffer layers that would occur
379 ! if there were no entrainment by the deeper interior layers. Also find
380 ! how much entrainment of the deeper layers would occur.
381 call determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, &
382 zeros, max_eakb, kmb, is, ie, do_i, G, GV, CS, min_eakb, &
3830 error=err_min_eakb0, F_kb=F_kb, err_max_eakb0=err_max_eakb0)
384 ! Error_min_eakb0 should be ~0 unless error_max_eakb0 < 0.
3850 do i=is,ie ; if ((kb(i)<nz) .and. (kb_min>kb(i))) kb_min = kb(i) ; enddo
386 else
387 ! Without a bulk mixed layer, surface fluxes are applied in this
388 ! subroutine. (Otherwise, they are handled in mixedlayer.)
389 ! Initially the maximum flux in layer zero is given by the surface
390 ! buoyancy flux. It will later be limited if the surface flux is
391 ! too large. Here buoy is the surface buoyancy flux.
3920 do i=is,ie
3930 maxF(i,1) = 0.0
3940 htot(i) = h(i,j,1) - Angstrom
395 enddo
3960 if (associated(fluxes%buoy) .and. GV%Boussinesq) then
3970 do i=is,ie
3980 maxF(i,1) = GV%Z_to_H * (dt*fluxes%buoy(i,j)) / GV%g_prime(2)
399 enddo
4000 elseif (associated(fluxes%buoy)) then
4010 do i=is,ie
402 maxF(i,1) = (GV%RZ_to_H * 0.5*(GV%Rlay(1) + GV%Rlay(2)) * (dt*fluxes%buoy(i,j))) / &
4030 GV%g_prime(2)
404 enddo
405 endif
406 endif
407
408! The following code calculates the maximum flux, maxF, for the interior
409! layers.
4100 do k=kb_min,nz-1 ; do i=is,ie
4110 if ((k == kb(i)+1) .and. CS%bulkmixedlayer) then
4120 maxF(i,k) = ds_dsp1(i,k)*(F_kb_maxEnt(i) + htot(i))
4130 htot(i) = htot(i) + (h(i,j,k) - Angstrom)
4140 elseif (k > kb(i)) then
4150 maxF(i,k) = ds_dsp1(i,k)*(maxF(i,k-1) + htot(i))
4160 htot(i) = htot(i) + (h(i,j,k) - Angstrom)
417 endif
418 enddo ; enddo
4190 do i=is,ie
4200 maxF(i,nz) = 0.0
4210 if (.not.CS%bulkmixedlayer) then
4220 maxF_correct(i) = MAX(0.0, -(maxF(i,nz-1) + htot(i)))
423 endif
4240 htot(i) = h(i,j,nz) - Angstrom
425 enddo
4260 if (.not.CS%bulkmixedlayer) then
4270 do_any = .false. ; do i=is,ie ; if (maxF_correct(i) > 0.0) do_any = .true. ; enddo
4280 if (do_any) then
4290 do k=nz-1,1,-1 ; do i=is,ie
4300 maxF(i,k) = maxF(i,k) + maxF_correct(i)
4310 maxF_correct(i) = maxF_correct(i) * dsp1_ds(i,k)
432 enddo ; enddo
433 endif
434 endif
4350 do k=nz-1,kb_min,-1 ; do i=is,ie ; if (do_i(i)) then
4360 if (k >= kb(i)) then
4370 maxF(i,k) = MIN(maxF(i,k),dsp1_ds(i,k+1)*maxF(i,k+1) + htot(i))
4380 htot(i) = htot(i) + (h(i,j,k) - Angstrom)
439 endif
4400 if (k == kb(i)) then
4410 if ((maxF(i,k) < F_kb(i)) .or. (maxF(i,k) < maxF_kb(i)) &
442 .and. (eakb_maxF(i) <= max_eakb(i))) then
443 ! In this case, too much was being entrained by the topmost interior
444 ! layer, even with the minimum initial estimate. The buffer layer
445 ! will always entrain the maximum amount.
4460 F_kb(i) = maxF(i,k)
4470 if ((F_kb(i) <= maxF_kb(i)) .and. (eakb_maxF(i) <= max_eakb(i))) then
4480 eakb(i) = eakb_maxF(i)
449 else
4500 eakb(i) = max_eakb(i)
451 endif
452 call F_kb_to_ea_kb(h_bl, Sref, Ent_bl, I_dSkbp1, F_kb, kmb, i, &
4530 G, GV, CS, eakb, Angstrom)
4540 if ((eakb(i) < max_eakb(i)) .or. (eakb(i) < min_eakb(i))) then
455 call determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, zeros, &
456 eakb, eakb, kmb, i, i, do_i, G, GV, CS, eakb, &
4570 error=err_eakb0)
4580 if (eakb(i) < max_eakb(i)) then
4590 max_eakb(i) = eakb(i) ; err_max_eakb0(i) = err_eakb0(i)
460 endif
4610 if (eakb(i) < min_eakb(i)) then
4620 min_eakb(i) = eakb(i) ; err_min_eakb0(i) = err_eakb0(i)
463 endif
464 endif
465 endif
466 endif
467 endif ; enddo ; enddo
4680 if (.not.CS%bulkmixedlayer) then
4690 do i=is,ie
4700 maxF(i,1) = MIN(maxF(i,1),dsp1_ds(i,2)*maxF(i,2) + htot(i))
471 enddo
472 endif
473
474! The following code provides an initial estimate of the flux in
475! each layer, F. The initial guess for the layer diffusive flux is
476! the smaller of a forward discretization or the maximum diffusive
477! flux starting from zero thickness in one time step without
478! considering adjacent layers.
4790 do i=is,ie
4800 F(i,1) = maxF(i,1)
4810 F(i,nz) = maxF(i,nz) ; minF(i,nz) = 0.0
482 enddo
4830 do k=nz-1,K2,-1
4840 do i=is,ie
4850 if ((k==kb(i)) .and. (do_i(i))) then
4860 eakb(i) = min_eakb(i)
4870 minF(i,k) = 0.0
4880 elseif ((k>kb(i)) .and. (do_i(i))) then
489! Here the layer flux is estimated, assuming no entrainment from
490! the surrounding layers. The estimate is a forward (steady) flux,
491! limited by the maximum flux for a layer starting with zero
492! thickness. This is often a good guess and leads to few iterations.
4930 hm = h(i,j,k) + h_neglect
494 ! Note: Tried sqrt((0.5*ds_dsp1(i,k))*dtKd(i,k)) for the second limit,
495 ! but it usually doesn't work as well.
496 F(i,k) = MIN(maxF(i,k), sqrt(ds_dsp1(i,k)*dtKd(i,k)), &
4970 0.5*(ds_dsp1(i,k)+1.0) * (dtKd(i,k) / hm))
498
499! Calculate the minimum flux that can be expected if there is no entrainment
500! from the neighboring layers. The 0.9 is used to give used to give a 10%
501! known error tolerance.
5020 fk = dtKd(i,k) * grats(i,k)
503 minF(i,k) = MIN(maxF(i,k), &
5040 0.9*(I2p2dsp1_ds(i,k) * fk / (hm + sqrt(hm*hm + fk))))
5050 if (k==kb(i)) minF(i,k) = 0.0 ! BACKWARD COMPATIBILITY - DELETE LATER?
506 else
5070 F(i,k) = 0.0
5080 minF(i,k) = 0.0
509 endif
510 enddo ! end of i loop
511 enddo ! end of k loop
512
513 ! This is where the fluxes are actually calculated.
514
5150 is1 = ie+1 ; ie1 = is-1
5160 do i=is,ie ; if (do_i(i)) then ; is1 = i ; exit ; endif ; enddo
5170 do i=ie,is,-1 ; if (do_i(i)) then ; ie1 = i ; exit ; endif ; enddo
518
5190 if (CS%bulkmixedlayer) then
5200 kb_min_act = nz
5210 do i=is,ie
5220 if (do_i(i) .and. (kb(i) < kb_min_act)) kb_min_act = kb(i)
523 enddo
524 ! Solve for the entrainment rate from above in the topmost interior
525 ! layer, eakb, such that
526 ! eakb*dS_implicit = dt*Kd*dS_layer_implicit / h_implicit.
5270 do i=is1,ie1
5280 ea_kbp1(i) = 0.0
5290 if (do_i(i) .and. (kb(i) < nz)) &
5300 ea_kbp1(i) = dsp1_ds(i,kb(i)+1)*F(i,kb(i)+1)
531 enddo
532 call determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, min_eakb, &
533 max_eakb, kmb, is1, ie1, do_i, G, GV, CS, eakb, F_kb=F_kb, &
534 err_max_eakb0=err_max_eakb0, err_min_eakb0=err_min_eakb0, &
5350 dFdfm_kb=dFdfm_kb)
536 else
5370 kb_min_act = kb_min
538 endif
539
5400 do it=0,CS%max_ent_it-1
5410 do i=is1,ie1 ; if (do_i(i)) then
5420 if (.not.CS%bulkmixedlayer) F(i,1) = MIN(F(i,1),maxF(i,1))
5430 b1(i) = 1.0
544 endif ; enddo ! end of i loop
545
546 ! F_kb has already been found for this iteration, either above or at
547 ! the end of the code for the previous iteration.
5480 do k=kb_min_act,nz-1 ; do i=is1,ie1 ; if (do_i(i) .and. (k>=kb(i))) then
549 ! Calculate the flux in layer k.
5500 if (CS%bulkmixedlayer .and. (k==kb(i))) then
5510 F(i,k) = F_kb(i)
5520 dFdfm(i,k) = dFdfm_kb(i)
553 else ! k > kb(i)
5540 Fprev(i,k) = F(i,k)
5550 fm = (F(i,k-1) - h(i,j,k)) + dsp1_ds(i,k+1)*F(i,k+1)
5560 fk = grats(i,k)*dtKd(i,k)
5570 fr = sqrt(fm*fm + fk)
558
5590 if (fm>=0) then
5600 F(i,k) = MIN(maxF(i,k), I2p2dsp1_ds(i,k) * (fm+fr))
561 else
5620 F(i,k) = MIN(maxF(i,k), I2p2dsp1_ds(i,k) * (fk / (-1.0*fm+fr)))
563 endif
564
5650 if ((F(i,k) >= maxF(i,k)) .or. (fr == 0.0)) then
5660 dFdfm(i,k) = 0.0
567 else
5680 dFdfm(i,k) = I2p2dsp1_ds(i,k) * ((fr + fm) / fr)
569 endif
570
5710 if (k > K2) then
572 ! This is part of a tridiagonal solver for the actual flux.
5730 c1(i,k) = dFdfm(i,k-1)*(dsp1_ds(i,k)*b1(i))
5740 b1(i) = 1.0 / (1.0 - c1(i,k)*dFdfm(i,k))
5750 F(i,k) = MIN(b1(i)*(F(i,k)-Fprev(i,k)) + Fprev(i,k), maxF(i,k))
5760 if (F(i,k) >= maxF(i,k)) dFdfm(i,k) = 0.0
577 endif
578 endif
579 endif ; enddo ; enddo
580
5810 do k=nz-2,kb_min_act,-1 ; do i=is1,ie1
5820 if (do_i(i) .and. (k > kb(i))) &
5830 F(i,k) = MIN((F(i,k)+c1(i,k+1)*(F(i,k+1)-Fprev(i,k+1))),maxF(i,k))
584 enddo ; enddo
585
5860 if (CS%bulkmixedlayer) then
5870 do i=is1,ie1
5880 if (do_i(i) .and. (kb(i) < nz)) then
589 ! F will be increased to minF later.
5900 ea_kbp1(i) = dsp1_ds(i,kb(i)+1)*max(F(i,kb(i)+1), minF(i,kb(i)+1))
591 else
5920 ea_kbp1(i) = 0.0
593 endif
594 enddo
595 call determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, min_eakb, &
596 max_eakb, kmb, is1, ie1, do_i, G, GV, CS, eakb, F_kb=F_kb, &
597 err_max_eakb0=err_max_eakb0, err_min_eakb0=err_min_eakb0, &
5980 dFdfm_kb=dFdfm_kb)
5990 do i=is1,ie1
6000 if (do_i(i) .and. (kb(i) < nz)) F(i,kb(i)) = F_kb(i)
601 enddo
602 endif
603
604! Determine whether to do another iteration.
6050 if (it < CS%max_ent_it-1) then
606
6070 reiterate = .false.
6080 if (CS%bulkmixedlayer) then ; do i=is1,ie1 ; if (do_i(i)) then
6090 eb_kmb(i) = max(2.0*Ent_bl(i,Kmb+1) - eakb(i), 0.0)
610 endif ; enddo ; endif
6110 do i=is1,ie1
6120 did_i(i) = do_i(i) ; do_i(i) = .false.
613 enddo
6140 do k=kb_min_act,nz-1 ; do i=is1,ie1
6150 if (did_i(i) .and. (k >= kb(i))) then
6160 if (F(i,k) < minF(i,k)) then
6170 F(i,k) = minF(i,k)
6180 do_i(i) = .true. ; reiterate = .true.
6190 elseif (k > kb(i)) then
6200 if ((abs(F(i,k) - Fprev(i,k)) > tolerance) .or. &
621 ((h(i,j,k) + ((1.0+dsp1_ds(i,k))*F(i,k) - &
622 (F(i,k-1) + dsp1_ds(i,k+1)*F(i,k+1)))) < 0.9*Angstrom)) then
6230 do_i(i) = .true. ; reiterate = .true.
624 endif
625 else ! (k == kb(i))
626! A more complicated test is required for the layer beneath the buffer layer,
627! since its flux may be partially used to entrain directly from the mixed layer.
628! Negative fluxes should not occur with the bulk mixed layer.
6290 if (h(i,j,k) + ((F(i,k) + eakb(i)) - &
630 (eb_kmb(i) + dsp1_ds(i,k+1)*F(i,k+1))) < 0.9*Angstrom) then
6310 do_i(i) = .true. ; reiterate = .true.
632 endif
633 endif
634 endif
635 enddo ; enddo
6360 if (.not.reiterate) exit
637 endif ! end of if (it < CS%max_ent_it-1)
638 enddo ! end of it loop
639! This is the end of the section that might be iterated.
640
641
6420 if (it == (CS%max_ent_it)) then
643 ! Limit the flux so that the layer below is not depleted.
644 ! This should only be applied to the last iteration.
6450 do i=is1,ie1 ; if (do_i(i)) then
6460 F(i,nz-1) = MAX(F(i,nz-1), MIN(minF(i,nz-1), 0.0))
6470 if (kb(i) >= nz-1) then ; ea_kbp1(i) = 0.0 ; endif
648 endif ; enddo
6490 do k=nz-2,kb_min_act,-1 ; do i=is1,ie1 ; if (do_i(i)) then
6500 if (k>kb(i)) then
651 F(i,k) = MIN(MAX(minF(i,k),F(i,k)), (dsp1_ds(i,k+1)*F(i,k+1) + &
652 MAX(((F(i,k+1)-dsp1_ds(i,k+2)*F(i,k+2)) + &
6530 (h(i,j,k+1) - Angstrom)), 0.5*(h(i,j,k+1)-Angstrom))))
6540 elseif (k==kb(i)) then
6550 ea_kbp1(i) = dsp1_ds(i,k+1)*F(i,k+1)
656 h_avail = dsp1_ds(i,k+1)*F(i,k+1) + MAX(0.5*(h(i,j,k+1)-Angstrom), &
6570 ((F(i,k+1)-dsp1_ds(i,k+2)*F(i,k+2)) + (h(i,j,k+1) - Angstrom)))
6580 if ((F(i,k) > 0.0) .and. (F(i,k) > h_avail)) then
6590 F_kb(i) = MAX(0.0, h_avail)
6600 F(i,k) = F_kb(i)
6610 if ((F_kb(i) < maxF_kb(i)) .and. (eakb_maxF(i) <= eakb(i))) &
6620 eakb(i) = eakb_maxF(i)
663 call F_kb_to_ea_kb(h_bl, Sref, Ent_bl, I_dSkbp1, F_kb, kmb, i, &
6640 G, GV, CS, eakb)
665 endif
666 endif
667 endif ; enddo ; enddo
668
669
6700 if (CS%bulkmixedlayer) then ; do i=is1,ie1
6710 if (do_i(i) .and. (kb(i) < nz)) then
672 h_avail = eakb(i) + MAX(0.5*(h_bl(i,kmb+1)-Angstrom), &
6730 (F_kb(i)-ea_kbp1(i)) + (h_bl(i,kmb+1)-Angstrom))
674 ! Ensure that 0 < eb_kmb < h_avail.
6750 Ent_bl(i,Kmb+1) = MIN(Ent_bl(i,Kmb+1),0.5*(eakb(i) + h_avail))
676
6770 eb_kmb(i) = max(2.0*Ent_bl(i,Kmb+1) - eakb(i), 0.0)
678 endif
679 enddo ; endif
680
681 ! Limit the flux so that the layer above is not depleted.
6820 do k=kb_min_act+1,nz-1 ; do i=is1,ie1 ; if (do_i(i)) then
6830 if ((.not.CS%bulkmixedlayer) .or. (k > kb(i)+1)) then
684 F(i,k) = MIN(F(i,k), ds_dsp1(i,k)*( ((F(i,k-1) + &
6850 dsp1_ds(i,k-1)*F(i,k-1)) - F(i,k-2)) + (h(i,j,k-1) - Angstrom)))
6860 F(i,k) = MAX(F(i,k),MIN(minF(i,k),0.0))
6870 elseif (k == kb(i)+1) then
688 F(i,k) = MIN(F(i,k), ds_dsp1(i,k)*( ((F(i,k-1) + eakb(i)) - &
6890 eb_kmb(i)) + (h(i,j,k-1) - Angstrom)))
6900 F(i,k) = MAX(F(i,k),MIN(minF(i,k),0.0))
691 endif
692 endif ; enddo ; enddo
693 endif ! (it == (CS%max_ent_it))
694
6950 call F_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb)
696
697 ! Calculate the layer thicknesses after the entrainment to constrain the
698 ! corrective fluxes.
6990 if (associated(tv%eqn_of_state)) then
7000 do i=is,ie
7010 h_guess(i,1) = (h(i,j,1) - Angstrom) + (eb(i,j,1) - ea(i,j,2))
7020 h_guess(i,nz) = (h(i,j,nz) - Angstrom) + (ea(i,j,nz) - eb(i,j,nz-1))
7030 if (h_guess(i,1) < 0.0) h_guess(i,1) = 0.0
7040 if (h_guess(i,nz) < 0.0) h_guess(i,nz) = 0.0
705 enddo
7060 do k=2,nz-1 ; do i=is,ie
707 h_guess(i,k) = (h(i,j,k) - Angstrom) + ((ea(i,j,k) - eb(i,j,k-1)) + &
7080 (eb(i,j,k) - ea(i,j,k+1)))
7090 if (h_guess(i,k) < 0.0) h_guess(i,k) = 0.0
710 enddo ; enddo
7110 if (CS%bulkmixedlayer) then
712 call determine_dSkb(h_bl, Sref, Ent_bl, eakb, is, ie, kmb, G, GV, &
7130 .true., dS_kb, dS_anom_lim=dS_anom_lim)
7140 do k=nz-1,kb_min,-1
7150 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pres, Rcv, tv%eqn_of_state, EOSdom)
7160 do i=is,ie
7170 if ((k>kb(i)) .and. (F(i,k) > 0.0)) then
718 ! Within a time step, a layer may entrain no more than its
719 ! thickness for correction. This limitation should apply
720 ! extremely rarely, but precludes undesirable behavior.
721 ! Note: Corrected a sign/logic error & factor of 2 error, and
722 ! the layers tracked the target density better, mostly due to
723 ! the factor of 2 error.
724 F_cor = h(i,j,k) * MIN(1.0 , MAX(-ds_dsp1(i,k), &
7250 (GV%Rlay(k) - Rcv(i)) / (GV%Rlay(k+1)-GV%Rlay(k))) )
726
727 ! Ensure that (1) Entrainments are positive, (2) Corrections in
728 ! a layer cannot deplete the layer itself (very generously), and
729 ! (3) a layer can take no more than a quarter the mass of its
730 ! neighbor.
7310 if (F_cor > 0.0) then
732 F_cor = MIN(F_cor, 0.9*F(i,k), ds_dsp1(i,k)*0.5*h_guess(i,k), &
7330 0.25*h_guess(i,k+1))
734 else
735 F_cor = -MIN(-F_cor, 0.9*F(i,k), 0.5*h_guess(i,k), &
7360 0.25*ds_dsp1(i,k)*h_guess(i,k-1) )
737 endif
738
7390 ea(i,j,k) = ea(i,j,k) - dsp1_ds(i,k)*F_cor
7400 eb(i,j,k) = eb(i,j,k) + F_cor
7410 elseif ((k==kb(i)) .and. (F(i,k) > 0.0)) then
742 ! Rho_cor is the density anomaly that needs to be corrected,
743 ! taking into account that the true potential density of the
744 ! deepest buffer layer is not exactly what is returned as dS_kb.
7450 dS_kb_eff = 2.0*dS_kb(i) - dS_anom_lim(i) ! Could be negative!!!
7460 Rho_cor = h(i,j,k) * (GV%Rlay(k)-Rcv(i)) + eakb(i)*dS_anom_lim(i)
747
748 ! Ensure that -.9*eakb < ea_cor < .9*eakb
7490 if (abs(Rho_cor) < abs(0.9*eakb(i)*dS_kb_eff)) then
7500 ea_cor = -Rho_cor / dS_kb_eff
751 else
7520 ea_cor = sign(0.9*eakb(i),-Rho_cor*dS_kb_eff)
753 endif
754
7550 if (ea_cor > 0.0) then
756 ! Ensure that -F_cor < 0.5*h_guess
757 ea_cor = MIN(ea_cor, 0.5*(max_eakb(i) - eakb(i)), &
7580 0.5*h_guess(i,k) / (dS_kb(i) * I_dSkbp1(i)))
759 else
760 ! Ensure that -ea_cor < 0.5*h_guess & F_cor < 0.25*h_guess(k+1)
761 ea_cor = -MIN(-ea_cor, 0.5*h_guess(i,k), &
7620 0.25*h_guess(i,k+1) / (dS_kb(i) * I_dSkbp1(i)))
763 endif
764
7650 ea(i,j,k) = ea(i,j,k) + ea_cor
7660 eb(i,j,k) = eb(i,j,k) - (dS_kb(i) * I_dSkbp1(i)) * ea_cor
7670 elseif (k < kb(i)) then
768 ! Repetitive, unless ea(kb) has been corrected.
7690 ea(i,j,k) = ea(i,j,k+1)
770 endif
771 enddo
772 enddo
7730 do k=kb_min-1,K2,-1 ; do i=is,ie
7740 ea(i,j,k) = ea(i,j,k+1)
775 enddo ; enddo
776
777 ! Repetitive, unless ea(kb) has been corrected.
7780 k=kmb
7790 do i=is,ie
780 ! Do not adjust eb through the base of the buffer layers, but it
781 ! may be necessary to change entrainment from above.
7820 h1 = (h(i,j,k) - Angstrom) + (eb(i,j,k) - ea(i,j,k+1))
7830 ea(i,j,k) = MAX(Ent_bl(i,K), Ent_bl(i,K)-0.5*h1, -h1)
784 enddo
7850 do k=kmb-1,2,-1 ; do i=is,ie
786 ! Determine the entrainment from below for each buffer layer.
7870 eb(i,j,k) = max(2.0*Ent_bl(i,K+1) - ea(i,j,k+1), 0.0)
788
789 ! Determine the entrainment from above for each buffer layer.
7900 h1 = (h(i,j,k) - Angstrom) + (eb(i,j,k) - ea(i,j,k+1))
7910 ea(i,j,k) = MAX(Ent_bl(i,K), Ent_bl(i,K)-0.5*h1, -h1)
792 enddo ; enddo
7930 do i=is,ie
7940 eb(i,j,1) = max(2.0*Ent_bl(i,2) - ea(i,j,2), 0.0)
795 enddo
796
797 else ! not bulkmixedlayer
7980 do k=K2,nz-1
7990 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pres, Rcv, tv%eqn_of_state, EOSdom)
8000 do i=is,ie ; if (F(i,k) > 0.0) then
801 ! Within a time step, a layer may entrain no more than
802 ! its thickness for correction. This limitation should
803 ! apply extremely rarely, but precludes undesirable
804 ! behavior.
805 F_cor = h(i,j,k) * MIN(dsp1_ds(i,k) , MAX(-1.0, &
8060 (GV%Rlay(k) - Rcv(i)) / (GV%Rlay(k+1)-GV%Rlay(k))) )
807
808 ! Ensure that (1) Entrainments are positive, (2) Corrections in
809 ! a layer cannot deplete the layer itself (very generously), and
810 ! (3) a layer can take no more than a quarter the mass of its
811 ! neighbor.
8120 if (F_cor >= 0.0) then
813 F_cor = MIN(F_cor, 0.9*F(i,k), 0.5*dsp1_ds(i,k)*h_guess(i,k), &
8140 0.25*h_guess(i,k+1))
815 else
816 F_cor = -MIN(-F_cor, 0.9*F(i,k), 0.5*h_guess(i,k), &
8170 0.25*ds_dsp1(i,k)*h_guess(i,k-1) )
818 endif
819
8200 ea(i,j,k) = ea(i,j,k) - dsp1_ds(i,k)*F_cor
8210 eb(i,j,k) = eb(i,j,k) + F_cor
822 endif ; enddo
823 enddo
824 endif
825
826 endif ! associated(tv%eqn_of_state))
827
8280 if (CS%id_Kd > 0) then
8290 Idt = (GV%H_to_m*US%m_to_Z) / dt
8300 do k=2,nz-1 ; do i=is,ie
8310 if (k<kb(i)) then ; Kd_here = 0.0 ; else
832 Kd_here = F(i,k) * ( h(i,j,k) + ((ea(i,j,k) - eb(i,j,k-1)) + &
8330 (eb(i,j,k) - ea(i,j,k+1))) ) / (I2p2dsp1_ds(i,k) * grats(i,k))
834 endif
835
8360 Kd_eff(i,j,k) = MAX(dtKd(i,k), Kd_here)*Idt
837 enddo ; enddo
8380 do i=is,ie
8390 Kd_eff(i,j,1) = dtKd(i,1)*Idt
8400 Kd_eff(i,j,nz) = dtKd(i,nz)*Idt
841 enddo
842 endif
843
8440 if (CS%id_diff_work > 0) then
8450 if (GV%Boussinesq .or. .not.associated(tv%eqn_of_state)) then
8460 g_2dt = 0.5 * GV%H_to_Z**2 * (GV%g_Earth_Z_T2 / dt)
847 else
8480 g_2dt = 0.5 * GV%H_to_RZ**2 * (GV%g_Earth_Z_T2 / dt)
849 endif
8500 do i=is,ie ; diff_work(i,j,1) = 0.0 ; diff_work(i,j,nz+1) = 0.0 ; enddo
8510 if (associated(tv%eqn_of_state)) then
8520 if (associated(fluxes%p_surf)) then
8530 do i=is,ie ; pressure(i) = fluxes%p_surf(i,j) ; enddo
854 else
8550 do i=is,ie ; pressure(i) = 0.0 ; enddo
856 endif
8570 do K=2,nz
8580 do i=is,ie ; pressure(i) = pressure(i) + (GV%g_Earth*GV%H_to_RZ)*h(i,j,k-1) ; enddo
8590 do i=is,ie
8600 if (k==kb(i)) then
8610 T_eos(i) = 0.5*(tv%T(i,j,kmb) + tv%T(i,j,k))
8620 S_eos(i) = 0.5*(tv%S(i,j,kmb) + tv%S(i,j,k))
863 else
8640 T_eos(i) = 0.5*(tv%T(i,j,k-1) + tv%T(i,j,k))
8650 S_eos(i) = 0.5*(tv%S(i,j,k-1) + tv%S(i,j,k))
866 endif
867 enddo
8680 if (GV%Boussinesq) then
869 call calculate_density_derivs(T_EOS, S_EOS, pressure, dRho_dT, dRho_dS, &
8700 tv%eqn_of_state, EOSdom)
8710 do i=is,ie
8720 if ((k>kmb) .and. (k<kb(i))) then ; diff_work(i,j,K) = 0.0
873 else
8740 if (k==kb(i)) then
875 dRho = dRho_dT(i) * (tv%T(i,j,k)-tv%T(i,j,kmb)) + &
8760 dRho_dS(i) * (tv%S(i,j,k)-tv%S(i,j,kmb))
877 else
878 dRho = dRho_dT(i) * (tv%T(i,j,k)-tv%T(i,j,k-1)) + &
8790 dRho_dS(i) * (tv%S(i,j,k)-tv%S(i,j,k-1))
880 endif
881 diff_work(i,j,K) = g_2dt * dRho * &
882 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
8830 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
884 endif
885 enddo
886 else
887 call calculate_specific_vol_derivs(T_EOS, S_EOS, pressure, dSpV_dT, dSpV_dS, &
8880 tv%eqn_of_state, EOSdom)
889
8900 do i=is,ie
8910 if ((k>kmb) .and. (k<kb(i))) then ; diff_work(i,j,K) = 0.0
892 else
8930 if (k==kb(i)) then
894 dSpV = dSpV_dT(i) * (tv%T(i,j,k)-tv%T(i,j,kmb)) + &
8950 dSpV_dS(i) * (tv%S(i,j,k)-tv%S(i,j,kmb))
896 else
897 dSpV = dSpV_dT(i) * (tv%T(i,j,k)-tv%T(i,j,k-1)) + &
8980 dSpV_dS(i) * (tv%S(i,j,k)-tv%S(i,j,k-1))
899 endif
900 diff_work(i,j,K) = -g_2dt * dSpV * &
901 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
9020 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
903 endif
904 enddo
905 endif
906 enddo
907 else
9080 do K=2,nz ; do i=is,ie
909 diff_work(i,j,K) = g_2dt * (GV%Rlay(k)-GV%Rlay(k-1)) * &
910 (ea(i,j,k) * (h(i,j,k) + ea(i,j,k)) + &
9110 eb(i,j,k-1)*(h(i,j,k-1) + eb(i,j,k-1)))
912 enddo ; enddo
913 endif
914 endif
915
9160 do i=is,ie ; kb_out(i,j) = kb(i) ; enddo
917
918 enddo ! end of j loop
919
920! Offer diagnostic fields for averaging.
9210 if (CS%id_Kd > 0) call post_data(CS%id_Kd, Kd_eff, CS%diag)
9220 if (CS%id_Kd > 0) deallocate(Kd_eff)
9230 if (CS%id_diff_work > 0) call post_data(CS%id_diff_work, diff_work, CS%diag)
9240 if (CS%id_diff_work > 0) deallocate(diff_work)
925
9260end subroutine entrainment_diffusive
927
928!> This subroutine calculates the actual entrainments (ea and eb) and the
929!! amount of surface forcing that is applied to each layer if there is no bulk
930!! mixed layer.
9310subroutine F_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb)
932 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure
933 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure
934 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: F !< The density flux through a layer within
935 !! a time step divided by the density
936 !! difference across the interface below
937 !! the layer [H ~> m or kg m-2].
938 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
939 intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]
940 integer, dimension(SZI_(G)), intent(in) :: kb !< The index of the lightest layer denser than
941 !! the deepest buffer layer.
942 integer, intent(in) :: kmb !< The number of mixed and buffer layers.
943 integer, intent(in) :: j !< The meridional index upon which to work.
944 type(entrain_diffusive_CS), intent(in) :: CS !< This module's control structure.
945 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: dsp1_ds !< The ratio of coordinate variable
946 !! differences across the interfaces below
947 !! a layer over the difference across the
948 !! interface above the layer [nondim].
949 real, dimension(SZI_(G)), intent(in) :: eakb !< The entrainment from above by the layer
950 !! below the buffer layer [H ~> m or kg m-2].
951 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: Ent_bl !< The average entrainment upward and
952 !! downward across each interface around
953 !! the buffer layers [H ~> m or kg m-2].
954 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
955 intent(inout) :: ea !< The amount of fluid entrained from the layer
956 !! above within this time step [H ~> m or kg m-2].
957 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
958 intent(inout) :: eb !< The amount of fluid entrained from the layer
959 !! below within this time step [H ~> m or kg m-2].
960
961 real :: h1 ! The thickness in excess of the minimum that will remain
962 ! after exchange with the layer below [H ~> m or kg m-2].
963 integer :: i, k, is, ie, nz
964
9650 is = G%isc ; ie = G%iec ; nz = GV%ke
966
9670 do i=is,ie
9680 ea(i,j,nz) = 0.0 ; eb(i,j,nz) = 0.0
969 enddo
9700 if (CS%bulkmixedlayer) then
9710 do i=is,ie
9720 eb(i,j,kmb) = max(2.0*Ent_bl(i,Kmb+1) - eakb(i), 0.0)
973 enddo
9740 do k=nz-1,kmb+1,-1 ; do i=is,ie
9750 if (k > kb(i)) then
976 ! With a bulk mixed layer, surface buoyancy fluxes are applied
977 ! elsewhere, so F should always be nonnegative.
9780 ea(i,j,k) = dsp1_ds(i,k)*F(i,k)
9790 eb(i,j,k) = F(i,k)
9800 elseif (k == kb(i)) then
9810 ea(i,j,k) = eakb(i)
9820 eb(i,j,k) = F(i,k)
9830 elseif (k == kb(i)-1) then
9840 ea(i,j,k) = ea(i,j,k+1)
9850 eb(i,j,k) = eb(i,j,kmb)
986 else
9870 ea(i,j,k) = ea(i,j,k+1)
988 ! Add the entrainment of the thin interior layers to eb going
989 ! up into the buffer layer.
9900 eb(i,j,k) = eb(i,j,k+1) + max(0.0, h(i,j,k+1) - GV%Angstrom_H)
991 endif
992 enddo ; enddo
9930 k = kmb
9940 do i=is,ie
995 ! Adjust the previously calculated entrainment from below by the deepest
996 ! buffer layer to account for entrainment of thin interior layers .
9970 if (kb(i) > kmb+1) &
9980 eb(i,j,k) = eb(i,j,k+1) + max(0.0, h(i,j,k+1) - GV%Angstrom_H)
999
1000 ! Determine the entrainment from above for each buffer layer.
10010 h1 = (h(i,j,k) - GV%Angstrom_H) + (eb(i,j,k) - ea(i,j,k+1))
10020 ea(i,j,k) = MAX(Ent_bl(i,K), Ent_bl(i,K)-0.5*h1, -h1)
1003 enddo
10040 do k=kmb-1,2,-1 ; do i=is,ie
1005 ! Determine the entrainment from below for each buffer layer.
10060 eb(i,j,k) = max(2.0*Ent_bl(i,K+1) - ea(i,j,k+1), 0.0)
1007
1008 ! Determine the entrainment from above for each buffer layer.
10090 h1 = (h(i,j,k) - GV%Angstrom_H) + (eb(i,j,k) - ea(i,j,k+1))
10100 ea(i,j,k) = MAX(Ent_bl(i,K), Ent_bl(i,K)-0.5*h1, -h1)
1011! if (h1 >= 0.0) then ; ea(i,j,k) = Ent_bl(i,K)
1012! elseif (Ent_bl(i,K)+0.5*h1 >= 0.0) then ; ea(i,j,k) = Ent_bl(i,K)-0.5*h1
1013! else ; ea(i,j,k) = -h1 ; endif
1014 enddo ; enddo
10150 do i=is,ie
10160 eb(i,j,1) = max(2.0*Ent_bl(i,2) - ea(i,j,2), 0.0)
10170 ea(i,j,1) = 0.0
1018 enddo
1019 else ! not BULKMIXEDLAYER
1020 ! Calculate the entrainment by each layer from above and below.
1021 ! Entrainment is always positive, but F may be negative due to
1022 ! surface buoyancy fluxes.
10230 do i=is,ie
10240 ea(i,j,1) = 0.0 ; eb(i,j,1) = MAX(F(i,1),0.0)
10250 ea(i,j,2) = dsp1_ds(i,2)*F(i,2) - MIN(F(i,1),0.0)
1026 enddo
1027
10280 do k=2,nz-1 ; do i=is,ie
10290 eb(i,j,k) = MAX(F(i,k),0.0)
10300 ea(i,j,k+1) = dsp1_ds(i,k+1)*F(i,k+1) - (F(i,k)-eb(i,j,k))
10310 if (ea(i,j,k+1) < 0.0) then
10320 eb(i,j,k) = eb(i,j,k) - ea(i,j,k+1)
10330 ea(i,j,k+1) = 0.0
1034 endif
1035 enddo ; enddo
1036 endif ! end BULKMIXEDLAYER
10370end subroutine F_to_ent
1038
1039!> This subroutine sets the average entrainment across each of the interfaces
1040!! between buffer layers within a timestep. It also causes thin and relatively
1041!! light interior layers to be entrained by the deepest buffer layer.
1042!! Also find the initial coordinate potential densities (Sref) of each layer.
10430subroutine set_Ent_bl(h, dtKd_int, tv, kb, kmb, do_i, G, GV, US, CS, j, Ent_bl, Sref, h_bl)
1044 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
1045 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
1046 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
1047 intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]
1048 real, dimension(SZI_(G),SZK_(GV)+1), &
1049 intent(in) :: dtKd_int !< The diapycnal diffusivity across
1050 !! each interface times the time step
1051 !! [H2 ~> m2 or kg2 m-4].
1052 type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any
1053 !! available thermodynamic fields. Absent
1054 !! fields have NULL ptrs.
1055 integer, dimension(SZI_(G)), intent(inout) :: kb !< The index of the lightest layer denser
1056 !! than the buffer layer or 1 if there is
1057 !! no buffer layer.
1058 integer, intent(in) :: kmb !< The number of mixed and buffer layers.
1059 logical, dimension(SZI_(G)), intent(in) :: do_i !< A logical variable indicating which
1060 !! i-points to work on.
1061 type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
1062 type(entrain_diffusive_CS), intent(in) :: CS !< This module's control structure.
1063 integer, intent(in) :: j !< The meridional index upon which to work.
1064 real, dimension(SZI_(G),SZK_(GV)+1), &
1065 intent(out) :: Ent_bl !< The average entrainment upward and
1066 !! downward across each interface around
1067 !! the buffer layers [H ~> m or kg m-2].
1068 real, dimension(SZI_(G),SZK_(GV)), intent(out) :: Sref !< The coordinate potential density minus
1069 !! 1000 for each layer [R ~> kg m-3].
1070 real, dimension(SZI_(G),SZK_(GV)), intent(out) :: h_bl !< The thickness of each layer [H ~> m or kg m-2].
1071
1072! This subroutine sets the average entrainment across each of the interfaces
1073! between buffer layers within a timestep. It also causes thin and relatively
1074! light interior layers to be entrained by the deepest buffer layer.
1075! Also find the initial coordinate potential densities (Sref) of each layer.
1076! Does there need to be limiting when the layers below are all thin?
1077
1078 ! Local variables
1079 real, dimension(SZI_(G)) :: &
10800 b1, d1, & ! Variables used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1] and [nondim].
10810 Rcv, & ! Value of the coordinate variable (potential density)
1082 ! based on the simulated T and S and P_Ref [R ~> kg m-3].
10830 pres, & ! Reference pressure (P_Ref) [R L2 T-2 ~> Pa].
10840 frac_rem, & ! The fraction of the diffusion remaining [nondim].
10850 h_interior ! The interior thickness available for entrainment [H ~> m or kg m-2].
1086 real, dimension(SZI_(G), SZK_(GV)) :: &
10870 S_est ! An estimate of the coordinate potential density - 1000 after
1088 ! entrainment for each layer [R ~> kg m-3].
1089 real :: dh ! An available thickness [H ~> m or kg m-2].
1090 real :: Kd_x_dt ! The diffusion that remains after thin layers are
1091 ! entrained [H2 ~> m2 or kg2 m-4].
1092 real :: h_neglect ! A thickness that is so small it is usually lost
1093 ! in roundoff and can be neglected [H ~> m or kg m-2].
1094 integer, dimension(2) :: EOSdom ! The i-computational domain for the equation of state
1095 integer :: i, k, is, ie, nz
10960 is = G%isc ; ie = G%iec ; nz = GV%ke
1097
10980 h_neglect = GV%H_subroundoff
1099
11000 do i=is,ie ; pres(i) = tv%P_Ref ; enddo
11010 EOSdom(:) = EOS_domain(G%HI)
11020 do k=1,kmb
11030 call calculate_density(tv%T(:,j,k), tv%S(:,j,k), pres, Rcv, tv%eqn_of_state, EOSdom)
11040 do i=is,ie
11050 h_bl(i,k) = h(i,j,k) + h_neglect
11060 Sref(i,k) = Rcv(i) - CS%Rho_sig_off
1107 enddo
1108 enddo
1109
11100 do i=is,ie
11110 h_interior(i) = 0.0 ; Ent_bl(i,1) = 0.0
1112! if (kb(i) > nz) Ent_bl(i,Kmb+1) = 0.0
1113 enddo
1114
11150 do k=2,kmb ; do i=is,ie
11160 if (do_i(i)) then
11170 Ent_bl(i,K) = min(2.0 * dtKd_int(i,K) / (h(i,j,k-1) + h(i,j,k) + h_neglect), CS%max_Ent)
11180 else ; Ent_bl(i,K) = 0.0 ; endif
1119 enddo ; enddo
1120
1121 ! Determine the coordinate density of the bottommost buffer layer if there
1122 ! is no entrainment from the layers below. This is a partial solver, based
1123 ! on the first pass of a tridiagonal solver, as the values in the upper buffer
1124 ! layers are not needed.
1125
11260 do i=is,ie
11270 b1(i) = 1.0 / (h_bl(i,1) + Ent_bl(i,2))
11280 d1(i) = h_bl(i,1) * b1(i) ! = 1.0 - Ent_bl(i,2)*b1(i)
11290 S_est(i,1) = (h_bl(i,1)*Sref(i,1)) * b1(i)
1130 enddo
11310 do k=2,kmb-1 ; do i=is,ie
11320 b1(i) = 1.0 / ((h_bl(i,k) + Ent_bl(i,K+1)) + d1(i)*Ent_bl(i,K))
11330 d1(i) = (h_bl(i,k) + d1(i)*Ent_bl(i,K)) * b1(i) ! = 1.0 - Ent_bl(i,K+1)*b1(i)
11340 S_est(i,k) = (h_bl(i,k)*Sref(i,k) + Ent_bl(i,K)*S_est(i,k-1)) * b1(i)
1135 enddo ; enddo
11360 do i=is,ie
1137 S_est(i,kmb) = (h_bl(i,kmb)*Sref(i,kmb) + Ent_bl(i,Kmb)*S_est(i,kmb-1)) / &
11380 (h_bl(i,kmb) + d1(i)*Ent_bl(i,Kmb))
11390 frac_rem(i) = 1.0
1140 enddo
1141
1142 ! Entrain any thin interior layers that are lighter (in the coordinate
1143 ! potential density) than the deepest buffer layer will be, and adjust kb.
11440 do i=is,ie ; kb(i) = nz+1 ; if (do_i(i)) kb(i) = kmb+1 ; enddo
1145
11460 do k=kmb+1,nz ; do i=is,ie ; if (do_i(i)) then
11470 if ((k == kb(i)) .and. (S_est(i,kmb) > (GV%Rlay(k) - CS%Rho_sig_off))) then
11480 if (4.0*dtKd_int(i,Kmb+1)*frac_rem(i) > &
1149 (h_bl(i,kmb) + h(i,j,k)) * (h(i,j,k) - GV%Angstrom_H)) then
1150 ! Entrain this layer into the buffer layer and move kb down.
11510 dh = max((h(i,j,k) - GV%Angstrom_H), 0.0)
11520 if (dh > 0.0) then
1153 frac_rem(i) = frac_rem(i) - ((h_bl(i,kmb) + h(i,j,k)) * dh) / &
11540 (4.0*dtKd_int(i,Kmb+1))
1155 Sref(i,kmb) = (h_bl(i,kmb)*Sref(i,kmb) + dh*(GV%Rlay(k)-CS%Rho_sig_off)) / &
11560 (h_bl(i,kmb) + dh)
11570 h_bl(i,kmb) = h_bl(i,kmb) + dh
1158 S_est(i,kmb) = (h_bl(i,kmb)*Sref(i,kmb) + Ent_bl(i,Kmb)*S_est(i,kmb-1)) / &
11590 (h_bl(i,kmb) + d1(i)*Ent_bl(i,Kmb))
1160 endif
11610 kb(i) = kb(i) + 1
1162 endif
1163 endif
1164 endif ; enddo ; enddo
1165
1166 ! This is where variables are be set up with a different vertical grid
1167 ! in which the (newly?) massless layers are taken out.
11680 do k=nz,kmb+1,-1 ; do i=is,ie
11690 if (k >= kb(i)) h_interior(i) = h_interior(i) + (h(i,j,k)-GV%Angstrom_H)
11700 if (k==kb(i)) then
11710 h_bl(i,kmb+1) = h(i,j,k) ; Sref(i,kmb+1) = GV%Rlay(k) - CS%Rho_sig_off
11720 elseif (k==kb(i)+1) then
11730 h_bl(i,kmb+2) = h(i,j,k) ; Sref(i,kmb+2) = GV%Rlay(k) - CS%Rho_sig_off
1174 endif
1175 enddo ; enddo
11760 do i=is,ie ; if (kb(i) >= nz) then
11770 h_bl(i,kmb+1) = h(i,j,nz)
11780 Sref(i,kmb+1) = GV%Rlay(nz) - CS%Rho_sig_off
11790 h_bl(i,kmb+2) = GV%Angstrom_H
11800 Sref(i,kmb+2) = Sref(i,kmb+1) + (GV%Rlay(nz) - GV%Rlay(nz-1))
1181 endif ; enddo
1182
1183 ! Perhaps we should revisit the way that the average entrainment between the
1184 ! buffer layer and the interior is calculated so that it is not unduly
1185 ! limited when the layers are less than sqrt(Kd * dt) thick?
11860 do i=is,ie ; if (do_i(i)) then
11870 Kd_x_dt = frac_rem(i) * dtKd_int(i,Kmb+1)
11880 if ((Kd_x_dt <= 0.0) .or. (h_interior(i) <= 0.0)) then
11890 Ent_bl(i,Kmb+1) = 0.0
1190 else
1191 ! If the combined layers are exceptionally thin, use sqrt(Kd*dt) as the
1192 ! estimate of the thickness in the denominator of the thickness diffusion.
1193 Ent_bl(i,Kmb+1) = MIN(0.5*h_interior(i), sqrt(Kd_x_dt), &
11940 Kd_x_dt / (0.5*(h_bl(i,kmb) + h_bl(i,kmb+1))))
1195 endif
1196 else
11970 Ent_bl(i,Kmb+1) = 0.0
1198 endif ; enddo
1199
12000end subroutine set_Ent_bl
1201
1202!> This subroutine determines the reference density difference between the
1203!! bottommost buffer layer and the first interior after the mixing between mixed
1204!! and buffer layers and mixing with the layer below. Within the mixed and buffer
1205!! layers, entrainment from the layer above is increased when it is necessary to
1206!! keep the layers from developing a negative thickness; otherwise it equals
1207!! Ent_bl. At each interface, the upward and downward fluxes average out to
1208!! Ent_bl, unless entrainment by the layer below is larger than twice Ent_bl.
1209!! The density difference across the first interior layer may also be returned.
1210!! It could also be limited to avoid negative values or values that greatly
1211!! exceed the density differences across an interface.
1212!! Additionally, the partial derivatives of dSkb and dSlay with E_kb could
1213!! also be returned.
12140subroutine determine_dSkb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, &
12150 dSkb, ddSkb_dE, dSlay, ddSlay_dE, dS_anom_lim, do_i_in)
1216 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
1217 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid
1218 !! structure.
1219 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: h_bl !< Layer thickness [H ~> m or kg m-2]
1220 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: Sref !< Reference potential density [R ~> kg m-3]
1221 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: Ent_bl !< The average entrainment upward and
1222 !! downward across each interface
1223 !! around the buffer layers [H ~> m or kg m-2].
1224 real, dimension(SZI_(G)), intent(in) :: E_kb !< The entrainment by the top interior
1225 !! layer [H ~> m or kg m-2].
1226 integer, intent(in) :: is !< The start of the i-index range to work on.
1227 integer, intent(in) :: ie !< The end of the i-index range to work on.
1228 integer, intent(in) :: kmb !< The number of mixed and buffer layers.
1229 logical, intent(in) :: limit !< If true, limit dSkb and dSlay to
1230 !! avoid negative values.
1231 real, dimension(SZI_(G)), intent(inout) :: dSkb !< The limited potential density
1232 !! difference across the interface
1233 !! between the bottommost buffer layer
1234 !! and the topmost interior layer. [R ~> kg m-3]
1235 !! dSkb > 0.
1236 real, dimension(SZI_(G)), optional, intent(inout) :: ddSkb_dE !< The partial derivative of dSkb
1237 !! with E [R H-1 ~> kg m-4 or m-1].
1238 real, dimension(SZI_(G)), optional, intent(inout) :: dSlay !< The limited potential density
1239 !! difference across the topmost
1240 !! interior layer. 0 < dSkb [R ~> kg m-3]
1241 real, dimension(SZI_(G)), optional, intent(inout) :: ddSlay_dE !< The partial derivative of dSlay
1242 !! with E [R H-1 ~> kg m-4 or m-1].
1243 real, dimension(SZI_(G)), optional, intent(inout) :: dS_anom_lim !< A limiting value to use for
1244 !! the density anomalies below the
1245 !! buffer layer [R ~> kg m-3].
1246 logical, dimension(SZI_(G)), optional, intent(in) :: do_i_in !< If present, determines which
1247 !! columns are worked on.
1248
1249! Note that dSkb, ddSkb_dE, dSlay, ddSlay_dE, and dS_anom_lim are declared
1250! intent inout because they should not change where do_i_in is false.
1251
1252! This subroutine determines the reference density difference between the
1253! bottommost buffer layer and the first interior after the mixing between mixed
1254! and buffer layers and mixing with the layer below. Within the mixed and buffer
1255! layers, entrainment from the layer above is increased when it is necessary to
1256! keep the layers from developing a negative thickness; otherwise it equals
1257! Ent_bl. At each interface, the upward and downward fluxes average out to
1258! Ent_bl, unless entrainment by the layer below is larger than twice Ent_bl.
1259! The density difference across the first interior layer may also be returned.
1260! It could also be limited to avoid negative values or values that greatly
1261! exceed the density differences across an interface.
1262! Additionally, the partial derivatives of dSkb and dSlay with E_kb could
1263! also be returned.
1264
1265 ! Local variables
1266 real, dimension(SZI_(G),SZK_(GV)) :: &
12670 b1, c1, & ! b1 [H-1 ~> m-1 or m2 kg-1] and c1 [nondim] are variables used by the tridiagonal solver.
12680 S, dS_dE, & ! The coordinate density [R ~> kg m-3] and its derivative with E [R H-1 ~> kg m-4 or m-1].
12690 ea, dea_dE, & ! The entrainment from above [H ~> m or kg m-2] and its derivative with E [nondim].
12700 eb, deb_dE ! The entrainment from below [H ~> m or kg m-2] and its derivative with E [nondim].
12710 real :: deriv_dSkb(SZI_(G)) ! The limited derivative of the new density difference across the base of
1272 ! the buffer layers with the new density of the bottommost buffer layer [nondim]
12730 real :: d1(SZI_(G)) ! d1 = 1.0-c1 is also used by the tridiagonal solver [nondim].
1274 real :: src ! A source term for dS_dR [R ~> kg m-3].
1275 real :: h1 ! The thickness in excess of the minimum that will remain
1276 ! after exchange with the layer below [H ~> m or kg m-2].
12770 logical, dimension(SZI_(G)) :: do_i
1278 real :: h_neglect ! A thickness that is so small it is usually lost
1279 ! in roundoff and can be neglected [H ~> m or kg m-2].
1280 real :: h_tr ! h_tr is h at tracer points with a tiny thickness
1281 ! added to ensure positive definiteness [H ~> m or kg m-2].
1282 real :: b_denom_1 ! The first term in the denominator of b1 [H ~> m or kg m-2].
1283 real :: rat ! A ratio of density differences [nondim]
1284 real :: dS_kbp1 ! The density difference between the top two interior layers [R ~> kg m-3].
1285 real :: IdS_kbp1 ! The inverse of dS_kbp1 [R-1 ~> m3 kg-1]
1286 real :: deriv_dSLay ! The derivative of the projected density difference across the topmost interior
1287 ! layer with the density difference across the interface above it [nondim]
1288 real :: Inv_term ! The inverse of a nondimensional expression [nondim]
1289 real :: f1, df1_drat ! Temporary variables [nondim].
1290 real :: z, dz_drat, f2, df2_dz, expz ! Temporary variables [nondim].
1291 real :: eps_dSLay, eps_dSkb ! Small nondimensional constants [nondim].
1292 integer :: i, k
1293
12940 if (present(ddSlay_dE) .and. .not.present(dSlay)) call MOM_error(FATAL, &
12950 "In deterimine_dSkb, ddSLay_dE may only be present if dSlay is.")
1296
12970 h_neglect = GV%H_subroundoff
1298
12990 do i=is,ie
13000 ea(i,kmb+1) = E_kb(i) ; dea_dE(i,kmb+1) = 1.0
13010 S(i,kmb+1) = Sref(i,kmb+1) ; dS_dE(i,kmb+1) = 0.0
13020 b1(i,kmb+1) = 0.0
13030 d1(i) = 1.0
13040 do_i(i) = .true.
1305 enddo
13060 if (present(do_i_in)) then
13070 do i=is,ie ; do_i(i) = do_i_in(i) ; enddo
1308 endif
13090 do k=kmb,1,-1 ; do i=is,ie
13100 if (do_i(i)) then
1311 ! The do_i test here is only for efficiency.
1312 ! Determine the entrainment from below for each buffer layer.
13130 if (2.0*Ent_bl(i,K+1) > ea(i,k+1)) then
13140 eb(i,k) = 2.0*Ent_bl(i,K+1) - ea(i,k+1) ; deb_dE(i,k) = -dea_dE(i,k+1)
1315 else
13160 eb(i,k) = 0.0 ; deb_dE(i,k) = 0.0
1317 endif
1318
1319 ! Determine the entrainment from above for each buffer layer.
13200 h1 = (h_bl(i,k) - GV%Angstrom_H) + (eb(i,k) - ea(i,k+1))
13210 if (h1 >= 0.0) then
13220 ea(i,k) = Ent_bl(i,K) ; dea_dE(i,k) = 0.0
13230 elseif (Ent_bl(i,K) + 0.5*h1 >= 0.0) then
13240 ea(i,k) = Ent_bl(i,K) - 0.5*h1
13250 dea_dE(i,k) = 0.5*(dea_dE(i,k+1) - deb_dE(i,k))
1326 else
13270 ea(i,k) = -h1
13280 dea_dE(i,k) = dea_dE(i,k+1) - deb_dE(i,k)
1329 endif
1330 else
13310 ea(i,k) = 0.0 ; dea_dE(i,k) = 0.0 ; eb(i,k) = 0.0 ; deb_dE(i,k) = 0.0
1332 endif
1333
1334 ! This is the first-pass of a tridiagonal solver for S.
13350 h_tr = h_bl(i,k) + h_neglect
13360 c1(i,k) = ea(i,k+1) * b1(i,k+1)
13370 b_denom_1 = (h_tr + d1(i)*eb(i,k))
13380 b1(i,k) = 1.0 / (b_denom_1 + ea(i,k))
13390 d1(i) = b_denom_1 * b1(i,k)
1340
13410 S(i,k) = (h_tr*Sref(i,k) + eb(i,k)*S(i,k+1)) * b1(i,k)
1342 enddo ; enddo
13430 do k=2,kmb ; do i=is,ie
13440 S(i,k) = S(i,k) + c1(i,k-1)*S(i,k-1)
1345 enddo ; enddo
1346
13470 if (present(ddSkb_dE) .or. present(ddSlay_dE)) then
1348 ! These two tridiagonal solvers cannot be combined because the solutions for
1349 ! S are required as a source for dS_dE.
13500 do k=kmb,2,-1 ; do i=is,ie
13510 if (do_i(i) .and. (dea_dE(i,k) - deb_dE(i,k) > 0.0)) then
1352 src = (((S(i,k+1) - Sref(i,k)) * (h_bl(i,k) + h_neglect) + &
1353 (S(i,k+1) - S(i,k-1)) * ea(i,k)) * deb_dE(i,k) - &
1354 ((Sref(i,k) - S(i,k-1)) * h_bl(i,k) + &
1355 (S(i,k+1) - S(i,k-1)) * eb(i,k)) * dea_dE(i,k)) / &
13560 ((h_bl(i,k) + h_neglect + ea(i,k)) + eb(i,k))
13570 else ; src = 0.0 ; endif
13580 dS_dE(i,k) = (src + eb(i,k)*dS_dE(i,k+1)) * b1(i,k)
1359 enddo ; enddo
13600 do i=is,ie
13610 if (do_i(i) .and. (deb_dE(i,1) < 0.0)) then
1362 src = (((S(i,2) - Sref(i,1)) * (h_bl(i,1) + h_neglect)) * deb_dE(i,1)) / &
13630 (h_bl(i,1) + h_neglect + eb(i,1))
13640 else ; src = 0.0 ; endif
13650 dS_dE(i,1) = (src + eb(i,1)*dS_dE(i,2)) * b1(i,1)
1366 enddo
13670 do k=2,kmb ; do i=is,ie
13680 dS_dE(i,k) = dS_dE(i,k) + c1(i,k-1)*dS_dE(i,k-1)
1369 enddo ; enddo
1370 endif
1371
1372 ! Now, apply any limiting and return the requested variables.
1373
13740 eps_dSkb = 1.0e-6 ! Should be a small, nondimensional, positive number.
13750 if (.not.limit) then
13760 do i=is,ie ; if (do_i(i)) then
13770 dSkb(i) = Sref(i,kmb+1) - S(i,kmb)
1378 endif ; enddo
13790 if (present(ddSkb_dE)) then ; do i=is,ie ; if (do_i(i)) then
13800 ddSkb_dE(i) = -1.0*dS_dE(i,kmb)
1381 endif ; enddo ; endif
1382
13830 if (present(dSlay)) then ; do i=is,ie ; if (do_i(i)) then
13840 dSlay(i) = 0.5 * (Sref(i,kmb+2) - S(i,kmb))
1385 endif ; enddo ; endif
13860 if (present(ddSlay_dE)) then ; do i=is,ie ; if (do_i(i)) then
13870 ddSlay_dE(i) = -0.5*dS_dE(i,kmb)
1388 endif ; enddo ; endif
1389 else
13900 do i=is,ie ; if (do_i(i)) then
1391 ! Need to ensure that 0 < dSkb <= S_kb - Sbl
13920 if (Sref(i,kmb+1) - S(i,kmb) < eps_dSkb*(Sref(i,kmb+2) - Sref(i,kmb+1))) then
13930 dSkb(i) = eps_dSkb * (Sref(i,kmb+2) - Sref(i,kmb+1)) ; deriv_dSkb(i) = 0.0
1394 else
13950 dSkb(i) = Sref(i,kmb+1) - S(i,kmb) ; deriv_dSkb(i) = -1.0
1396 endif
13970 if (present(ddSkb_dE)) ddSkb_dE(i) = deriv_dSkb(i)*dS_dE(i,kmb)
1398 endif ; enddo
1399
14000 if (present(dSLay)) then
14010 dz_drat = 1000.0 ! The limit of large dz_drat the same as choosing a
1402 ! Heaviside function.
14030 eps_dSLay = 1.0e-10 ! Should be ~= GV%Angstrom_H / sqrt(Kd*dt)
14040 do i=is,ie ; if (do_i(i)) then
14050 dS_kbp1 = Sref(i,kmb+2) - Sref(i,kmb+1)
14060 IdS_kbp1 = 1.0 / (Sref(i,kmb+2) - Sref(i,kmb+1))
14070 rat = (Sref(i,kmb+1) - S(i,kmb)) * IdS_kbp1
1408 ! Need to ensure that 0 < dSLay <= 2*dSkb
14090 if (rat < 0.5) then
1410 ! The coefficients here are chosen so that at rat = 0.5, the value (1.5)
1411 ! and first derivative (-0.5) match with the "typical" case (next).
1412 ! The functional form here is arbitrary.
1413 ! f1 provides a reasonable profile that matches the value and derivative
1414 ! of the "typical" case at rat = 0.5, and has a maximum of less than 2.
14150 Inv_term = 1.0 / (1.0-rat)
14160 f1 = 2.0 - 0.125*(Inv_term**2)
14170 df1_drat = - 0.25*(Inv_term**3)
1418
1419 ! f2 ensures that dSLay goes to 0 rapidly if rat is significantly
1420 ! negative.
14210 z = dz_drat * rat + 4.0 ! The 4 here gives f2(0) = 0.982.
14220 if (z >= 18.0) then ; f2 = 1.0 ; df2_dz = 0.0
14230 elseif (z <= -58.0) then ; f2 = eps_dSLay ; df2_dz = 0.0
1424 else
14250 expz = exp(z) ; Inv_term = 1.0 / (1.0 + expz)
14260 f2 = (eps_dSLay + expz) * Inv_term
14270 df2_dz = (1.0 - eps_dSLay) * expz * Inv_term**2
1428 endif
1429
14300 dSLay(i) = dSkb(i) * f1 * f2
1431 deriv_dSLay = deriv_dSkb(i) * (f1 * f2) - (dSkb(i)*IdS_kbp1) * &
14320 (df1_drat*f2 + f1 * dz_drat * df2_dz)
14330 elseif (dSkb(i) <= 3.0*dS_kbp1) then
1434 ! This is the "typical" case.
14350 dSLay(i) = 0.5 * (dSkb(i) + dS_kbp1)
14360 deriv_dSLay = 0.5 * deriv_dSkb(i) ! = -0.5
1437 else
14380 dSLay(i) = 2.0*dS_kbp1
14390 deriv_dSLay = 0.0
1440 endif
14410 if (present(ddSlay_dE)) ddSlay_dE(i) = deriv_dSLay*dS_dE(i,kmb)
1442 endif ; enddo
1443 endif ! present(dSlay)
1444 endif ! Not limited.
1445
14460 if (present(dS_anom_lim)) then ; do i=is,ie ; if (do_i(i)) then
1447 dS_anom_lim(i) = max(0.0, eps_dSkb * (Sref(i,kmb+2) - Sref(i,kmb+1)) - &
14480 (Sref(i,kmb+1) - S(i,kmb)) )
1449 endif ; enddo ; endif
1450
14510end subroutine determine_dSkb
1452
1453!> Given an entrainment from below for layer kb, determine a consistent
1454!! entrainment from above, such that dSkb * ea_kb = dSkbp1 * F_kb. The input
1455!! value of ea_kb is both the maximum value that can be obtained and the first
1456!! guess of the iterations. Ideally ea_kb should be an under-estimate
14570subroutine F_kb_to_ea_kb(h_bl, Sref, Ent_bl, I_dSkbp1, F_kb, kmb, i, &
14580 G, GV, CS, ea_kb, tol_in)
1459 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure
1460 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure
1461 real, dimension(SZI_(G),SZK_(GV)), &
1462 intent(in) :: h_bl !< Layer thickness, with the top interior
1463 !! layer at k-index kmb+1 [H ~> m or kg m-2].
1464 real, dimension(SZI_(G),SZK_(GV)), &
1465 intent(in) :: Sref !< The coordinate reference potential density,
1466 !! with the value of the topmost interior layer
1467 !! at index kmb+1 [R ~> kg m-3].
1468 real, dimension(SZI_(G),SZK_(GV)), &
1469 intent(in) :: Ent_bl !< The average entrainment upward and downward
1470 !! across each interface around the buffer layers,
1471 !! [H ~> m or kg m-2].
1472 real, dimension(SZI_(G)), intent(in) :: I_dSkbp1 !< The inverse of the difference in reference
1473 !! potential density across the base of the
1474 !! uppermost interior layer [R-1 ~> m3 kg-1].
1475 real, dimension(SZI_(G)), intent(in) :: F_kb !< The entrainment from below by the
1476 !! uppermost interior layer [H ~> m or kg m-2]
1477 integer, intent(in) :: kmb !< The number of mixed and buffer layers.
1478 integer, intent(in) :: i !< The i-index to work on
1479 type(entrain_diffusive_CS), intent(in) :: CS !< This module's control structure.
1480 real, dimension(SZI_(G)), intent(inout) :: ea_kb !< The entrainment from above by the layer below
1481 !! the buffer layer (i.e. layer kb) [H ~> m or kg m-2].
1482 real, optional, intent(in) :: tol_in !< A tolerance for the iterative determination
1483 !! of the entrainment [H ~> m or kg m-2].
1484
1485 real :: max_ea, min_ea ! Bounds on the estimated entraiment [H ~> m or kg m-2]
1486 real :: err, err_min, err_max ! Errors in the mass flux balance [H R ~> kg m-2 or kg2 m-5]
1487 real :: derr_dea ! The change in error with the change in ea [R ~> kg m-3]
1488 real :: val ! An estimate mass flux [H R ~> kg m-2 or kg2 m-5]
1489 real :: tolerance, tol1 ! Tolerances for the determination of the entrainment [H ~> m or kg m-2]
1490 real :: ea_prev ! A previous estimate of ea_kb [H ~> m or kg m-2]
1491 real :: dS_kbp1 ! The density difference between two interior layers [R ~> kg m-3]
14920 real :: dS_kb(SZI_(G)) ! The limited potential density difference across the interface
1493 ! between the bottommost buffer layer and the topmost interior layer [R ~> kg m-3]
14940 real :: maxF(SZI_(G)) ! The maximum value of F (the density flux divided by density
1495 ! differences) found in the range min_ent < ent < max_ent [H ~> m or kg m-2].
14960 real :: ent_maxF(SZI_(G)) ! The value of entrainment that gives maxF [H ~> m or kg m-2]
14970 real :: zeros(SZI_(G)) ! An array of zero entrainments [H ~> m or kg m-2]
14980 real :: ddSkb_dE(SZI_(G)) ! The partial derivative of dS_kb with ea_kb [R H-1 ~> kg m-4 or m-1]
1499 logical :: bisect_next, Newton ! These indicate what method the next iteration should use
1500 integer :: it
1501 integer, parameter :: MAXIT = 30
1502
15030 dS_kbp1 = Sref(i,kmb+2) - Sref(i,kmb+1)
15040 max_ea = ea_kb(i) ; min_ea = 0.0
15050 val = dS_kbp1 * F_kb(i)
15060 err_min = -val
1507
15080 tolerance = CS%Tolerance_Ent
15090 if (present(tol_in)) tolerance = tol_in
15100 bisect_next = .true.
1511
1512 call determine_dSkb(h_bl, Sref, Ent_bl, ea_kb, i, i, kmb, G, GV, .true., &
15130 dS_kb, ddSkb_dE)
1514
15150 err = dS_kb(i) * ea_kb(i) - val
15160 derr_dea = dS_kb(i) + ddSkb_dE(i) * ea_kb(i)
1517 ! Return if Newton's method on the first guess would give a tolerably small
1518 ! change in the value of ea_kb.
15190 if ((err <= 0.0) .and. (abs(err) <= tolerance*abs(derr_dea))) return
1520
15210 if (err == 0.0) then ; return ! The exact solution on the first guess...
15220 elseif (err > 0.0) then ! The root is properly bracketed.
15230 max_ea = ea_kb(i) ; err_max = err
1524 ! Use Newton's method (if it stays bounded) or the false position method
1525 ! to find the next value.
15260 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i) - min_ea) > err) .and. &
1527 (derr_dea*(max_ea - ea_kb(i)) > -1.0*err)) then
15280 ea_kb(i) = ea_kb(i) - err / derr_dea
1529 else ! Use the bisection for the next guess.
15300 ea_kb(i) = 0.5*(max_ea+min_ea)
1531 endif
1532 else
1533 ! Try to bracket the root first. If unable to bracket the root, return
1534 ! the maximum.
15350 zeros(i) = 0.0
1536 call find_maxF_kb(h_bl, Sref, Ent_bl, I_dSkbp1, zeros, ea_kb, &
15370 kmb, i, i, G, GV, CS, maxF, ent_maxF, F_thresh=F_kb)
15380 err_max = dS_kbp1 * maxF(i) - val
1539 ! If err_max is negative, there is no good solution, so use the maximum
1540 ! value of F in the valid range.
15410 if (err_max <= 0.0) then
15420 ea_kb(i) = ent_maxF(i) ; return
1543 else
15440 max_ea = ent_maxF(i)
15450 ea_kb(i) = 0.5*(max_ea+min_ea) ! Use bisection for the next guess.
1546 endif
1547 endif
1548
1549 ! Exit if the range between max_ea and min_ea already acceptable.
1550 ! if (abs(max_ea - min_ea) < 0.1*tolerance) return
1551
15520 do it = 1, MAXIT
1553 call determine_dSkb(h_bl, Sref, Ent_bl, ea_kb, i, i, kmb, G, GV, .true., &
15540 dS_kb, ddSkb_dE)
1555
15560 err = dS_kb(i) * ea_kb(i) - val
15570 derr_dea = dS_kb(i) + ddSkb_dE(i) * ea_kb(i)
1558
15590 ea_prev = ea_kb(i)
1560 ! Use Newton's method or the false position method to find the next value.
15610 Newton = .false.
15620 if (err > 0.0) then
15630 max_ea = ea_kb(i) ; err_max = err
15640 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i)-min_ea) > err)) Newton = .true.
1565 else
15660 min_ea = ea_kb(i) ; err_min = err
15670 if ((derr_dea > 0.0) .and. (derr_dea*(ea_kb(i)-max_ea) < err)) Newton = .true.
1568 endif
1569
15700 if (Newton) then
15710 ea_kb(i) = ea_kb(i) - err / derr_dea
15720 elseif (bisect_next) then ! Use bisection to reduce the range.
15730 ea_kb(i) = 0.5*(max_ea+min_ea)
15740 bisect_next = .false.
1575 else ! Use the false-position method for the next guess.
15760 ea_kb(i) = min_ea + (max_ea-min_ea) * (err_min/(err_min - err_max))
15770 bisect_next = .true.
1578 endif
1579
15800 tol1 = tolerance ; if (err > 0.0) tol1 = 0.099*tolerance
15810 if (dS_kb(i) <= dS_kbp1) then
15820 if (abs(ea_kb(i) - ea_prev) <= tol1) return
1583 else
15840 if (dS_kbp1*abs(ea_kb(i) - ea_prev) <= dS_kb(i)*tol1) return
1585 endif
1586 enddo
1587
1588end subroutine F_kb_to_ea_kb
1589
1590
1591!> This subroutine determines the entrainment from above by the top interior
1592!! layer (labeled kb elsewhere) given an entrainment by the layer below it,
1593!! constrained to be within the provided bounds.
15940subroutine determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, &
15950 min_eakb, max_eakb, kmb, is, ie, do_i, G, GV, CS, Ent, &
15960 error, err_min_eakb0, err_max_eakb0, F_kb, dFdfm_kb)
1597 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
1598 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
1599 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: h_bl !< Layer thickness, with the top interior
1600 !! layer at k-index kmb+1 [H ~> m or kg m-2].
1601 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: Sref !< The coordinate reference potential
1602 !! density, with the value of the
1603 !! topmost interior layer at layer
1604 !! kmb+1 [R ~> kg m-3].
1605 real, dimension(SZI_(G),SZK_(GV)), intent(in) :: Ent_bl !< The average entrainment upward and
1606 !! downward across each interface around
1607 !! the buffer layers [H ~> m or kg m-2].
1608 real, dimension(SZI_(G)), intent(in) :: I_dSkbp1 !< The inverse of the difference in
1609 !! reference potential density across
1610 !! the base of the uppermost interior
1611 !! layer [R-1 ~> m3 kg-1].
1612 real, dimension(SZI_(G)), intent(in) :: dtKd_kb !< The diapycnal diffusivity in the top
1613 !! interior layer times the time step
1614 !! [H2 ~> m2 or kg2 m-4].
1615 real, dimension(SZI_(G)), intent(in) :: ea_kbp1 !< The entrainment from above by layer
1616 !! kb+1 [H ~> m or kg m-2].
1617 real, dimension(SZI_(G)), intent(in) :: min_eakb !< The minimum permissible rate of
1618 !! entrainment [H ~> m or kg m-2].
1619 real, dimension(SZI_(G)), intent(in) :: max_eakb !< The maximum permissible rate of
1620 !! entrainment [H ~> m or kg m-2].
1621 integer, intent(in) :: kmb !< The number of mixed and buffer layers.
1622 integer, intent(in) :: is !< The start of the i-index range to work on.
1623 integer, intent(in) :: ie !< The end of the i-index range to work on.
1624 logical, dimension(SZI_(G)), intent(in) :: do_i !< A logical variable indicating which
1625 !! i-points to work on.
1626 type(entrain_diffusive_CS), intent(in) :: CS !< This module's control structure.
1627 real, dimension(SZI_(G)), intent(inout) :: Ent !< The entrainment rate of the uppermost
1628 !! interior layer [H ~> m or kg m-2].
1629 !! The input value is the first guess.
1630 real, dimension(SZI_(G)), optional, intent(out) :: error !< The error (locally defined in this
1631 !! routine) associated with the returned
1632 !! solution [H2 ~> m2 or kg2 m-4]
1633 real, dimension(SZI_(G)), optional, intent(in) :: err_min_eakb0 !< The errors (locally defined)
1634 !! associated with min_eakb when ea_kbp1 = 0,
1635 !! returned from a previous call to this
1636 !! subroutine [H2 ~> m2 or kg2 m-4].
1637 real, dimension(SZI_(G)), optional, intent(in) :: err_max_eakb0 !< The errors (locally defined)
1638 !! associated with min_eakb when ea_kbp1 = 0,
1639 !! returned from a previous call to this
1640 !! subroutine [H2 ~> m2 or kg2 m-4].
1641 real, dimension(SZI_(G)), optional, intent(out) :: F_kb !< The entrainment from below by the
1642 !! uppermost interior layer
1643 !! corresponding to the returned
1644 !! value of Ent [H ~> m or kg m-2].
1645 real, dimension(SZI_(G)), optional, intent(out) :: dFdfm_kb !< The partial derivative of F_kb with
1646 !! ea_kbp1 [nondim].
1647
1648! This subroutine determines the entrainment from above by the top interior
1649! layer (labeled kb elsewhere) given an entrainment by the layer below it,
1650! constrained to be within the provided bounds.
1651
1652 ! Local variables
1653 real, dimension(SZI_(G)) :: &
16540 dS_kb, & ! The coordinate-density difference between the
1655 ! layer kb and deepest buffer layer, limited to
1656 ! ensure that it is positive [R ~> kg m-3].
16570 dS_Lay, & ! The coordinate-density difference across layer
1658 ! kb, limited to ensure that it is positive and not
1659 ! too much bigger than dS_kb or dS_kbp1 [R ~> kg m-3].
16600 ddSkb_dE, ddSlay_dE, & ! The derivatives of dS_kb and dS_Lay with E
1661 ! [R H-1 ~> kg m-4 or m-1].
16620 derror_dE, & ! The derivative of err with E [H ~> m or kg m-2].
16630 err, & ! The "error" whose zero is being sought [H2 ~> m2 or kg2 m-4].
16640 E_min, E_max, & ! The minimum and maximum values of E [H ~> m or kg m-2].
16650 error_minE, error_maxE ! err when E = E_min or E = E_max [H2 ~> m2 or kg2 m-4].
1666 real :: err_est ! An estimate of what err will be [H2 ~> m2 or kg2 m-4].
1667 real :: eL ! 1 or 0, depending on whether increases in E lead
1668 ! to decreases in the entrainment from below by the
1669 ! deepest buffer layer [nondim].
1670 real :: fa ! Temporary variable used to calculate err [nondim].
1671 real :: fk ! Temporary variable used to calculate err [H2 ~> m2 or kg2 m-4].
1672 real :: fm, fr ! Temporary variables used to calculate err [H ~> m or kg m-2].
1673 real :: tolerance ! The tolerance within which E must be converged [H ~> m or kg m-2].
1674 real :: E_prev ! The previous value of E [H ~> m or kg m-2].
16750 logical, dimension(SZI_(G)) :: false_position ! If true, the false position
1676 ! method might be used for the next iteration.
16770 logical, dimension(SZI_(G)) :: redo_i ! If true, more work is needed on this column.
1678 logical :: do_any
1679 real :: large_err ! A large error measure [H2 ~> m2 or kg2 m-4].
1680 integer :: i, it
1681 integer, parameter :: MAXIT = 30
1682
16830 if (.not.CS%bulkmixedlayer) then
1684 call MOM_error(FATAL, "determine_Ea_kb should not be called "//&
16850 "unless BULKMIXEDLAYER is defined.")
1686 endif
16870 tolerance = CS%Tolerance_Ent
16880 large_err = GV%m_to_H**2 * 1.0e30
1689
16900 do i=is,ie ; redo_i(i) = do_i(i) ; enddo
1691
16920 do i=is,ie ; if (do_i(i)) then
1693 ! The first guess of Ent was the value from the previous iteration.
1694
1695 ! These were previously calculated and provide good limits and estimates
1696 ! of the errors there. By construction the errors increase with R*ea_kbp1.
16970 E_min(i) = min_eakb(i) ; E_max(i) = max_eakb(i)
16980 error_minE(i) = -large_err ; error_maxE(i) = large_err
16990 false_position(i) = .true. ! Used to alternate between false_position and
1700 ! bisection when Newton's method isn't working.
17010 if (present(err_min_eakb0)) error_minE(i) = err_min_eakb0(i) - E_min(i) * ea_kbp1(i)
17020 if (present(err_max_eakb0)) error_maxE(i) = err_max_eakb0(i) - E_max(i) * ea_kbp1(i)
1703
17040 if ((error_maxE(i) <= 0.0) .or. (error_minE(i) >= 0.0)) then
1705 ! The root is not bracketed and one of the limiting values should be used.
17060 if (error_maxE(i) <= 0.0) then
1707 ! The errors decrease with E*ea_kbp1, so E_max is the best solution.
17080 Ent(i) = E_max(i) ; err(i) = error_maxE(i)
1709 else ! error_minE >= 0 is equivalent to ea_kbp1 = 0.0.
17100 Ent(i) = E_min(i) ; err(i) = error_minE(i)
1711 endif
17120 derror_dE(i) = 0.0
17130 redo_i(i) = .false.
1714 endif
1715 endif ; enddo ! End of i-loop
1716
17170 do it = 1,MAXIT
17180 do_any = .false. ; do i=is,ie ; if (redo_i(i)) do_any = .true. ; enddo
17190 if (.not.do_any) exit
1720 call determine_dSkb(h_bl, Sref, Ent_bl, Ent, is, ie, kmb, G, GV, .true., dS_kb, &
17210 ddSkb_dE, dS_lay, ddSlay_dE, do_i_in=redo_i)
17220 do i=is,ie ; if (redo_i(i)) then
1723 ! The correct root is bracketed between E_min and E_max.
1724 ! Note the following limits: Ent >= 0 ; fa > 1 ; fk > 0
17250 eL = 0.0 ; if (2.0*Ent_bl(i,Kmb+1) >= Ent(i)) eL = 1.0
17260 fa = (1.0 + eL) + dS_kb(i)*I_dSkbp1(i)
17270 fk = dtKd_kb(i) * (dS_Lay(i)/dS_kb(i))
17280 fm = (ea_kbp1(i) - h_bl(i,kmb+1)) + eL*2.0*Ent_bl(i,Kmb+1)
17290 if (fm > -GV%Angstrom_H) fm = fm + GV%Angstrom_H ! This could be smooth if need be.
17300 err(i) = (fa * Ent(i)**2 - fm * Ent(i)) - fk
1731 derror_dE(i) = ((2.0*fa + (ddSkb_dE(i)*I_dSkbp1(i))*Ent(i))*Ent(i) - fm) - &
17320 dtKd_kb(i) * (ddSlay_dE(i)*dS_kb(i) - ddSkb_dE(i)*dS_Lay(i))/(dS_kb(i)**2)
1733
17340 if (err(i) == 0.0) then
17350 redo_i(i) = .false. ; cycle
17360 elseif (err(i) > 0.0) then
17370 E_max(i) = Ent(i) ; error_maxE(i) = err(i)
1738 else
17390 E_min(i) = Ent(i) ; error_minE(i) = err(i)
1740 endif
1741
17420 E_prev = Ent(i)
17430 if ((it == 1) .or. (derror_dE(i) <= 0.0)) then
1744 ! Assuming that the coefficients of the quadratic equation are correct
1745 ! will usually give a very good first guess. Also, if derror_dE < 0.0,
1746 ! R is on the wrong side of the approximate parabola. In either case,
1747 ! try assuming that the error is approximately a parabola and solve.
17480 fr = sqrt(fm**2 + 4.0*fa*fk)
17490 if (fm >= 0.0) then
17500 Ent(i) = (fm + fr) / (2.0 * fa)
1751 else
17520 Ent(i) = (2.0 * fk) / (fr - fm)
1753 endif
1754 ! But make sure that the root stays bracketed, bisecting if needed.
17550 if ((Ent(i) > E_max(i)) .or. (Ent(i) < E_min(i))) &
17560 Ent(i) = 0.5*(E_max(i) + E_min(i))
17570 elseif (((E_max(i)-Ent(i))*derror_dE(i) > -err(i)) .and. &
1758 ((Ent(i)-E_min(i))*derror_dE(i) > err(i)) ) then
1759 ! Use Newton's method for the next estimate, provided it will
1760 ! remain bracketed between Rmin and Rmax.
17610 Ent(i) = Ent(i) - err(i) / derror_dE(i)
17620 elseif (false_position(i) .and. &
1763 (error_maxE(i) - error_minE(i) < 0.9*large_err)) then
1764 ! Use the false position method if there are decent error estimates.
1765 Ent(i) = E_min(i) + (E_max(i)-E_min(i)) * &
17660 (-error_minE(i)/(error_maxE(i) - error_minE(i)))
17670 false_position(i) = .false.
1768 else ! Bisect as a last resort or if the false position method was used last.
17690 Ent(i) = 0.5*(E_max(i) + E_min(i))
17700 false_position(i) = .true.
1771 endif
1772
17730 if (abs(E_prev - Ent(i)) < tolerance) then
17740 err_est = err(i) + (Ent(i) - E_prev) * derror_dE(i)
17750 if ((it > 1) .or. (err_est*err(i) <= 0.0) .or. &
17760 (abs(err_est) < abs(tolerance*derror_dE(i)))) redo_i(i) = .false.
1777 endif
1778
1779 endif ; enddo ! End of i-loop
1780 enddo ! End of iterations to determine Ent(i).
1781
1782 ! Update the value of dS_kb for consistency with Ent.
17830 if (present(F_kb) .or. present(dFdfm_kb)) &
1784 call determine_dSkb(h_bl, Sref, Ent_bl, Ent, is, ie, kmb, G, GV, .true., &
17850 dS_kb, do_i_in=do_i)
1786
17870 if (present(F_kb)) then ; do i=is,ie ; if (do_i(i)) then
17880 F_kb(i) = Ent(i) * (dS_kb(i) * I_dSkbp1(i))
1789 endif ; enddo ; endif
17900 if (present(error)) then ; do i=is,ie ; if (do_i(i)) then
17910 error(i) = err(i)
1792 endif ; enddo ; endif
17930 if (present(dFdfm_kb)) then ; do i=is,ie ; if (do_i(i)) then
1794 ! derror_dE and ddSkb_dE are _not_ recalculated here, since dFdfm_kb is
1795 ! only used in Newton's method, and slightly increasing the accuracy of the
1796 ! estimate is unlikely to speed convergence.
17970 if (derror_dE(i) > 0.0) then
1798 dFdfm_kb(i) = ((dS_kb(i) + Ent(i) * ddSkb_dE(i)) * I_dSkbp1(i)) * &
17990 (Ent(i) / derror_dE(i))
1800 else ! Use Adcroft's division by 0 convention.
18010 dFdfm_kb(i) = 0.0
1802 endif
1803 endif ; enddo ; endif
1804
18050end subroutine determine_Ea_kb
1806
1807!> Maximize F = ent*ds_kb*I_dSkbp1 in the range min_ent < ent < max_ent.
18080subroutine find_maxF_kb(h_bl, Sref, Ent_bl, I_dSkbp1, min_ent_in, max_ent_in, &
18090 kmb, is, ie, G, GV, CS, maxF, ent_maxF, do_i_in, &
18100 F_lim_maxent, F_thresh)
1811 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
1812 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
1813 real, dimension(SZI_(G),SZK_(GV)), &
1814 intent(in) :: h_bl !< Layer thickness [H ~> m or kg m-2]
1815 real, dimension(SZI_(G),SZK_(GV)), &
1816 intent(in) :: Sref !< Reference potential density [R ~> kg m-3].
1817 real, dimension(SZI_(G),SZK_(GV)), &
1818 intent(in) :: Ent_bl !< The average entrainment upward and
1819 !! downward across each interface around
1820 !! the buffer layers [H ~> m or kg m-2].
1821 real, dimension(SZI_(G)), intent(in) :: I_dSkbp1 !< The inverse of the difference in
1822 !! reference potential density across the
1823 !! base of the uppermost interior layer
1824 !! [R-1 ~> m3 kg-1].
1825 real, dimension(SZI_(G)), intent(in) :: min_ent_in !< The minimum value of ent to search,
1826 !! [H ~> m or kg m-2].
1827 real, dimension(SZI_(G)), intent(in) :: max_ent_in !< The maximum value of ent to search,
1828 !! [H ~> m or kg m-2].
1829 integer, intent(in) :: kmb !< The number of mixed and buffer layers.
1830 integer, intent(in) :: is !< The start of the i-index range to work on.
1831 integer, intent(in) :: ie !< The end of the i-index range to work on.
1832 type(entrain_diffusive_CS), intent(in) :: CS !< This module's control structure.
1833 real, dimension(SZI_(G)), intent(out) :: maxF !< The maximum value of F
1834 !! = ent*ds_kb*I_dSkbp1 found in the range
1835 !! min_ent < ent < max_ent [H ~> m or kg m-2].
1836 real, dimension(SZI_(G)), &
1837 optional, intent(out) :: ent_maxF !< The value of ent at that maximum [H ~> m or kg m-2].
1838 logical, dimension(SZI_(G)), &
1839 optional, intent(in) :: do_i_in !< A logical array indicating which columns
1840 !! to work on.
1841 real, dimension(SZI_(G)), &
1842 optional, intent(out) :: F_lim_maxent !< If present, do not apply the limit in
1843 !! finding the maximum value, but return the
1844 !! limited value at ent=max_ent_in in this
1845 !! array [H ~> m or kg m-2].
1846 real, dimension(SZI_(G)), &
1847 optional, intent(in) :: F_thresh !< If F_thresh is present, return the first value
1848 !! found that has F > F_thresh [H ~> m or kg m-2], or
1849 !! the maximum root if it is absent.
1850
1851! Maximize F = ent*ds_kb*I_dSkbp1 in the range min_ent < ent < max_ent.
1852! ds_kb may itself be limited to positive values in determine_dSkb, which gives
1853! the prospect of two local maxima in the range - one at max_ent_in with that
1854! minimum value of ds_kb, and the other due to the unlimited (potentially
1855! negative) value. It is faster to find the true maximum by first finding the
1856! unlimited maximum and comparing it to the limited value at max_ent_in.
1857 real, dimension(SZI_(G)) :: &
18580 ent, & ! The updated estimate of the entrainment [H ~> m or kg m-2]
18590 minent, maxent, ent_best, & ! Various previous estimates of the entrainment [H ~> m or kg m-2]
18600 F_max_ent_in, & ! The value of F that gives the input maximum value of ent [H ~> m or kg m-2]
18610 F_maxent, F_minent, F, F_best, & ! Various estimates of F [H ~> m or kg m-2]
18620 dF_dent, dF_dE_max, dF_dE_min, dF_dE_best, & ! Various derivatives of F with ent [nondim]
18630 dS_kb, & ! The density difference across the interface between the bottommost
1864 ! buffer layer and the topmost interior layer [R ~> kg m-3]
18650 dS_kb_lim, dS_anom_lim, & ! Various limits on dS_kb [R ~> kg m-3]
18660 ddSkb_dE, & ! The partial derivative of dS_kb with ent [R H-1 ~> kg m-4 or m-1].
18670 chg_prev, chg_pre_prev ! Changes in estimates of the entrainment from previous iterations [H ~> m or kg m-2]
1868 real :: dF_dE_mean, maxslope, minslope ! Various derivatives of F with ent [nondim]
1869 real :: tolerance ! The tolerance within which ent must be converged [H ~> m or kg m-2]
1870 real :: ratio_select_end, rat ! Fractional changes in the value of ent to use for the next iteration
1871 ! relative to its bounded range [nondim]
1872 real :: max_chg, min_chg, chg1, chg2, chg ! Changes in entrainment estimates [H ~> m or kg m-2]
18730 logical, dimension(SZI_(G)) :: do_i, last_it, need_bracket, may_use_best
1874 logical :: doany, OK1, OK2, bisect, new_min_bound
1875 integer :: i, it, is1, ie1
1876 integer, parameter :: MAXIT = 20
1877
18780 tolerance = CS%Tolerance_Ent
1879
18800 if (present(do_i_in)) then
18810 do i=is,ie ; do_i(i) = do_i_in(i) ; enddo
1882 else
18830 do i=is,ie ; do_i(i) = .true. ; enddo
1884 endif
1885
1886 ! The most likely value is at max_ent.
1887 call determine_dSkb(h_bl, Sref, Ent_bl, max_ent_in, is, ie, kmb, G, GV, .false., &
18880 dS_kb, ddSkb_dE, dS_anom_lim=dS_anom_lim)
18890 ie1 = is-1 ; doany = .false.
18900 do i=is,ie
18910 dS_kb_lim(i) = dS_kb(i) + dS_anom_lim(i)
18920 F_max_ent_in(i) = max_ent_in(i)*dS_kb_lim(i)*I_dSkbp1(i)
18930 maxent(i) = max_ent_in(i) ; minent(i) = min_ent_in(i)
18940 if ((abs(maxent(i) - minent(i)) < tolerance) .or. (.not.do_i(i))) then
18950 F_best(i) = max_ent_in(i)*dS_kb(i)*I_dSkbp1(i)
18960 ent_best(i) = max_ent_in(i) ; ent(i) = max_ent_in(i)
18970 do_i(i) = .false.
1898 else
18990 F_maxent(i) = maxent(i) * dS_kb(i) * I_dSkbp1(i)
19000 dF_dE_max(i) = (dS_kb(i) + maxent(i)*ddSkb_dE(i)) * I_dSkbp1(i)
19010 doany = .true. ; last_it(i) = .false. ; need_bracket(i) = .true.
1902 endif
1903 enddo
1904
19050 if (doany) then
19060 ie1 = is-1 ; do i=is,ie ; if (do_i(i)) ie1 = i ; enddo
19070 do i=ie1,is,-1 ; if (do_i(i)) is1 = i ; enddo
1908 ! Find the value of F and its derivative at min_ent.
1909 call determine_dSkb(h_bl, Sref, Ent_bl, minent, is1, ie1, kmb, G, GV, .false., &
19100 dS_kb, ddSkb_dE, do_i_in=do_i)
19110 do i=is1,ie1 ; if (do_i(i)) then
19120 F_minent(i) = minent(i) * dS_kb(i) * I_dSkbp1(i)
19130 dF_dE_min(i) = (dS_kb(i) + minent(i)*ddSkb_dE(i)) * I_dSkbp1(i)
1914 endif ; enddo
1915
19160 ratio_select_end = 0.9
19170 do it=1,MAXIT
19180 ratio_select_end = 0.5*ratio_select_end
19190 do i=is1,ie1 ; if (do_i(i)) then
19200 if (need_bracket(i)) then
19210 dF_dE_mean = (F_maxent(i) - F_minent(i)) / (maxent(i) - minent(i))
19220 maxslope = MAX(dF_dE_mean, dF_dE_min(i), dF_dE_max(i))
19230 minslope = MIN(dF_dE_mean, dF_dE_min(i), dF_dE_max(i))
19240 if (F_minent(i) >= F_maxent(i)) then
19250 if (dF_dE_min(i) > 0.0) then ; rat = 0.02 ! A small step should bracket the solution.
19260 elseif (maxslope < ratio_select_end*minslope) then
1927 ! The maximum of F is at minent.
19280 F_best(i) = F_minent(i) ; ent_best(i) = minent(i) ; rat = 0.0
19290 do_i(i) = .false.
19300 else ; rat = 0.382 ; endif ! Use the golden ratio
1931 else
19320 if (dF_dE_max(i) < 0.0) then ; rat = 0.98 ! A small step should bracket the solution.
19330 elseif (minslope > ratio_select_end*maxslope) then
1934 ! The maximum of F is at maxent.
19350 F_best(i) = F_maxent(i) ; ent_best(i) = maxent(i) ; rat = 1.0
19360 do_i(i) = .false.
19370 else ; rat = 0.618 ; endif ! Use the golden ratio
1938 endif
1939
19400 if (rat >= 0.0) ent(i) = rat*maxent(i) + (1.0-rat)*minent(i)
19410 if (((maxent(i) - minent(i)) < tolerance) .or. (it==MAXIT)) &
19420 last_it(i) = .true.
1943 else ! The maximum is bracketed by minent, ent_best, and maxent.
19440 chg1 = 2.0*(maxent(i) - minent(i)) ; chg2 = chg1
19450 if (dF_dE_best(i) > 0) then
19460 max_chg = maxent(i) - ent_best(i) ; min_chg = 0.0
1947 else
19480 max_chg = 0.0 ; min_chg = minent(i) - ent_best(i) ! < 0
1949 endif
19500 if (max_chg - min_chg < 2.0*tolerance) last_it(i) = .true.
19510 if (dF_dE_max(i) /= dF_dE_best(i)) &
1952 chg1 = (maxent(i) - ent_best(i))*dF_dE_best(i) / &
19530 (dF_dE_best(i) - dF_dE_max(i))
19540 if (dF_dE_min(i) /= dF_dE_best(i)) &
1955 chg2 = (minent(i) - ent_best(i))*dF_dE_best(i) / &
19560 (dF_dE_best(i) - dF_dE_min(i))
19570 OK1 = ((chg1 < max_chg) .and. (chg1 > min_chg))
19580 OK2 = ((chg2 < max_chg) .and. (chg2 > min_chg))
19590 if (.not.(OK1 .or. OK2)) then ; bisect = .true. ; else
19600 if (OK1 .and. OK2) then ! Take the acceptable smaller change.
19610 chg = chg1 ; if (abs(chg2) < abs(chg1)) chg = chg2
19620 elseif (OK1) then ; chg = chg1
19630 else ; chg = chg2 ; endif
19640 if (abs(chg) > 0.5*abs(chg_pre_prev(i))) then ; bisect = .true.
19650 else ; bisect = .false. ; endif
1966 endif
19670 chg_pre_prev(i) = chg_prev(i)
19680 if (bisect) then
19690 if (dF_dE_best(i) > 0.0) then
19700 ent(i) = 0.5*(maxent(i) + ent_best(i))
19710 chg_prev(i) = 0.5*(maxent(i) - ent_best(i))
1972 else
19730 ent(i) = 0.5*(minent(i) + ent_best(i))
19740 chg_prev(i) = 0.5*(minent(i) - ent_best(i))
1975 endif
1976 else
19770 if (abs(chg) < tolerance) chg = SIGN(tolerance,chg)
19780 ent(i) = ent_best(i) + chg
19790 chg_prev(i) = chg
1980 endif
1981 endif
1982 endif ; enddo
1983
19840 if (mod(it,3) == 0) then ! Re-determine the loop bounds.
19850 ie1 = is-1 ; do i=is1,ie ; if (do_i(i)) ie1 = i ; enddo
19860 do i=ie1,is,-1 ; if (do_i(i)) is1 = i ; enddo
1987 endif
1988
1989 call determine_dSkb(h_bl, Sref, Ent_bl, ent, is1, ie1, kmb, G, GV, .false., &
19900 dS_kb, ddSkb_dE, do_i_in=do_i)
19910 do i=is1,ie1 ; if (do_i(i)) then
19920 F(i) = ent(i)*dS_kb(i)*I_dSkbp1(i)
19930 dF_dent(i) = (dS_kb(i) + ent(i)*ddSkb_dE(i)) * I_dSkbp1(i)
1994 endif ; enddo
1995
19960 if (present(F_thresh)) then ; do i=is1,ie1 ; if (do_i(i)) then
19970 if (F(i) >= F_thresh(i)) then
19980 F_best(i) = F(i) ; ent_best(i) = ent(i) ; do_i(i) = .false.
1999 endif
2000 endif ; enddo ; endif
2001
20020 doany = .false.
20030 do i=is1,ie1 ; if (do_i(i)) then
20040 if (.not.last_it(i)) doany = .true.
20050 if (last_it(i)) then
20060 if (need_bracket(i)) then
20070 if ((F(i) > F_maxent(i)) .and. (F(i) > F_minent(i))) then
20080 F_best(i) = F(i) ; ent_best(i) = ent(i)
20090 elseif (F_maxent(i) > F_minent(i)) then
20100 F_best(i) = F_maxent(i) ; ent_best(i) = maxent(i)
2011 else
20120 F_best(i) = F_minent(i) ; ent_best(i) = minent(i)
2013 endif
20140 elseif (F(i) > F_best(i)) then
20150 F_best(i) = F(i) ; ent_best(i) = ent(i)
2016 endif
20170 do_i(i) = .false.
20180 elseif (need_bracket(i)) then
20190 if ((F(i) > F_maxent(i)) .and. (F(i) > F_minent(i))) then
20200 need_bracket(i) = .false. ! The maximum is now bracketed.
20210 chg_prev(i) = (maxent(i) - minent(i))
20220 chg_pre_prev(i) = 2.0*chg_prev(i)
20230 ent_best(i) = ent(i) ; F_best(i) = F(i) ; dF_dE_best(i) = dF_dent(i)
20240 elseif ((F(i) <= F_maxent(i)) .and. (F(i) > F_minent(i))) then
20250 new_min_bound = .true. ! We have a new minimum bound.
20260 elseif ((F(i) <= F_maxent(i)) .and. (F(i) > F_minent(i))) then
20270 new_min_bound = .false. ! We have a new maximum bound.
2028 else ! This case would bracket a minimum. Weird.
2029 ! Unless the derivative indicates that there is a maximum near the
2030 ! lower bound, try keeping the end with the larger value of F
2031 ! in a tie keep the minimum as the answer here will be compared
2032 ! with the maximum input value later.
20330 new_min_bound = .true.
20340 if (dF_dE_min(i) > 0.0 .or. (F_minent(i) >= F_maxent(i))) &
20350 new_min_bound = .false.
2036 endif
20370 if (need_bracket(i)) then ! Still not bracketed.
20380 if (new_min_bound) then
20390 minent(i) = ent(i) ; F_minent(i) = F(i) ; dF_dE_min(i) = dF_dent(i)
2040 else
20410 maxent(i) = ent(i) ; F_maxent(i) = F(i) ; dF_dE_max(i) = dF_dent(i)
2042 endif
2043 endif
2044 else ! The root was previously bracketed.
20450 if (F(i) >= F_best(i)) then ! There is a new maximum.
20460 if (ent(i) > ent_best(i)) then ! Replace minent with ent_prev.
20470 minent(i) = ent_best(i) ; F_minent(i) = F_best(i) ; dF_dE_min(i) = dF_dE_best(i)
2048 else ! Replace maxent with ent_best.
20490 maxent(i) = ent_best(i) ; F_maxent(i) = F_best(i) ; dF_dE_max(i) = dF_dE_best(i)
2050 endif
20510 ent_best(i) = ent(i) ; F_best(i) = F(i) ; dF_dE_best(i) = dF_dent(i)
2052 else
20530 if (ent(i) < ent_best(i)) then ! Replace the minent with ent.
20540 minent(i) = ent(i) ; F_minent(i) = F(i) ; dF_dE_min(i) = dF_dent(i)
2055 else ! Replace maxent with ent_prev.
20560 maxent(i) = ent(i) ; F_maxent(i) = F(i) ; dF_dE_max(i) = dF_dent(i)
2057 endif
2058 endif
20590 if ((maxent(i) - minent(i)) <= tolerance) do_i(i) = .false. ! Done.
2060 endif ! need_bracket.
2061 endif ; enddo
20620 if (.not.doany) exit
2063 enddo
2064 endif
2065
20660 if (present(F_lim_maxent)) then
2067 ! Return the unlimited maximum in maxF, and the limited value of F at maxent.
20680 do i=is,ie
20690 maxF(i) = F_best(i)
20700 F_lim_maxent(i) = F_max_ent_in(i)
20710 if (present(ent_maxF)) ent_maxF(i) = ent_best(i)
2072 enddo
2073 else
2074 ! Now compare the two? potential maxima using the limited value of dF_kb.
20750 doany = .false.
20760 do i=is,ie
20770 may_use_best(i) = (ent_best(i) /= max_ent_in(i))
20780 if (may_use_best(i)) doany = .true.
2079 enddo
20800 if (doany) then
2081 ! For efficiency, could save previous value of dS_anom_lim_best?
20820 call determine_dSkb(h_bl, Sref, Ent_bl, ent_best, is, ie, kmb, G, GV, .true., dS_kb_lim)
20830 do i=is,ie
20840 F_best(i) = ent_best(i)*dS_kb_lim(i)*I_dSkbp1(i)
2085 ! The second test seems necessary because of roundoff differences that
2086 ! can arise during compilation.
20870 if ((F_best(i) > F_max_ent_in(i)) .and. (may_use_best(i))) then
20880 maxF(i) = F_best(i)
20890 if (present(ent_maxF)) ent_maxF(i) = ent_best(i)
2090 else
20910 maxF(i) = F_max_ent_in(i)
20920 if (present(ent_maxF)) ent_maxF(i) = max_ent_in(i)
2093 endif
2094 enddo
2095 else
2096 ! All of the maxima are at the maximum entrainment.
20970 do i=is,ie ; maxF(i) = F_max_ent_in(i) ; enddo
20980 if (present(ent_maxF)) then
20990 do i=is,ie ; ent_maxF(i) = max_ent_in(i) ; enddo
2100 endif
2101 endif
2102 endif
2103
21040end subroutine find_maxF_kb
2105
2106!> This subroutine initializes the parameters and memory associated with the
2107!! entrain_diffusive module.
21081subroutine entrain_diffusive_init(Time, G, GV, US, param_file, diag, CS, just_read_params)
2109 type(time_type), intent(in) :: Time !< The current model time.
2110 type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
2111 type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
2112 type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
2113 type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
2114 !! parameters.
2115 type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to regulate diagnostic
2116 !! output.
2117 type(entrain_diffusive_CS), intent(inout) :: CS !< Entrainment diffusion control structure
2118 logical, intent(in) :: just_read_params !< If true, this call will only read
2119 !! and log parameters without registering
2120 !! any diagnostics
2121
2122 ! Local variables
2123 real :: dt ! The dynamics timestep, used here in the default for TOLERANCE_ENT [T ~> s]
2124 real :: Kd ! A diffusivity used in the default for TOLERANCE_ENT [Z2 T-1 ~> m2 s-1]
2125 ! This include declares and sets the variable "version".
2126# include "version_variable.h"
2127 character(len=40) :: mdl = "MOM_entrain_diffusive" ! This module's name.
2128
21291 CS%initialized = .true.
21301 CS%diag => diag
2131
21321 CS%bulkmixedlayer = (GV%nkml > 0)
2133
2134 ! Set default, read and log parameters
21351 if (.not.just_read_params) call log_version(param_file, mdl, version, "")
2136 call get_param(param_file, mdl, "MAX_ENT_IT", CS%max_ent_it, &
2137 "The maximum number of iterations that may be used to "//&
21381 "calculate the interior diapycnal entrainment.", default=5, do_not_log=just_read_params)
2139 ! In this module, KD is only used to set the default for TOLERANCE_ENT. [Z2 T-1 ~> m2 s-1]
21401 call get_param(param_file, mdl, "KD", Kd, units="m2 s-1", default=0.0, scale=US%m2_s_to_Z2_T)
2141 call get_param(param_file, mdl, "DT", dt, &
2142 "The (baroclinic) dynamics time step.", &
21431 units="s", scale=US%s_to_T, fail_if_missing=.true., do_not_log=just_read_params)
2144 call get_param(param_file, mdl, "TOLERANCE_ENT", CS%Tolerance_Ent, &
2145 "The tolerance with which to solve for entrainment values.", &
2146 units="m", default=US%Z_to_m*MAX(100.0*GV%Angstrom_Z,1.0e-4*sqrt(dt*Kd)), scale=GV%m_to_H, &
21471 do_not_log=just_read_params)
2148 call get_param(param_file, mdl, "ENTRAIN_DIFFUSIVE_MAX_ENT", CS%max_Ent, &
2149 "A large ceiling on the maximum permitted amount of entrainment across each "//&
2150 "interface between the mixed and buffer layers within a timestep.", &
21511 units="m", default=1.0e4, scale=GV%m_to_H, do_not_log=.not.CS%bulkmixedlayer)
2152
21531 CS%Rho_sig_off = 1000.0*US%kg_m3_to_R
2154
21551 if (.not.just_read_params) then
2156 CS%id_Kd = register_diag_field('ocean_model', 'Kd_effective', diag%axesTL, Time, &
21570 'Diapycnal diffusivity as applied', 'm2 s-1', conversion=GV%HZ_T_to_m2_s)
2158 CS%id_diff_work = register_diag_field('ocean_model', 'diff_work', diag%axesTi, Time, &
2159 'Work actually done by diapycnal diffusion across each interface', &
21600 'W m-2', conversion=US%RZ3_T3_to_W_m2)
2161 endif
21621end subroutine entrain_diffusive_init
2163
2164!> \namespace mom_entrain_diffusive
2165!!
2166!! By Robert Hallberg, September 1997 - July 2000
2167!!
2168!! This file contains the subroutines that implement diapycnal
2169!! mixing and advection in isopycnal layers. The main subroutine,
2170!! calculate_entrainment, returns the entrainment by each layer
2171!! across the interfaces above and below it. These are calculated
2172!! subject to the constraints that no layers can be driven to negative
2173!! thickness and that the each layer maintains its target density,
2174!! using the scheme described in Hallberg (MWR 2000). There may or
2175!! may not be a bulk mixed layer above the isopycnal layers.
2176!! The solution is iterated until the change in the entrainment
2177!! between successive iterations is less than some small tolerance.
2178!!
2179!! The dual-stream entrainment scheme of MacDougall and Dewar
2180!! (JPO 1997) is used for combined diapycnal advection and diffusion,
2181!! modified as described in Hallberg (MWR 2000) to be solved
2182!! implicitly in time. Any profile of diffusivities may be used.
2183!! Diapycnal advection is fundamentally the residual of diapycnal
2184!! diffusion, so the fully implicit upwind differencing scheme that
2185!! is used is entirely appropriate. The downward buoyancy flux in
2186!! each layer is determined from an implicit calculation based on
2187!! the previously calculated flux of the layer above and an estimated
2188!! flux in the layer below. This flux is subject to the following
2189!! conditions: (1) the flux in the top and bottom layers are
2190!! set by the boundary conditions, and (2) no layer may be driven
2191!! below an Angstrom thickness. If there is a bulk mixed layer, the
2192!! mixed and buffer layers are treated as Eulerian layers, whose
2193!! thicknesses only change due to entrainment by the interior layers.
2194
21950end module MOM_entrain_diffusive