40 use diag_axis_mod
, only : get_diag_axis_name
41 use diag_manager_mod
, only : diag_axis_init
43 implicit none ;
private 60 logical :: configured = .false.
61 logical :: initialized = .false.
62 logical :: used = .false.
63 integer :: vertical_coord = 0
64 character(len=10) :: vertical_coord_name =
'' 65 character(len=16) :: diag_coord_name =
'' 66 character(len=8) :: diag_module_suffix =
'' 70 real,
dimension(:,:,:),
allocatable :: h
71 real,
dimension(:),
allocatable :: dz
72 integer :: interface_axes_id = 0
73 integer :: layer_axes_id = 0
81 character(len=*),
intent(in) :: coord_tuple
84 remap_cs%diag_module_suffix = trim(
extractword(coord_tuple, 1))
85 remap_cs%diag_coord_name = trim(
extractword(coord_tuple, 2))
86 remap_cs%vertical_coord_name = trim(
extractword(coord_tuple, 3))
87 remap_cs%vertical_coord =
coordinatemode(remap_cs%vertical_coord_name)
88 remap_cs%configured = .false.
89 remap_cs%initialized = .false.
90 remap_cs%used = .false.
100 if (
allocated(remap_cs%h))
deallocate(remap_cs%h)
101 if (
allocated(remap_cs%dz))
deallocate(remap_cs%dz)
102 remap_cs%configured = .false.
103 remap_cs%initialized = .false.
104 remap_cs%used = .false.
117 if (.not. remap_cs%used)
then 129 remap_cs%used = .true.
140 integer :: nzi(4), nzl(4), k
141 character(len=200) :: inputdir, string, filename, int_varname, layer_varname
142 character(len=40) :: mod =
"MOM_diag_remap" 143 character(len=8) :: units, expected_units
144 character(len=34) :: longname, string2
146 character(len=256) :: err_msg
149 real,
allocatable,
dimension(:) :: interfaces, layers
151 call initialize_regridding(remap_cs%regrid_cs, gv, gv%max_depth, param_file, mod, &
152 trim(remap_cs%vertical_coord_name),
"DIAG_COORD", trim(remap_cs%diag_coord_name))
153 call set_regrid_params(remap_cs%regrid_cs, min_thickness=0., integrate_downward_for_e=.false.)
155 remap_cs%nz = get_regrid_size(remap_cs%regrid_cs)
159 longname =
'Fraction' 162 longname =
'Target Potential Density' 169 allocate(interfaces(remap_cs%nz+1))
170 allocate(layers(remap_cs%nz))
172 interfaces(:) = getcoordinateinterfaces(remap_cs%regrid_cs)
173 layers(:) = 0.5 * ( interfaces(1:remap_cs%nz) + interfaces(2:remap_cs%nz+1) )
175 remap_cs%interface_axes_id = diag_axis_init(
lowercase(trim(remap_cs%diag_coord_name))//
'_i', &
176 interfaces, trim(units),
'z', &
177 trim(longname)//
' at interface', direction=-1)
178 remap_cs%layer_axes_id = diag_axis_init(
lowercase(trim(remap_cs%diag_coord_name))//
'_l', &
179 layers, trim(units),
'z', &
180 trim(longname)//
' at cell center', direction=-1, &
181 edges=remap_cs%interface_axes_id)
184 remap_cs%configured = .true.
186 deallocate(interfaces)
195 integer,
intent(out) :: nz
196 integer,
intent(out) :: id_layer
197 integer,
intent(out) :: id_interface
200 id_layer = remap_cs%layer_axes_id
201 id_interface = remap_cs%interface_axes_id
211 logical :: diag_remap_axes_configured
213 diag_remap_axes_configured = remap_cs%configured
225 real,
dimension(:, :, :),
intent(in) :: h, T, S
226 type(
eos_type),
pointer,
intent(in) :: eqn_of_state
229 integer :: i, j, k, nz
230 real,
dimension(remap_cs%nz + 1) :: zInterfaces
231 real,
dimension(remap_cs%nz) :: resolution
235 if (.not. remap_cs%configured)
then 241 if (.not. remap_cs%initialized)
then 243 call initialize_remapping(remap_cs%remap_cs,
'PPM_IH4', boundary_extrapolation=.false.)
244 allocate(remap_cs%h(g%isd:g%ied,g%jsd:g%jed, nz))
245 remap_cs%initialized = .true.
253 if (g%mask2dT(i,j)==0.)
then 254 remap_cs%h(i,j,:) = 0.
260 g%bathyT(i,j), sum(h(i,j,:)), zinterfaces)
263 g%bathyT(i,j), sum(h(i,j,:)), zinterfaces)
266 g%bathyT(i,j), h(i,j,:), t(i, j, :), s(i, j, :), &
267 eqn_of_state, zinterfaces)
271 call mom_error(fatal,
"diag_remap_update: SLIGHT coordinate not coded for diagnostics yet!")
275 call mom_error(fatal,
"diag_remap_update: HYCOM1 coordinate not coded for diagnostics yet!")
277 remap_cs%h(i,j,:) = zinterfaces(1:nz) - zinterfaces(2:nz+1)
285 mask, missing_value, field, remapped_field)
288 real,
dimension(:,:,:),
intent(in) :: h
289 logical,
intent(in) :: staggered_in_x
290 logical,
intent(in) :: staggered_in_y
291 real,
dimension(:,:,:),
pointer :: mask
292 real,
intent(in) :: missing_value
293 real,
dimension(:,:,:),
intent(in) :: field(:,:,:)
294 real,
dimension(:,:,:),
intent(inout) :: remapped_field
296 real,
dimension(remap_cs%nz) :: h_dest
297 real,
dimension(size(h,3)) :: h_src
298 logical :: mask_vanished_layers
299 integer :: nz_src, nz_dest
302 call assert(remap_cs%initialized,
'diag_remap_do_remap: remap_cs not initialized.')
303 call assert(
size(field, 3) ==
size(h, 3), &
304 'diag_remap_do_remap: Remap field and thickness z-axes do not match.')
306 nz_src =
size(field,3)
307 nz_dest = remap_cs%nz
308 mask_vanished_layers = (remap_cs%vertical_coord ==
coordinatemode(
'ZSTAR'))
309 remapped_field(:,:,:) = missing_value
311 if (staggered_in_x .and. .not. staggered_in_y)
then 315 if (
associated(mask))
then 316 if (mask(i,j,1) == 0.) cycle
318 h_src(:) = 0.5 * (h(i,j,:) + h(i+1,j,:))
319 h_dest(:) = 0.5 * (remap_cs%h(i,j,:) + remap_cs%h(i+1,j,:))
321 nz_dest, h_dest(:), remapped_field(i,j,:))
322 if (mask_vanished_layers)
then 324 if (h_dest(k) == 0.) remapped_field(i, j, k:nz_dest) = missing_value
329 elseif (staggered_in_y .and. .not. staggered_in_x)
then 333 if (
associated(mask))
then 334 if (mask(i,j,1) == 0.) cycle
336 h_src(:) = 0.5 * (h(i,j,:) + h(i,j+1,:))
337 h_dest(:) = 0.5 * (remap_cs%h(i,j,:) + remap_cs%h(i,j+1,:) )
339 nz_dest, h_dest(:), remapped_field(i,j,:))
340 if (mask_vanished_layers)
then 342 if (h_dest(k) == 0.) remapped_field(i,j,k) = missing_value
347 elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y))
then 351 if (
associated(mask))
then 352 if (mask(i,j, 1) == 0.) cycle
354 h_dest(:) = remap_cs%h(i,j,:)
356 nz_dest, h_dest(:), remapped_field(i,j,:))
357 if (mask_vanished_layers)
then 359 if (h_dest(k)==0.) remapped_field(i,j,k) = missing_value
365 call assert(.false.,
'diag_remap_do_remap: Unsupported axis combination')
372 mask, missing_value, field, reintegrated_field)
375 real,
dimension(:,:,:),
intent(in) :: h
376 logical,
intent(in) :: staggered_in_x
377 logical,
intent(in) :: staggered_in_y
378 real,
dimension(:,:,:),
pointer :: mask
379 real,
intent(in) :: missing_value
380 real,
dimension(:,:,:),
intent(in) :: field
381 real,
dimension(:,:,:),
intent(inout) :: reintegrated_field
383 real,
dimension(remap_cs%nz) :: h_dest
384 real,
dimension(size(h,3)) :: h_src
385 integer :: nz_src, nz_dest
388 call assert(remap_cs%initialized,
'vertically_reintegrate_diag_field: remap_cs not initialized.')
389 call assert(
size(field, 3) ==
size(h, 3), &
390 'vertically_reintegrate_diag_field: Remap field and thickness z-axes do not match.')
392 nz_src =
size(field,3)
393 nz_dest = remap_cs%nz
394 reintegrated_field(:,:,:) = missing_value
396 if (staggered_in_x .and. .not. staggered_in_y)
then 400 if (
associated(mask))
then 401 if (mask(i,j,1) == 0.) cycle
403 h_src(:) = 0.5 * (h(i,j,:) + h(i+1,j,:))
404 h_dest(:) = 0.5 * ( remap_cs%h(i,j,:) + remap_cs%h(i+1,j,:) )
406 nz_dest, h_dest, missing_value, reintegrated_field(i,j,:))
409 elseif (staggered_in_y .and. .not. staggered_in_x)
then 413 if (
associated(mask))
then 414 if (mask(i,j,1) == 0.) cycle
416 h_src(:) = 0.5 * (h(i,j,:) + h(i,j+1,:))
417 h_dest(:) = 0.5 * ( remap_cs%h(i,j,:) + remap_cs%h(i,j+1,:) )
419 nz_dest, h_dest, missing_value, reintegrated_field(i,j,:))
422 elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y))
then 426 if (
associated(mask))
then 427 if (mask(i,j, 1) == 0.) cycle
430 h_dest(:) = remap_cs%h(i,j,:)
432 nz_dest, h_dest, missing_value, reintegrated_field(i,j,:))
436 call assert(.false.,
'vertically_reintegrate_diag_field: Q point remapping is not coded yet.')
443 mask, missing_value, field, interpolated_field)
446 real,
dimension(:,:,:),
intent(in) :: h
447 logical,
intent(in) :: staggered_in_x
448 logical,
intent(in) :: staggered_in_y
449 real,
dimension(:,:,:),
pointer :: mask
450 real,
intent(in) :: missing_value
451 real,
dimension(:,:,:),
intent(in) :: field
452 real,
dimension(:,:,:),
intent(inout) :: interpolated_field
454 real,
dimension(remap_cs%nz) :: h_dest
455 real,
dimension(size(h,3)) :: h_src
456 integer :: nz_src, nz_dest
459 call assert(remap_cs%initialized,
'vertically_interpolate_diag_field: remap_cs not initialized.')
460 call assert(
size(field, 3) ==
size(h, 3)+1, &
461 'vertically_interpolate_diag_field: Remap field and thickness z-axes do not match.')
463 interpolated_field(:,:,:) = missing_value
466 nz_dest = remap_cs%nz
468 if (staggered_in_x .and. .not. staggered_in_y)
then 472 if (
associated(mask))
then 473 if (mask(i,j,1) == 0.) cycle
475 h_src(:) = 0.5 * (h(i,j,:) + h(i+1,j,:))
476 h_dest(:) = 0.5 * ( remap_cs%h(i,j,:) + remap_cs%h(i+1,j,:) )
478 nz_dest, h_dest, missing_value, interpolated_field(i,j,:))
481 elseif (staggered_in_y .and. .not. staggered_in_x)
then 485 if (
associated(mask))
then 486 if (mask(i,j,1) == 0.) cycle
488 h_src(:) = 0.5 * (h(i,j,:) + h(i,j+1,:))
489 h_dest(:) = 0.5 * ( remap_cs%h(i,j,:) + remap_cs%h(i,j+1,:) )
491 nz_dest, h_dest, missing_value, interpolated_field(i,j,:))
494 elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y))
then 498 if (
associated(mask))
then 499 if (mask(i,j, 1) == 0.) cycle
502 h_dest(:) = remap_cs%h(i,j,:)
504 nz_dest, h_dest, missing_value, interpolated_field(i,j,:))
508 call assert(.false.,
'vertically_interpolate_diag_field: Q point remapping is not coded yet.')
515 is_layer, is_extensive, &
516 missing_value, field, averaged_field)
518 real,
dimension(:,:,:),
intent(in) :: h
519 logical,
intent(in) :: staggered_in_x
520 logical,
intent(in) :: staggered_in_y
521 logical,
intent(in) :: is_layer
522 logical,
intent(in) :: is_extensive
523 real,
intent(in) :: missing_value
524 real,
dimension(:,:,:),
intent(in) :: field
525 real,
dimension(:),
intent(inout) :: averaged_field
527 real,
dimension(size(field, 3)) :: vol_sum, stuff_sum
528 real :: v1, v2, total_volume, total_stuff, val
529 integer :: i, j, k, nz
533 if (staggered_in_x .and. .not. staggered_in_y)
then 539 if (is_extensive)
then 540 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
543 vol_sum(k) = vol_sum(k) + 0.5 * ( v1 + v2 ) * g%mask2dT(i,j)
544 stuff_sum(k) = stuff_sum(k) + 0.5 * ( v1 * field(i,j,k) + v2 * field(i-1,j,k) ) * g%mask2dT(i,j)
547 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
548 v1 = g%areaCu(i,j) * 0.5 * ( h(i,j,k) + h(i+1,j,k) )
549 v2 = g%areaCu(i-1,j) * 0.5 * ( h(i,j,k) + h(i-1,j,k) )
550 vol_sum(k) = vol_sum(k) + 0.5 * ( v1 + v2 ) * g%mask2dT(i,j)
551 stuff_sum(k) = stuff_sum(k) + 0.5 * ( v1 * field(i,j,k) + v2 * field(i-1,j,k) ) * g%mask2dT(i,j)
559 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
562 vol_sum(k) = vol_sum(k) + 0.5 * ( v1 + v2 ) * g%mask2dT(i,j)
563 stuff_sum(k) = stuff_sum(k) + 0.5 * ( v1 * field(i,j,k) + v2 * field(i-1,j,k) ) * g%mask2dT(i,j)
567 elseif (staggered_in_y .and. .not. staggered_in_x)
then 573 if (is_extensive)
then 574 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
577 vol_sum(k) = vol_sum(k) + 0.5 * ( v1 + v2 ) * g%mask2dT(i,j)
578 stuff_sum(k) = stuff_sum(k) + 0.5 * ( v1 * field(i,j,k) + v2 * field(i,j-1,k) ) * g%mask2dT(i,j)
581 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
582 v1 = g%areaCv(i,j) * 0.5 * ( h(i,j,k) + h(i,j+1,k) )
583 v2 = g%areaCv(i,j-1) * 0.5 * ( h(i,j,k) + h(i,j-1,k) )
584 vol_sum(k) = vol_sum(k) + 0.5 * ( v1 + v2 ) * g%mask2dT(i,j)
585 stuff_sum(k) = stuff_sum(k) + 0.5 * ( v1 * field(i,j,k) + v2 * field(i,j-1,k) ) * g%mask2dT(i,j)
593 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
596 vol_sum(k) = vol_sum(k) + 0.5 * ( v1 + v2 ) * g%mask2dT(i,j)
597 stuff_sum(k) = stuff_sum(k) + 0.5 * ( v1 * field(i,j,k) + v2 * field(i,j-1,k) ) * g%mask2dT(i,j)
601 elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y))
then 607 if (is_extensive)
then 608 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
609 if (g%mask2dT(i,j)>0. .and. h(i,j,k)>0.)
then 611 vol_sum(k) = vol_sum(k) + v1
612 stuff_sum(k) = stuff_sum(k) + v1 * field(i,j,k)
616 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
617 if (g%mask2dT(i,j)>0. .and. h(i,j,k)>0.)
then 618 v1 = g%areaT(i,j) * h(i,j,k)
619 vol_sum(k) = vol_sum(k) + v1
620 stuff_sum(k) = stuff_sum(k) + v1 * field(i,j,k)
629 do j=g%jsc, g%jec ;
do i=g%isc, g%iec
631 if (g%mask2dT(i,j)>0. .and. val/=missing_value)
then 633 vol_sum(k) = vol_sum(k) + v1
634 stuff_sum(k) = stuff_sum(k) + v1 * field(i,j,k)
640 call assert(.false.,
'horizontally_average_diag_field: Q point averaging is not coded yet.')
643 call sum_across_pes(vol_sum, nz)
644 call sum_across_pes(stuff_sum, nz)
647 if (vol_sum(k)>0.)
then 648 averaged_field(k) = stuff_sum(k) / vol_sum(k)
650 averaged_field(k) = missing_value
integer function coordinatemode(string)
Parse a string parameter specifying the coordinate mode and return the appropriate enumerated integer...
Provides kernels for single-column interpolation, re-integration (re-mapping of integrated quantities...
real function, dimension(nk), public uniformresolution(nk, coordMode, maxDepth, rhoLight, rhoHeavy)
type(rho_cs) function, public get_rho_cs(CS)
subroutine, public diag_remap_set_active(remap_cs)
Indicate that this remapping type is actually used by the diag manager. If this is never called then ...
subroutine, public diag_remap_init(remap_cs, coord_tuple)
Initialize a diagnostic remapping type with the given vertical coordinate.
Ocean grid type. See mom_grid for details.
logical function, public diag_remap_axes_configured(remap_cs)
Whether or not the axes for this vertical coordinated has been configured. Configuration is complete ...
type(zlike_cs) function, public get_zlike_cs(CS)
subroutine, public diag_remap_diag_registration_closed(remap_cs)
Inform that all diagnostics have been registered. If _set_active() has not been called on the remappi...
Provides the ocean grid type.
subroutine, public diag_remap_end(remap_cs)
De-init a diagnostic remapping type. Free allocated memory.
subroutine, public vertically_interpolate_diag_field(remap_cs, G, h, staggered_in_x, staggered_in_y, mask, missing_value, field, interpolated_field)
Vertically interpolate diagnostic field to alternative vertical grid.
Generates vertical grids as part of the ALE algorithm.
Provides column-wise vertical remapping functions.
This module contains I/O framework code.
integer function, public get_regrid_size(CS)
Returns the number of levels/layers in the regridding control structure.
subroutine, public reintegrate_column(nsrc, h_src, uh_src, ndest, h_dest, missing_value, uh_dest)
Conservatively calculate integrated data, uh_dest, on grid h_dest, from layer-integrated data...
Container for remapping parameters.
subroutine, public diag_remap_get_axes_info(remap_cs, nz, id_layer, id_interface)
Get layer and interface axes ids for this coordinate Needed when defining axes groups.
character(len=len(input_string)) function, public lowercase(input_string)
subroutine, public build_rho_column(CS, remapCS, nz, depth, h, T, S, eqn_of_state, zInterface)
Regridding control structure.
This type represents remapping of diagnostics to a particular vertical coordinate. There is one of these types for each vertical coordinate. The vertical axes of a diagnostic will reference an instance of this type indicating how (or if) the diagnostic should be vertically remapped when being posted.
subroutine, public set_regrid_params(CS, boundary_extrapolation, min_thickness, old_grid_weight, interp_scheme, depth_of_time_filter_shallow, depth_of_time_filter_deep, compress_fraction, dz_min_surface, nz_fixed_surface, Rho_ML_avg_depth, nlay_ML_to_interior, fix_haloclines, halocline_filt_len, halocline_strat_tol, integrate_downward_for_e, adaptTimeRatio, adaptZoom, adaptZoomCoeff, adaptBuoyCoeff, adaptAlpha, adaptDoMin)
Can be used to set any of the parameters for MOM_regridding.
subroutine, public assert(logical_arg, msg)
Issues a FATAL error if the assertion fails, i.e. the first argument is false.
character(len=120) function, public extractword(string, n)
Returns the string corresponding to the nth word in the argument or "" if the string is not long enou...
subroutine, public diag_remap_update(remap_cs, G, h, T, S, eqn_of_state)
Build/update target vertical grids for diagnostic remapping.
Regrid columns for the sigma coordinate.
real function, dimension(cs%nk+1), public getcoordinateinterfaces(CS)
Query the target coordinate interface positions.
subroutine, public build_zstar_column(CS, nz, depth, total_thickness, zInterface, z_rigid_top, eta_orig)
Builds a z* coordinate with a minimum thickness.
Regrid columns for a z-like coordinate (z-star, z-level)
subroutine, public horizontally_average_diag_field(G, h, staggered_in_x, staggered_in_y, is_layer, is_extensive, missing_value, field, averaged_field)
Horizontally average field.
This module is used for runtime remapping of diagnostics to z star, sigma and rho vertical coordinate...
type(sigma_cs) function, public get_sigma_cs(CS)
Provides subroutines for quantities specific to the equation of state.
subroutine, public remapping_core_h(CS, n0, h0, u0, n1, h1, u1)
Remaps column of values u0 on grid h0 to grid h1 assuming the top edge is aligned.
subroutine, public diag_remap_do_remap(remap_cs, G, h, staggered_in_x, staggered_in_y, mask, missing_value, field, remapped_field)
Remap diagnostic field to alternative vertical grid.
Regrid columns for the continuous isopycnal (rho) coordinate.
subroutine, public vertically_reintegrate_diag_field(remap_cs, G, h, staggered_in_x, staggered_in_y, mask, missing_value, field, reintegrated_field)
Vertically re-grid an already vertically-integrated diagnostic field to alternative vertical grid...
Contains constants for interpreting input parameters that control regridding.
subroutine, public initialize_remapping(CS, remapping_scheme, boundary_extrapolation, check_reconstruction, check_remapping, force_bounds_in_subcell)
Constructor for remapping control structure.
subroutine, public mom_error(level, message, all_print)
subroutine, public build_sigma_column(CS, nz, depth, totalThickness, zInterface)
Build a sigma coordinate column.
subroutine, public initialize_regridding(CS, GV, max_depth, param_file, mod, coord_mode, param_prefix, param_suffix)
Initialization and configures a regridding control structure based on customizable run-time parameter...
subroutine, public diag_remap_configure_axes(remap_cs, GV, param_file)
Configure the vertical axes for a diagnostic remapping control structure. Reads a configuration param...
A control structure for the equation of state.
subroutine, public interpolate_column(nsrc, h_src, u_src, ndest, h_dest, missing_value, u_dest)
Linearly interpolate interface data, u_src, from grid h_src to a grid h_dest.