Build a SLight coordinate column.
183 type(slight_CS),
intent(in) :: CS
184 type(EOS_type),
pointer :: eqn_of_state
185 real,
intent(in) :: H_to_pres
187 real,
intent(in) :: H_subroundoff
188 integer,
intent(in) :: nz
189 real,
intent(in) :: depth
190 real,
dimension(nz),
intent(in) :: T_col
191 real,
dimension(nz),
intent(in) :: S_col
192 real,
dimension(nz),
intent(in) :: h_col
193 real,
dimension(nz),
intent(in) :: p_col
194 real,
dimension(nz+1),
intent(in) :: z_col
195 real,
dimension(nz+1),
intent(inout) :: z_col_new
196 real,
optional,
intent(in) :: h_neglect
198 real,
optional,
intent(in) :: h_neglect_edge
201 real,
dimension(nz) :: rho_col
202 real,
dimension(nz) :: T_f, S_f
203 logical,
dimension(nz+1) :: reliable
204 real,
dimension(nz+1) :: T_int, S_int
205 real,
dimension(nz+1) :: rho_tmp
206 real,
dimension(nz+1) :: drho_dp
207 real,
dimension(nz+1) :: p_IS, p_R
208 real,
dimension(nz+1) :: drhoIS_dT
210 real,
dimension(nz+1) :: drhoIS_dS
212 real,
dimension(nz+1) :: drhoR_dT
214 real,
dimension(nz+1) :: drhoR_dS
216 real,
dimension(nz+1) :: strat_rat
220 real :: Fn_now, I_HStol, Fn_zero_val
236 logical :: maximum_depths_set
237 logical :: maximum_h_set
238 real :: k2_used, k2here, dz_sum, z_max
240 real :: h_tr, b_denom_1, b1, d1
241 real,
dimension(nz) :: c1
242 integer :: kur1, kur2
244 integer :: i, j, k, nkml
246 maximum_depths_set =
allocated(cs%max_interface_depths)
247 maximum_h_set =
allocated(cs%max_layer_thickness)
249 if (z_col(nz+1) - z_col(1) < nz*cs%min_thickness)
then
251 dz = (z_col(nz+1) - z_col(1)) / real(nz)
252 do k=2,nz ; z_col_new(k) = z_col(1) + dz*real(k-1) ;
enddo
254 call calculate_density(t_col, s_col, p_col, rho_col, eqn_of_state)
258 call rho_interfaces_col(rho_col, h_col, z_col, cs%target_density, nz, &
259 z_col_new, cs, reliable, debug=.true., &
260 h_neglect=h_neglect, h_neglect_edge=h_neglect_edge)
263 if (cs%min_thickness > 0.0)
then
265 do k=2,nz ;
if (z_col_new(k) < z_col_new(k-1) + cs%min_thickness)
then
266 z_col_new(k) = z_col_new(k-1) + cs%min_thickness
269 do k=nz,2,-1 ;
if (z_col_new(k) > z_col_new(k+1) - cs%min_thickness)
then
270 z_col_new(k) = z_col_new(k+1) - cs%min_thickness
281 do k=kur_ss,nz ;
if (.not.reliable(k))
then
287 do k=kur1+1,nz+1 ;
if (reliable(k))
then
288 kur2 = k-1 ; kur_ss = k ;
exit
290 if (kur2 < kur1)
call mom_error(fatal,
"Bad unreliable range.")
292 dz_ur = z_col_new(kur2+1) - z_col_new(kur1-1)
296 wgt = 1.0 ; cowgt = 0.0
298 z_col_new(k) = cowgt*z_col_new(k) + &
299 wgt * (z_col_new(kur1-1) + dz_ur*(k - (kur1-1)) / ((kur2 - kur1) + 2))
305 z_wt = 0.0 ; rho_x_z = 0.0
306 h_ml_av = cs%Rho_ml_avg_depth
308 if (z_wt + h_col(k) >= h_ml_av)
then
309 rho_x_z = rho_x_z + rho_col(k) * (h_ml_av - z_wt)
313 rho_x_z = rho_x_z + rho_col(k) * h_col(k)
314 z_wt = z_wt + h_col(k)
317 if (z_wt > 0.0) rho_ml_av = rho_x_z / z_wt
319 nkml = cs%nz_fixed_surface
321 if (rho_ml_av <= cs%target_density(nkml))
then
322 k_interior = cs%nlay_ml_offset + real(nkml)
323 elseif (rho_ml_av > cs%target_density(nz+1))
then
324 k_interior = real(nz+1)
326 if ((rho_ml_av >= cs%target_density(k)) .and. &
327 (rho_ml_av < cs%target_density(k+1)))
then
328 k_interior = (cs%nlay_ml_offset + k) + &
329 (rho_ml_av - cs%target_density(k)) / &
330 (cs%target_density(k+1) - cs%target_density(k))
334 if (k_interior > real(nz+1)) k_interior = real(nz+1)
337 k = int(ceiling(k_interior))
338 z_interior = (k-k_interior)*z_col_new(k-1) + (1.0+(k_interior-k))*z_col_new(k)
340 if (cs%fix_haloclines)
then
346 if (cs%halocline_filter_length > 0.0)
then
347 lfilt = cs%halocline_filter_length
350 h_tr = h_col(1) + h_subroundoff
351 b1 = 1.0 / (h_tr + lfilt) ; d1 = h_tr * b1
352 t_f(1) = (b1*h_tr)*t_col(1) ; s_f(1) = (b1*h_tr)*s_col(1)
355 h_tr = h_col(k) + h_subroundoff ; b_denom_1 = h_tr + d1*lfilt
356 b1 = 1.0 / (b_denom_1 + lfilt) ; d1 = b_denom_1 * b1
357 t_f(k) = b1 * (h_tr*t_col(k) + lfilt*t_f(k-1))
358 s_f(k) = b1 * (h_tr*s_col(k) + lfilt*s_f(k-1))
361 t_f(k) = t_f(k) + c1(k+1)*t_f(k+1) ; s_f(k) = s_f(k) + c1(k+1)*s_f(k+1)
364 do k=1,nz ; t_f(k) = t_col(k) ; s_f(k) = s_col(k) ;
enddo
367 t_int(1) = t_f(1) ; s_int(1) = s_f(1)
369 t_int(k) = 0.5*(t_f(k-1) + t_f(k)) ; s_int(k) = 0.5*(s_f(k-1) + s_f(k))
370 p_is(k) = z_col(k) * h_to_pres
371 p_r(k) = cs%ref_pressure + cs%compressibility_fraction * ( p_is(k) - cs%ref_pressure )
373 t_int(nz+1) = t_f(nz) ; s_int(nz+1) = s_f(nz)
374 p_is(nz+1) = z_col(nz+1) * h_to_pres
375 call calculate_density_derivs(t_int, s_int, p_is, drhois_dt, drhois_ds, &
376 eqn_of_state, (/2,nz/) )
377 call calculate_density_derivs(t_int, s_int, p_r, drhor_dt, drhor_ds, &
378 eqn_of_state, (/2,nz/) )
379 if (cs%compressibility_fraction > 0.0)
then
380 call calculate_compress(t_int, s_int, p_r(:), rho_tmp, drho_dp, 2, nz-1, eqn_of_state)
382 do k=2,nz ; drho_dp(k) = 0.0 ;
enddo
385 h_to_cpa = cs%compressibility_fraction * h_to_pres
388 dris = drhois_dt(k) * (t_f(k) - t_f(k-1)) + &
389 drhois_ds(k) * (s_f(k) - s_f(k-1))
390 drr = (drhor_dt(k) * (t_f(k) - t_f(k-1)) + &
391 drhor_ds(k) * (s_f(k) - s_f(k-1))) + &
392 drho_dp(k) * (h_to_cpa*0.5*(h_col(k) + h_col(k-1)))
394 if (dris <= 0.0)
then
397 strat_rat(k) = 2.0*max(drr,0.0) / (dris + abs(drr))
400 strat_rat(nz+1) = 1.0
402 z_int_unst = 0.0 ; fn_now = 0.0
403 fn_zero_val = min(2.0*cs%halocline_strat_tol, &
404 0.5*(1.0 + cs%halocline_strat_tol))
405 if (cs%halocline_strat_tol > 0.0)
then
407 i_hstol = 0.0 ;
if (fn_zero_val - cs%halocline_strat_tol > 0.0) &
408 i_hstol = 1.0 / (fn_zero_val - cs%halocline_strat_tol)
409 do k=nz,1,-1 ;
if (cs%ref_pressure > p_is(k+1))
then
410 z_int_unst = z_int_unst + fn_now * h_col(k)
411 if (strat_rat(k) <= fn_zero_val)
then
412 if (strat_rat(k) <= cs%halocline_strat_tol)
then ; fn_now = 1.0
414 fn_now = max(fn_now, (fn_zero_val - strat_rat(k)) * i_hstol)
419 do k=nz,1,-1 ;
if (cs%ref_pressure > p_is(k+1))
then
420 z_int_unst = z_int_unst + fn_now * h_col(k)
421 if (strat_rat(k) <= cs%halocline_strat_tol) fn_now = 1.0
425 if (z_interior < z_int_unst)
then
427 kur1 = max(int(ceiling(k_interior)),2)
428 if (z_col_new(kur1-1) < z_interior)
then
430 do k = kur1,nz+1 ;
if (z_col_new(k) >= z_int_unst)
then
432 if (z_col_new(k-1) >= z_int_unst) &
433 call mom_error(fatal,
"build_grid_SLight, bad halocline structure.")
434 k_int2 = real(k-1) + (z_int_unst - z_col_new(k-1)) / &
435 (z_col_new(k) - z_col_new(k-1))
438 if (z_col_new(nz+1) < z_int_unst)
then
440 z_int_unst = z_col_new(nz+1) ; k_int2 = real(nz+1)
444 if (k_int2 > k_interior)
then
445 k_interior = k_int2 ; z_interior = z_int_unst
453 z_col_new(k) = min((k-1)*cs%dz_ml_min, &
454 z_col_new(nz+1) - cs%min_thickness*(nz+1-k))
456 z_ml_fix = z_col_new(nkml+1)
457 if (z_interior > z_ml_fix)
then
458 dz_dk = (z_interior - z_ml_fix) / (k_interior - (nkml+1))
459 do k=nkml+2,int(floor(k_interior))
460 z_col_new(k) = z_ml_fix + dz_dk * (k - (nkml+1))
464 if (z_col_new(k) <= z_col_new(cs%nz_fixed_surface+1))
then
465 z_col_new(k) = z_col_new(cs%nz_fixed_surface+1)
470 if (maximum_depths_set .and. maximum_h_set)
then ;
do k=2,nz
473 z_col_new(k) = min(z_col_new(k), cs%max_interface_depths(k), &
474 z_col_new(k-1) + cs%max_layer_thickness(k-1))
475 enddo ;
elseif (maximum_depths_set)
then ;
do k=2,nz
476 z_col_new(k) = min(z_col_new(k), cs%max_interface_depths(k))
477 enddo ;
elseif (maximum_h_set)
then ;
do k=2,nz
478 z_col_new(k) = min(z_col_new(k), z_col_new(k-1) + cs%max_layer_thickness(k-1))