11 implicit none ;
private
20 real :: min_thickness = 0.
27 logical :: integrate_downward_for_e = .false.
30 real,
allocatable,
dimension(:) :: target_density
37 integer,
parameter :: nb_regridding_iterations = 1
39 real,
parameter :: deviation_tolerance = 1e-10
41 public init_coord_rho, set_rho_params, build_rho_column, old_inflate_layers_1d, end_coord_rho
46 subroutine init_coord_rho(CS, nk, ref_pressure, target_density, interp_CS)
48 integer,
intent(in) :: nk
49 real,
intent(in) :: ref_pressure
50 real,
dimension(:),
intent(in) :: target_density
53 if (
associated(cs))
call mom_error(fatal,
"init_coord_rho: CS already associated!")
55 allocate(cs%target_density(nk+1))
58 cs%ref_pressure = ref_pressure
59 cs%target_density(:) = target_density(:)
60 cs%interp_CS = interp_cs
61 end subroutine init_coord_rho
64 subroutine end_coord_rho(CS)
68 if (.not.
associated(cs))
return
69 deallocate(cs%target_density)
71 end subroutine end_coord_rho
74 subroutine set_rho_params(CS, min_thickness, integrate_downward_for_e, interp_CS)
76 real,
optional,
intent(in) :: min_thickness
77 logical,
optional,
intent(in) :: integrate_downward_for_e
83 if (.not.
associated(cs))
call mom_error(fatal,
"set_rho_params: CS not associated")
85 if (
present(min_thickness)) cs%min_thickness = min_thickness
86 if (
present(integrate_downward_for_e)) cs%integrate_downward_for_e = integrate_downward_for_e
87 if (
present(interp_cs)) cs%interp_CS = interp_cs
88 end subroutine set_rho_params
94 subroutine build_rho_column(CS, nz, depth, h, T, S, eqn_of_state, z_interface, &
95 h_neglect, h_neglect_edge)
97 integer,
intent(in) :: nz
98 real,
intent(in) :: depth
99 real,
dimension(nz),
intent(in) :: h
100 real,
dimension(nz),
intent(in) :: t
101 real,
dimension(nz),
intent(in) :: s
102 type(
eos_type),
pointer :: eqn_of_state
103 real,
dimension(CS%nk+1), &
104 intent(inout) :: z_interface
105 real,
optional,
intent(in) :: h_neglect
108 real,
optional,
intent(in) :: h_neglect_edge
112 integer :: k, count_nonzero_layers
113 integer,
dimension(nz) :: mapping
114 real,
dimension(nz) :: p, densities, h_nv
115 real,
dimension(nz+1) :: xtmp
116 real,
dimension(CS%nk) :: h_new
117 real,
dimension(CS%nk+1) :: x1
120 call copy_finite_thicknesses(nz, h, cs%min_thickness, count_nonzero_layers, h_nv, mapping)
122 if (count_nonzero_layers > 1)
then
124 do k = 1,count_nonzero_layers
125 xtmp(k+1) = xtmp(k) + h_nv(k)
129 p(:) = cs%ref_pressure
131 do k = 1,count_nonzero_layers
132 densities(k) = densities(mapping(k))
136 call build_and_interpolate_grid(cs%interp_CS, densities, count_nonzero_layers, &
137 h_nv, xtmp, cs%target_density, cs%nk, h_new, &
138 x1, h_neglect, h_neglect_edge)
141 call old_inflate_layers_1d(cs%min_thickness, cs%nk, h_new)
144 x1(1) = 0.0 ;
do k = 1,cs%nk ; x1(k+1) = x1(k) + h_new(k) ;
enddo
146 h_new(k) = x1(k+1) - x1(k)
150 if (nz == cs%nk)
then
159 if (cs%integrate_downward_for_e)
then
163 z_interface(k+1) = z_interface(k) - h_new(k)
167 z_interface(cs%nk+1) = -depth
169 z_interface(k) = z_interface(k+1) + h_new(k)
173 end subroutine build_rho_column
187 subroutine build_rho_column_iteratively(CS, remapCS, nz, depth, h, T, S, eqn_of_state, &
188 zInterface, h_neglect, h_neglect_edge)
191 integer,
intent(in) :: nz
192 real,
intent(in) :: depth
193 real,
dimension(nz),
intent(in) :: h
194 real,
dimension(nz),
intent(in) :: T
195 real,
dimension(nz),
intent(in) :: S
196 type(
eos_type),
pointer :: eqn_of_state
197 real,
dimension(nz+1),
intent(inout) :: zInterface
198 real,
optional,
intent(in) :: h_neglect
201 real,
optional,
intent(in) :: h_neglect_edge
206 integer :: count_nonzero_layers
211 real,
dimension(nz) :: p, densities, T_tmp, S_tmp, Tmp
212 integer,
dimension(nz) :: mapping
213 real,
dimension(nz) :: h0, h1, hTmp
214 real,
dimension(nz+1) :: x0, x1, xTmp
216 threshold = cs%min_thickness
217 p(:) = cs%ref_pressure
225 do while ( ( m <= nb_regridding_iterations ) .and. &
226 ( deviation > deviation_tolerance ) )
229 call copy_finite_thicknesses(nz, h0, threshold, count_nonzero_layers, htmp, mapping)
230 if ( count_nonzero_layers <= 1 )
then
236 do k = 1,count_nonzero_layers
237 xtmp(k+1) = xtmp(k) + htmp(k)
242 1, nz, eqn_of_state )
244 do k = 1,count_nonzero_layers
245 densities(k) = densities(mapping(k))
250 call build_and_interpolate_grid(cs%interp_CS, densities, count_nonzero_layers, &
251 htmp, xtmp, cs%target_density, nz, h1, x1, h_neglect, h_neglect_edge)
253 call old_inflate_layers_1d( cs%min_thickness, nz, h1 )
254 x1(1) = 0.0 ;
do k = 1,nz ; x1(k+1) = x1(k) + h1(k) ;
enddo
258 h1(k) = x1(k+1) - x1(k)
261 call remapping_core_h(remapcs, nz, h0, s, nz, h1, tmp, h_neglect, h_neglect_edge)
264 call remapping_core_h(remapcs, nz, h0, t, nz, h1, tmp, h_neglect, h_neglect_edge)
272 x0(k) = x0(k-1) + h0(k-1)
273 x1(k) = x1(k-1) + h1(k-1)
274 deviation = deviation + (x0(k)-x1(k))**2
276 deviation = sqrt( deviation / (nz-1) )
285 if (cs%integrate_downward_for_e)
then
288 zinterface(k+1) = zinterface(k) - h1(k)
294 zinterface(nz+1) = -depth
296 zinterface(k) = zinterface(k+1) + h1(k)
302 end subroutine build_rho_column_iteratively
305 subroutine copy_finite_thicknesses(nk, h_in, threshold, nout, h_out, mapping)
306 integer,
intent(in) :: nk
307 real,
dimension(nk),
intent(in) :: h_in
308 real,
intent(in) :: threshold
309 integer,
intent(out) :: nout
310 real,
dimension(nk),
intent(out) :: h_out
311 integer,
dimension(nk),
intent(out) :: mapping
313 integer :: k, k_thickest
314 real :: thickness_in_vanished, thickest_h_out
318 thickness_in_vanished = 0.0
319 thickest_h_out = h_in(1)
324 if (h_in(k) > threshold)
then
328 h_out(nout) = h_in(k)
329 if (h_out(nout) > thickest_h_out)
then
330 thickest_h_out = h_out(nout)
335 thickness_in_vanished = thickness_in_vanished + h_in(k)
340 if (nout <= 1)
return
343 h_out(k_thickest) = h_out(k_thickest) + thickness_in_vanished
345 end subroutine copy_finite_thicknesses
349 subroutine old_inflate_layers_1d( min_thickness, nk, h )
352 real,
intent(in) :: min_thickness
353 integer,
intent(in) :: nk
354 real,
dimension(:),
intent(inout) :: h
359 integer :: count_nonzero_layers
365 count_nonzero_layers = 0
367 if ( h(k) > min_thickness )
then
368 count_nonzero_layers = count_nonzero_layers + 1
373 if ( count_nonzero_layers == nk )
return
376 if ( count_nonzero_layers == 0 )
then
386 if ( h(k) <= min_thickness )
then
387 delta = min_thickness - h(k)
388 correction = correction + delta
397 if ( h(k) > maxthickness )
then
403 h(k_found) = h(k_found) - correction
405 end subroutine old_inflate_layers_1d