MOM6
mom_diag_remap Module Reference

Detailed Description

This module is used for runtime remapping of diagnostics to z star, sigma and rho vertical coordinates. It defines the diag_remap_ctrl type which represents a remapping of diagnostics to a particular vertical coordinate. The module is used by the diag mediator module in the following way: 1) _init() is called to initialise a diag_remap_ctrl instance. 2) _configure_axes() is called to read the configuration file and set up the vertical coordinate / axes definitions. 3) _get_axes_info() returns information needed for the diag mediator to define new axes for the remapped diagnostics. 4) _update() is called periodically (whenever h, T or S change) to either create or update the target remapping grids. 5) _do_remap() is called from within a diag post() to do the remapping before the diagnostic is written out.

Data Types

type  diag_remap_ctrl
 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. More...
 

Functions/Subroutines

subroutine, public diag_remap_init (remap_cs, coord_tuple)
 Initialize a diagnostic remapping type with the given vertical coordinate. More...
 
subroutine, public diag_remap_end (remap_cs)
 De-init a diagnostic remapping type. Free allocated memory. More...
 
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 remapping control structure will be disabled. This saves time in the case that a vertical coordinate was configured but no diagnostics which use the coordinate appeared in the diag_table. More...
 
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 the type will be disabled to save time. See further explanation with diag_remap_registration_closed. More...
 
subroutine, public diag_remap_configure_axes (remap_cs, GV, param_file)
 Configure the vertical axes for a diagnostic remapping control structure. Reads a configuration parameters to determine coordinate generation. More...
 
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. More...
 
logical function, public diag_remap_axes_configured (remap_cs)
 Whether or not the axes for this vertical coordinated has been configured. Configuration is complete when diag_remap_configure_axes() has been successfully called. More...
 
subroutine, public diag_remap_update (remap_cs, G, h, T, S, eqn_of_state)
 Build/update target vertical grids for diagnostic remapping. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 

Function/Subroutine Documentation

◆ diag_remap_axes_configured()

logical function, public mom_diag_remap::diag_remap_axes_configured ( type(diag_remap_ctrl), intent(in)  remap_cs)

Whether or not the axes for this vertical coordinated has been configured. Configuration is complete when diag_remap_configure_axes() has been successfully called.

Definition at line 210 of file MOM_diag_remap.F90.

210  type(diag_remap_ctrl), intent(in) :: remap_cs
211  logical :: diag_remap_axes_configured
212 
213  diag_remap_axes_configured = remap_cs%configured
214 

◆ diag_remap_configure_axes()

subroutine, public mom_diag_remap::diag_remap_configure_axes ( type(diag_remap_ctrl), intent(inout)  remap_cs,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file 
)

Configure the vertical axes for a diagnostic remapping control structure. Reads a configuration parameters to determine coordinate generation.

Parameters
[in,out]remap_csDiag remap control structure
[in]gvocean vertical grid structure
[in]param_fileParameter file structure

Definition at line 136 of file MOM_diag_remap.F90.

References regrid_consts::coordinatemode(), and mom_string_functions::lowercase().

136  type(diag_remap_ctrl), intent(inout) :: remap_cs !< Diag remap control structure
137  type(verticalgrid_type), intent(in) :: gv !< ocean vertical grid structure
138  type(param_file_type), intent(in) :: param_file !< Parameter file structure
139  ! Local variables
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" ! This module's name.
143  character(len=8) :: units, expected_units
144  character(len=34) :: longname, string2
145 
146  character(len=256) :: err_msg
147  logical :: ierr
148 
149  real, allocatable, dimension(:) :: interfaces, layers
150 
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.)
154 
155  remap_cs%nz = get_regrid_size(remap_cs%regrid_cs)
156 
157  if (remap_cs%vertical_coord == coordinatemode('SIGMA')) then
158  units = 'nondim'
159  longname = 'Fraction'
160  elseif (remap_cs%vertical_coord == coordinatemode('RHO')) then
161  units = 'kg m-3'
162  longname = 'Target Potential Density'
163  else
164  units = 'meters'
165  longname = 'Depth'
166  endif
167 
168  ! Make axes objects
169  allocate(interfaces(remap_cs%nz+1))
170  allocate(layers(remap_cs%nz))
171 
172  interfaces(:) = getcoordinateinterfaces(remap_cs%regrid_cs)
173  layers(:) = 0.5 * ( interfaces(1:remap_cs%nz) + interfaces(2:remap_cs%nz+1) )
174 
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)
182 
183  ! Axes have now been configured.
184  remap_cs%configured = .true.
185 
186  deallocate(interfaces)
187  deallocate(layers)
188 
Here is the call graph for this function:

◆ diag_remap_diag_registration_closed()

subroutine, public mom_diag_remap::diag_remap_diag_registration_closed ( type(diag_remap_ctrl), intent(inout)  remap_cs)

Inform that all diagnostics have been registered. If _set_active() has not been called on the remapping control structure will be disabled. This saves time in the case that a vertical coordinate was configured but no diagnostics which use the coordinate appeared in the diag_table.

Parameters
[in,out]remap_csDiag remapping control structure

Definition at line 115 of file MOM_diag_remap.F90.

References diag_remap_end().

115  type(diag_remap_ctrl), intent(inout) :: remap_cs !< Diag remapping control structure
116 
117  if (.not. remap_cs%used) then
118  call diag_remap_end(remap_cs)
119  endif
120 
Here is the call graph for this function:

◆ diag_remap_do_remap()

subroutine, public mom_diag_remap::diag_remap_do_remap ( type(diag_remap_ctrl), intent(in)  remap_cs,
type(ocean_grid_type), intent(in)  G,
real, dimension(:,:,:), intent(in)  h,
logical, intent(in)  staggered_in_x,
logical, intent(in)  staggered_in_y,
real, dimension(:,:,:), pointer  mask,
real, intent(in)  missing_value,
real, dimension(:,:,:), intent(in)  field,
real, dimension(:,:,:), intent(inout)  remapped_field 
)

Remap diagnostic field to alternative vertical grid.

Parameters
[in]remap_csDiagnostic coodinate control structure
[in]gOcean grid structure
[in]hThe current thicknesses
[in]staggered_in_xTrue is the x-axis location is at u or q points
[in]staggered_in_yTrue is the y-axis location is at v or q points
maskA mask for the field
[in]missing_valueA missing_value to assign land/vanished points
[in]fieldThe diagnostic field to be remapped
[in,out]remapped_fieldField remapped to new coordinate

Definition at line 286 of file MOM_diag_remap.F90.

References mom_error_handler::assert(), regrid_consts::coordinatemode(), and mom_remapping::remapping_core_h().

286  type(diag_remap_ctrl), intent(in) :: remap_cs !< Diagnostic coodinate control structure
287  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
288  real, dimension(:,:,:), intent(in) :: h !< The current thicknesses
289  logical, intent(in) :: staggered_in_x !< True is the x-axis location is at u or q points
290  logical, intent(in) :: staggered_in_y !< True is the y-axis location is at v or q points
291  real, dimension(:,:,:), pointer :: mask !< A mask for the field
292  real, intent(in) :: missing_value !< A missing_value to assign land/vanished points
293  real, dimension(:,:,:), intent(in) :: field(:,:,:) !< The diagnostic field to be remapped
294  real, dimension(:,:,:), intent(inout) :: remapped_field !< Field remapped to new coordinate
295  ! Local variables
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
300  integer :: i, j, k
301 
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.')
305 
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
310 
311  if (staggered_in_x .and. .not. staggered_in_y) then
312  ! U-points
313  do j=g%jsc, g%jec
314  do i=g%iscB, g%iecB
315  if (associated(mask)) then
316  if (mask(i,j,1) == 0.) cycle
317  endif
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,:))
320  call remapping_core_h(remap_cs%remap_cs, nz_src, h_src(:), field(i,j,:), &
321  nz_dest, h_dest(:), remapped_field(i,j,:))
322  if (mask_vanished_layers) then ! This only works for z-like output
323  do k=1, nz_dest
324  if (h_dest(k) == 0.) remapped_field(i, j, k:nz_dest) = missing_value
325  enddo
326  endif
327  enddo
328  enddo
329  elseif (staggered_in_y .and. .not. staggered_in_x) then
330  ! V-points
331  do j=g%jscB, g%jecB
332  do i=g%isc, g%iec
333  if (associated(mask)) then
334  if (mask(i,j,1) == 0.) cycle
335  endif
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,:) )
338  call remapping_core_h(remap_cs%remap_cs, nz_src, h_src(:), field(i,j,:), &
339  nz_dest, h_dest(:), remapped_field(i,j,:))
340  if (mask_vanished_layers) then ! This only works for z-like output
341  do k=1, nz_dest
342  if (h_dest(k) == 0.) remapped_field(i,j,k) = missing_value
343  enddo
344  endif
345  enddo
346  enddo
347  elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y)) then
348  ! H-points
349  do j=g%jsc, g%jec
350  do i=g%isc, g%iec
351  if (associated(mask)) then
352  if (mask(i,j, 1) == 0.) cycle
353  endif
354  h_dest(:) = remap_cs%h(i,j,:)
355  call remapping_core_h(remap_cs%remap_cs, nz_src, h(i,j,:), field(i,j,:), &
356  nz_dest, h_dest(:), remapped_field(i,j,:))
357  if (mask_vanished_layers) then ! This only works for z-like output
358  do k=1, nz_dest
359  if (h_dest(k)==0.) remapped_field(i,j,k) = missing_value
360  enddo
361  endif
362  enddo
363  enddo
364  else
365  call assert(.false., 'diag_remap_do_remap: Unsupported axis combination')
366  endif
367 
Here is the call graph for this function:

◆ diag_remap_end()

subroutine, public mom_diag_remap::diag_remap_end ( type(diag_remap_ctrl), intent(inout)  remap_cs)

De-init a diagnostic remapping type. Free allocated memory.

Parameters
[in,out]remap_csDiag remapping control structure

Definition at line 98 of file MOM_diag_remap.F90.

Referenced by diag_remap_diag_registration_closed().

98  type(diag_remap_ctrl), intent(inout) :: remap_cs !< Diag remapping control structure
99 
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.
105  remap_cs%nz = 0
106 
Here is the caller graph for this function:

◆ diag_remap_get_axes_info()

subroutine, public mom_diag_remap::diag_remap_get_axes_info ( type(diag_remap_ctrl), intent(in)  remap_cs,
integer, intent(out)  nz,
integer, intent(out)  id_layer,
integer, intent(out)  id_interface 
)

Get layer and interface axes ids for this coordinate Needed when defining axes groups.

Parameters
[in]remap_csDiagnostic coordinate control structure
[out]nzNumber of vertical levels for the coordinate
[out]id_layer1D-axes id for layer points
[out]id_interface1D-axes id for interface points

Definition at line 194 of file MOM_diag_remap.F90.

194  type(diag_remap_ctrl), intent(in) :: remap_cs !< Diagnostic coordinate control structure
195  integer, intent(out) :: nz !< Number of vertical levels for the coordinate
196  integer, intent(out) :: id_layer !< 1D-axes id for layer points
197  integer, intent(out) :: id_interface !< 1D-axes id for interface points
198 
199  nz = remap_cs%nz
200  id_layer = remap_cs%layer_axes_id
201  id_interface = remap_cs%interface_axes_id
202 

◆ diag_remap_init()

subroutine, public mom_diag_remap::diag_remap_init ( type(diag_remap_ctrl), intent(inout)  remap_cs,
character(len=*), intent(in)  coord_tuple 
)

Initialize a diagnostic remapping type with the given vertical coordinate.

Parameters
[in,out]remap_csDiag remapping control structure
[in]coord_tupleA string in form of MODULE_SUFFIX PARAMETER_SUFFIX COORDINATE_NAME

Definition at line 80 of file MOM_diag_remap.F90.

References regrid_consts::coordinatemode(), and mom_string_functions::extractword().

80  type(diag_remap_ctrl), intent(inout) :: remap_cs !< Diag remapping control structure
81  character(len=*), intent(in) :: coord_tuple !< A string in form of
82  !! MODULE_SUFFIX PARAMETER_SUFFIX COORDINATE_NAME
83 
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.
91  remap_cs%nz = 0
92 
Here is the call graph for this function:

◆ diag_remap_set_active()

subroutine, public mom_diag_remap::diag_remap_set_active ( type(diag_remap_ctrl), intent(inout)  remap_cs)

Indicate that this remapping type is actually used by the diag manager. If this is never called then the type will be disabled to save time. See further explanation with diag_remap_registration_closed.

Parameters
[in,out]remap_csDiag remapping control structure

Definition at line 127 of file MOM_diag_remap.F90.

127  type(diag_remap_ctrl), intent(inout) :: remap_cs !< Diag remapping control structure
128 
129  remap_cs%used = .true.
130 

◆ diag_remap_update()

subroutine, public mom_diag_remap::diag_remap_update ( type(diag_remap_ctrl), intent(inout)  remap_cs,
type(ocean_grid_type), pointer  G,
real, dimension(:, :, :), intent(in)  h,
real, dimension(:, :, :), intent(in)  T,
real, dimension(:, :, :), intent(in)  S,
type(eos_type), intent(in), pointer  eqn_of_state 
)

Build/update target vertical grids for diagnostic remapping.

Note
The target grids need to be updated whenever sea surface height or layer thicknesses changes. In the case of density-based coordinates then technically we should also regenerate the target grid whenever T/S change.
Parameters
[in,out]remap_csDiagnostic coordinate control structure
gThe ocean's grid type
[in]sNew thickness, T and S
[in]eqn_of_stateA pointer to the equation of state

Definition at line 223 of file MOM_diag_remap.F90.

References coord_rho::build_rho_column(), coord_sigma::build_sigma_column(), coord_zlike::build_zstar_column(), regrid_consts::coordinatemode(), mom_regridding::get_rho_cs(), mom_regridding::get_sigma_cs(), mom_regridding::get_zlike_cs(), and mom_error_handler::mom_error().

223  type(diag_remap_ctrl), intent(inout) :: remap_cs !< Diagnostic coordinate control structure
224  type(ocean_grid_type), pointer :: g !< The ocean's grid type
225  real, dimension(:, :, :), intent(in) :: h, t, s !< New thickness, T and S
226  type(eos_type), pointer, intent(in) :: eqn_of_state !< A pointer to the equation of state
227 
228  ! Local variables
229  integer :: i, j, k, nz
230  real, dimension(remap_cs%nz + 1) :: zinterfaces
231  real, dimension(remap_cs%nz) :: resolution
232 
233  ! Note that coordinateMode('LAYER') is never 'configured' so will
234  ! always return here.
235  if (.not. remap_cs%configured) then
236  return
237  endif
238 
239  nz = remap_cs%nz
240 
241  if (.not. remap_cs%initialized) then
242  ! Initialize remapping and regridding on the first call
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.
246  endif
247 
248  ! Calculate remapping thicknesses for different target grids based on
249  ! nominal/target interface locations. This happens for every call on the
250  ! assumption that h, T, S has changed.
251  do j=g%jsd, g%jed
252  do i=g%isd, g%ied
253  if (g%mask2dT(i,j)==0.) then
254  remap_cs%h(i,j,:) = 0.
255  cycle
256  endif
257 
258  if (remap_cs%vertical_coord == coordinatemode('ZSTAR')) then
259  call build_zstar_column(get_zlike_cs(remap_cs%regrid_cs), nz, &
260  g%bathyT(i,j), sum(h(i,j,:)), zinterfaces)
261  elseif (remap_cs%vertical_coord == coordinatemode('SIGMA')) then
262  call build_sigma_column(get_sigma_cs(remap_cs%regrid_cs), nz, &
263  g%bathyT(i,j), sum(h(i,j,:)), zinterfaces)
264  elseif (remap_cs%vertical_coord == coordinatemode('RHO')) then
265  call build_rho_column(get_rho_cs(remap_cs%regrid_cs), remap_cs%remap_cs, nz, &
266  g%bathyT(i,j), h(i,j,:), t(i, j, :), s(i, j, :), &
267  eqn_of_state, zinterfaces)
268  elseif (remap_cs%vertical_coord == coordinatemode('SLIGHT')) then
269 ! call build_slight_column(remap_cs%regrid_cs,remap_cs%remap_cs, nz, &
270 ! G%bathyT(i,j), sum(h(i,j,:)), zInterfaces)
271  call mom_error(fatal,"diag_remap_update: SLIGHT coordinate not coded for diagnostics yet!")
272  elseif (remap_cs%vertical_coord == coordinatemode('HYCOM1')) then
273 ! call build_hycom1_column(remap_cs%regrid_cs, nz, &
274 ! G%bathyT(i,j), sum(h(i,j,:)), zInterfaces)
275  call mom_error(fatal,"diag_remap_update: HYCOM1 coordinate not coded for diagnostics yet!")
276  endif
277  remap_cs%h(i,j,:) = zinterfaces(1:nz) - zinterfaces(2:nz+1)
278  enddo
279  enddo
280 
Here is the call graph for this function:

◆ horizontally_average_diag_field()

subroutine, public mom_diag_remap::horizontally_average_diag_field ( type(ocean_grid_type), intent(in)  G,
real, dimension(:,:,:), intent(in)  h,
logical, intent(in)  staggered_in_x,
logical, intent(in)  staggered_in_y,
logical, intent(in)  is_layer,
logical, intent(in)  is_extensive,
real, intent(in)  missing_value,
real, dimension(:,:,:), intent(in)  field,
real, dimension(:), intent(inout)  averaged_field 
)

Horizontally average field.

Parameters
[in]gOcean grid structure
[in]hThe current thicknesses
[in]staggered_in_xTrue if the x-axis location is at u or q points
[in]staggered_in_yTrue if the y-axis location is at v or q points
[in]is_layerTrue if the z-axis location is at h points
[in]is_extensiveTrue if the z-direction is spatially integrated (over layers)
[in]missing_valueA missing_value to assign land/vanished points
[in]fieldThe diagnostic field to be remapped
[in,out]averaged_fieldField argument horizontally averaged

Definition at line 517 of file MOM_diag_remap.F90.

References mom_error_handler::assert().

Referenced by mom_diag_mediator::post_xy_average().

517  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
518  real, dimension(:,:,:), intent(in) :: h !< The current thicknesses
519  logical, intent(in) :: staggered_in_x !< True if the x-axis location is at u or q points
520  logical, intent(in) :: staggered_in_y !< True if the y-axis location is at v or q points
521  logical, intent(in) :: is_layer !< True if the z-axis location is at h points
522  logical, intent(in) :: is_extensive !< True if the z-direction is spatially integrated (over layers)
523  real, intent(in) :: missing_value !< A missing_value to assign land/vanished points
524  real, dimension(:,:,:), intent(in) :: field !< The diagnostic field to be remapped
525  real, dimension(:), intent(inout) :: averaged_field !< Field argument horizontally averaged
526  ! Local variables
527  real, dimension(size(field, 3)) :: vol_sum, stuff_sum ! nz+1 is needed for interface averages
528  real :: v1, v2, total_volume, total_stuff, val
529  integer :: i, j, k, nz
530 
531  nz = size(field, 3)
532 
533  if (staggered_in_x .and. .not. staggered_in_y) then
534  if (is_layer) then
535  ! U-points
536  do k=1,nz
537  vol_sum(k) = 0.
538  stuff_sum(k) = 0.
539  if (is_extensive) then
540  do j=g%jsc, g%jec ; do i=g%isc, g%iec
541  v1 = g%areaCu(i,j)
542  v2 = g%areaCu(i-1,j)
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)
545  enddo ; enddo
546  else ! Intensive
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)
552  enddo ; enddo
553  endif
554  enddo
555  else ! Interface
556  do k=1,nz
557  vol_sum(k) = 0.
558  stuff_sum(k) = 0.
559  do j=g%jsc, g%jec ; do i=g%isc, g%iec
560  v1 = g%areaCu(i,j)
561  v2 = g%areaCu(i-1,j)
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)
564  enddo ; enddo
565  enddo
566  endif
567  elseif (staggered_in_y .and. .not. staggered_in_x) then
568  if (is_layer) then
569  ! V-points
570  do k=1,nz
571  vol_sum(k) = 0.
572  stuff_sum(k) = 0.
573  if (is_extensive) then
574  do j=g%jsc, g%jec ; do i=g%isc, g%iec
575  v1 = g%areaCv(i,j)
576  v2 = g%areaCv(i,j-1)
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)
579  enddo ; enddo
580  else ! Intensive
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)
586  enddo ; enddo
587  endif
588  enddo
589  else ! Interface
590  do k=1,nz
591  vol_sum(k) = 0.
592  stuff_sum(k) = 0.
593  do j=g%jsc, g%jec ; do i=g%isc, g%iec
594  v1 = g%areaCv(i,j)
595  v2 = g%areaCv(i,j-1)
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)
598  enddo ; enddo
599  enddo
600  endif
601  elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y)) then
602  if (is_layer) then
603  ! H-points
604  do k=1,nz
605  vol_sum(k) = 0.
606  stuff_sum(k) = 0.
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
610  v1 = g%areaT(i,j)
611  vol_sum(k) = vol_sum(k) + v1
612  stuff_sum(k) = stuff_sum(k) + v1 * field(i,j,k)
613  endif
614  enddo ; enddo
615  else ! Intensive
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)
621  endif
622  enddo ; enddo
623  endif
624  enddo
625  else ! Interface
626  do k=1,nz
627  vol_sum(k) = 0.
628  stuff_sum(k) = 0.
629  do j=g%jsc, g%jec ; do i=g%isc, g%iec
630  val = field(i,j,k)
631  if (g%mask2dT(i,j)>0. .and. val/=missing_value) then
632  v1 = g%areaT(i,j)
633  vol_sum(k) = vol_sum(k) + v1
634  stuff_sum(k) = stuff_sum(k) + v1 * field(i,j,k)
635  endif
636  enddo ; enddo
637  enddo
638  endif
639  else
640  call assert(.false., 'horizontally_average_diag_field: Q point averaging is not coded yet.')
641  endif
642 
643  call sum_across_pes(vol_sum, nz)
644  call sum_across_pes(stuff_sum, nz)
645 
646  do k=1,nz
647  if (vol_sum(k)>0.) then
648  averaged_field(k) = stuff_sum(k) / vol_sum(k)
649  else
650  averaged_field(k) = missing_value
651  endif
652  enddo
653 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ vertically_interpolate_diag_field()

subroutine, public mom_diag_remap::vertically_interpolate_diag_field ( type(diag_remap_ctrl), intent(in)  remap_cs,
type(ocean_grid_type), intent(in)  G,
real, dimension(:,:,:), intent(in)  h,
logical, intent(in)  staggered_in_x,
logical, intent(in)  staggered_in_y,
real, dimension(:,:,:), pointer  mask,
real, intent(in)  missing_value,
real, dimension(:,:,:), intent(in)  field,
real, dimension(:,:,:), intent(inout)  interpolated_field 
)

Vertically interpolate diagnostic field to alternative vertical grid.

Parameters
[in]remap_csDiagnostic coodinate control structure
[in]gOcean grid structure
[in]hThe current thicknesses
[in]staggered_in_xTrue is the x-axis location is at u or q points
[in]staggered_in_yTrue is the y-axis location is at v or q points
maskA mask for the field
[in]missing_valueA missing_value to assign land/vanished points
[in]fieldThe diagnostic field to be remapped
[in,out]interpolated_fieldField argument remapped to alternative coordinate

Definition at line 444 of file MOM_diag_remap.F90.

References mom_error_handler::assert(), and mom_diag_vkernels::interpolate_column().

444  type(diag_remap_ctrl), intent(in) :: remap_cs !< Diagnostic coodinate control structure
445  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
446  real, dimension(:,:,:), intent(in) :: h !< The current thicknesses
447  logical, intent(in) :: staggered_in_x !< True is the x-axis location is at u or q points
448  logical, intent(in) :: staggered_in_y !< True is the y-axis location is at v or q points
449  real, dimension(:,:,:), pointer :: mask !< A mask for the field
450  real, intent(in) :: missing_value !< A missing_value to assign land/vanished points
451  real, dimension(:,:,:), intent(in) :: field !< The diagnostic field to be remapped
452  real, dimension(:,:,:), intent(inout) :: interpolated_field !< Field argument remapped to alternative coordinate
453  ! Local variables
454  real, dimension(remap_cs%nz) :: h_dest
455  real, dimension(size(h,3)) :: h_src
456  integer :: nz_src, nz_dest
457  integer :: i, j, k
458 
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.')
462 
463  interpolated_field(:,:,:) = missing_value
464 
465  nz_src = size(h,3)
466  nz_dest = remap_cs%nz
467 
468  if (staggered_in_x .and. .not. staggered_in_y) then
469  ! U-points
470  do j=g%jsc, g%jec
471  do i=g%iscB, g%iecB
472  if (associated(mask)) then
473  if (mask(i,j,1) == 0.) cycle
474  endif
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,:) )
477  call interpolate_column(nz_src, h_src, field(i,j,:), &
478  nz_dest, h_dest, missing_value, interpolated_field(i,j,:))
479  enddo
480  enddo
481  elseif (staggered_in_y .and. .not. staggered_in_x) then
482  ! V-points
483  do j=g%jscB, g%jecB
484  do i=g%isc, g%iec
485  if (associated(mask)) then
486  if (mask(i,j,1) == 0.) cycle
487  endif
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,:) )
490  call interpolate_column(nz_src, h_src, field(i,j,:), &
491  nz_dest, h_dest, missing_value, interpolated_field(i,j,:))
492  enddo
493  enddo
494  elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y)) then
495  ! H-points
496  do j=g%jsc, g%jec
497  do i=g%isc, g%iec
498  if (associated(mask)) then
499  if (mask(i,j, 1) == 0.) cycle
500  endif
501  h_src(:) = h(i,j,:)
502  h_dest(:) = remap_cs%h(i,j,:)
503  call interpolate_column(nz_src, h_src, field(i,j,:), &
504  nz_dest, h_dest, missing_value, interpolated_field(i,j,:))
505  enddo
506  enddo
507  else
508  call assert(.false., 'vertically_interpolate_diag_field: Q point remapping is not coded yet.')
509  endif
510 
Here is the call graph for this function:

◆ vertically_reintegrate_diag_field()

subroutine, public mom_diag_remap::vertically_reintegrate_diag_field ( type(diag_remap_ctrl), intent(in)  remap_cs,
type(ocean_grid_type), intent(in)  G,
real, dimension(:,:,:), intent(in)  h,
logical, intent(in)  staggered_in_x,
logical, intent(in)  staggered_in_y,
real, dimension(:,:,:), pointer  mask,
real, intent(in)  missing_value,
real, dimension(:,:,:), intent(in)  field,
real, dimension(:,:,:), intent(inout)  reintegrated_field 
)

Vertically re-grid an already vertically-integrated diagnostic field to alternative vertical grid.

Parameters
[in]remap_csDiagnostic coodinate control structure
[in]gOcean grid structure
[in]hThe current thicknesses
[in]staggered_in_xTrue is the x-axis location is at u or q points
[in]staggered_in_yTrue is the y-axis location is at v or q points
maskA mask for the field
[in]missing_valueA missing_value to assign land/vanished points
[in]fieldThe diagnostic field to be remapped
[in,out]reintegrated_fieldField argument remapped to alternative coordinate

Definition at line 373 of file MOM_diag_remap.F90.

References mom_error_handler::assert(), and mom_diag_vkernels::reintegrate_column().

373  type(diag_remap_ctrl), intent(in) :: remap_cs !< Diagnostic coodinate control structure
374  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
375  real, dimension(:,:,:), intent(in) :: h !< The current thicknesses
376  logical, intent(in) :: staggered_in_x !< True is the x-axis location is at u or q points
377  logical, intent(in) :: staggered_in_y !< True is the y-axis location is at v or q points
378  real, dimension(:,:,:), pointer :: mask !< A mask for the field
379  real, intent(in) :: missing_value !< A missing_value to assign land/vanished points
380  real, dimension(:,:,:), intent(in) :: field !< The diagnostic field to be remapped
381  real, dimension(:,:,:), intent(inout) :: reintegrated_field !< Field argument remapped to alternative coordinate
382  ! Local variables
383  real, dimension(remap_cs%nz) :: h_dest
384  real, dimension(size(h,3)) :: h_src
385  integer :: nz_src, nz_dest
386  integer :: i, j, k
387 
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.')
391 
392  nz_src = size(field,3)
393  nz_dest = remap_cs%nz
394  reintegrated_field(:,:,:) = missing_value
395 
396  if (staggered_in_x .and. .not. staggered_in_y) then
397  ! U-points
398  do j=g%jsc, g%jec
399  do i=g%iscB, g%iecB
400  if (associated(mask)) then
401  if (mask(i,j,1) == 0.) cycle
402  endif
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,:) )
405  call reintegrate_column(nz_src, h_src, field(i,j,:), &
406  nz_dest, h_dest, missing_value, reintegrated_field(i,j,:))
407  enddo
408  enddo
409  elseif (staggered_in_y .and. .not. staggered_in_x) then
410  ! V-points
411  do j=g%jscB, g%jecB
412  do i=g%isc, g%iec
413  if (associated(mask)) then
414  if (mask(i,j,1) == 0.) cycle
415  endif
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,:) )
418  call reintegrate_column(nz_src, h_src, field(i,j,:), &
419  nz_dest, h_dest, missing_value, reintegrated_field(i,j,:))
420  enddo
421  enddo
422  elseif ((.not. staggered_in_x) .and. (.not. staggered_in_y)) then
423  ! H-points
424  do j=g%jsc, g%jec
425  do i=g%isc, g%iec
426  if (associated(mask)) then
427  if (mask(i,j, 1) == 0.) cycle
428  endif
429  h_src(:) = h(i,j,:)
430  h_dest(:) = remap_cs%h(i,j,:)
431  call reintegrate_column(nz_src, h_src, field(i,j,:), &
432  nz_dest, h_dest, missing_value, reintegrated_field(i,j,:))
433  enddo
434  enddo
435  else
436  call assert(.false., 'vertically_reintegrate_diag_field: Q point remapping is not coded yet.')
437  endif
438 
Here is the call graph for this function: