MOM6
mom_diag_mediator Module Reference

Data Types

type  axes_grp
 A group of 1D axes that comprise a 1D/2D/3D mesh. More...
 
type  diag_ctrl
 The following data type a list of diagnostic fields an their variants, as well as variables that control the handling of model output. More...
 
type  diag_type
 This type is used to represent a diagnostic at the diag_mediator level. There can be both 'primary' and 'seconday' diagnostics. The primaries reside in the diag_csdiags array. They have an id which is an index into this array. The secondaries are 'variations' on the primary diagnostic. For example the CMOR diagnostics are secondary. The secondary diagnostics are kept in a list with the primary diagnostic as the head. More...
 
interface  post_data
 

Functions/Subroutines

subroutine, public set_axes_info (G, GV, param_file, diag_cs, set_vertical)
 Sets up diagnostics axes. More...
 
subroutine, public diag_register_area_ids (diag_cs, id_area_t, id_area_q)
 Attaches the id of cell areas to axes groups for use with cell_measures. More...
 
subroutine, public diag_register_volume_ids (diag_cs, id_vol_t)
 Attaches the id of cell volumes to axes groups for use with cell_measures. More...
 
subroutine, public define_axes_group (diag_cs, handles, axes, nz, vertical_coordinate_number, x_cell_method, y_cell_method, v_cell_method, is_h_point, is_q_point, is_u_point, is_v_point, is_layer, is_interface, is_native, needs_remapping, needs_interpolating, xyave_axes)
 Defines a group of "axes" from list of handles. More...
 
subroutine, public set_diag_mediator_grid (G, diag_cs)
 
subroutine post_data_0d (diag_field_id, field, diag_cs, is_static)
 
subroutine, public post_data_1d_k (diag_field_id, field, diag_cs, is_static)
 
subroutine post_data_2d (diag_field_id, field, diag_cs, is_static, mask)
 
subroutine post_data_2d_low (diag, field, diag_cs, is_static, mask)
 
subroutine post_data_3d (diag_field_id, field, diag_cs, is_static, mask, alt_h)
 
subroutine post_data_3d_low (diag, field, diag_cs, is_static, mask)
 
subroutine post_xy_average (diag_cs, diag, field)
 Post the horizontally area-averaged diagnostic. More...
 
subroutine, public enable_averaging (time_int_in, time_end_in, diag_cs)
 
subroutine, public disable_averaging (diag_cs)
 
logical function, public query_averaging_enabled (diag_cs, time_int, time_end)
 
type(time_type) function, public get_diag_time_end (diag_cs)
 
integer function, public register_diag_field (module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, cell_methods, x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
 Returns the "diag_mediator" handle for a group (native, CMOR, z-coord, ...) of diagnostics derived from one field. More...
 
logical function register_diag_field_expand_cmor (dm_id, module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, cell_methods, x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
 Returns True if either the native of CMOr version of the diagnostic were registered. Updates 'dm_id' after calling register_diag_field_expand_axes() for both native and CMOR variants of the field. More...
 
integer function register_diag_field_expand_axes (module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count)
 Returns an FMS id from register_diag_field_fms (the diag_manager routine) after expanding axes (axes-group) into handles and conditionally adding an FMS area_id for cell_measures. More...
 
subroutine add_diag_to_list (diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
 Create a diagnostic type and attached to list. More...
 
subroutine attach_cell_methods (id, axes, ostring, cell_methods, x_cell_method, y_cell_method, v_cell_method, v_extensive)
 Attaches "cell_methods" attribute to a variable based on defaults for axes_grp or optional arguments. More...
 
integer function, public register_scalar_field (module_name, field_name, init_time, diag_cs, long_name, units, missing_value, range, standard_name, do_not_log, err_msg, interp_method, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name)
 
integer function, public register_static_field (module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, do_not_log, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, area)
 Registers a static diagnostic, returning an integer handle. More...
 
subroutine describe_option (opt_name, value, diag_CS)
 
integer function, public ocean_register_diag (var_desc, G, diag_CS, day)
 Registers a diagnostic using the information encapsulated in the vardesc type argument and returns an integer handle to this diagostic. That integer handle is negative if the diagnostic is unused. More...
 
subroutine, public diag_mediator_infrastructure_init (err_msg)
 
subroutine, public diag_mediator_init (G, nz, param_file, diag_cs, doc_file_dir)
 diag_mediator_init initializes the MOM diag_mediator and opens the available diagnostics file, if appropriate. More...
 
subroutine, public diag_set_state_ptrs (h, T, S, eqn_of_state, diag_cs)
 
subroutine, public diag_update_remap_grids (diag_cs, alt_h)
 Build/update vertical grids for diagnostic remapping. More...
 
subroutine, public diag_masks_set (G, nz, missing_value, diag_cs)
 diag_masks_set sets up the 2d and 3d masks for diagnostics More...
 
subroutine, public diag_mediator_close_registration (diag_CS)
 
subroutine, public diag_mediator_end (time, diag_CS, end_diag_manager)
 
character(len=15) function i2s (a, n_in)
 
subroutine set_diag_mask (diag, diag_cs, axes)
 Associates the mask pointers within diag with the appropriate mask based on the axes group. More...
 
integer function get_new_diag_id (diag_cs)
 Returns a new diagnostic id, it may be necessary to expand the diagnostics array. More...
 
subroutine initialize_diag_type (diag)
 Initializes a diag_type (used after allocating new memory) More...
 
subroutine alloc_diag_with_id (diag_id, diag_cs, diag)
 
subroutine log_available_diag (used, module_name, field_name, cell_methods_string, comment, diag_CS, long_name, units, standard_name)
 Log a diagnostic to the available diagnostics file. More...
 

Variables

integer id_clock_diag_mediator
 
integer id_clock_diag_remap
 
integer id_clock_diag_grid_updates
 

Function/Subroutine Documentation

◆ add_diag_to_list()

subroutine mom_diag_mediator::add_diag_to_list ( type(diag_ctrl), pointer  diag_cs,
integer, intent(inout)  dm_id,
integer, intent(in)  fms_id,
type(diag_type), pointer  this_diag,
type(axes_grp), intent(in), target  axes,
character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  msg 
)
private

Create a diagnostic type and attached to list.

Parameters
diag_csDiagnostics mediator control structure
[in,out]dm_idThe diag_mediator ID for this diagnostic group
[in]fms_idThe FMS diag_manager ID for this diagnostic
this_diagThis diagnostic
[in]axesContainer w/ up to 3 integer handles that indicates axes for this field
[in]module_nameName of this module, usually "ocean_model" or "ice_shelf_model"
[in]field_nameName of diagnostic
[in]msgMessage for errors

Definition at line 1371 of file MOM_diag_mediator.F90.

References alloc_diag_with_id(), mom_error_handler::assert(), get_new_diag_id(), and set_diag_mask().

Referenced by register_diag_field_expand_cmor().

1371  type(diag_ctrl), pointer :: diag_cs !< Diagnostics mediator control structure
1372  integer, intent(inout) :: dm_id !< The diag_mediator ID for this diagnostic group
1373  integer, intent(in) :: fms_id !< The FMS diag_manager ID for this diagnostic
1374  type(diag_type), pointer :: this_diag !< This diagnostic
1375  type(axes_grp), target, intent(in) :: axes !< Container w/ up to 3 integer handles that indicates axes for this field
1376  character(len=*), intent(in) :: module_name !< Name of this module, usually "ocean_model" or "ice_shelf_model"
1377  character(len=*), intent(in) :: field_name !< Name of diagnostic
1378  character(len=*), intent(in) :: msg !< Message for errors
1379 
1380  ! If the diagnostic is needed obtain a diag_mediator ID (if needed)
1381  if (dm_id == -1) dm_id = get_new_diag_id(diag_cs)
1382  ! Create a new diag_type to store links in
1383  call alloc_diag_with_id(dm_id, diag_cs, this_diag)
1384  call assert(associated(this_diag), trim(msg)//': diag_type allocation failed')
1385  ! Record FMS id, masks and conversion factor, in diag_type
1386  this_diag%fms_diag_id = fms_id
1387  this_diag%debug_str = trim(module_name)//"-"//trim(field_name)
1388  call set_diag_mask(this_diag, diag_cs, axes)
1389  this_diag%axes => axes
1390 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ alloc_diag_with_id()

subroutine mom_diag_mediator::alloc_diag_with_id ( integer, intent(in)  diag_id,
type(diag_ctrl), intent(inout), target  diag_cs,
type(diag_type), intent(out), pointer  diag 
)
private

Definition at line 2211 of file MOM_diag_mediator.F90.

Referenced by add_diag_to_list(), register_scalar_field(), and register_static_field().

2211  integer, intent(in) :: diag_id
2212  type(diag_ctrl), target, intent(inout) :: diag_cs
2213  type(diag_type), pointer, intent(out) :: diag
2214 
2215  ! Arguments:
2216  ! (in) diag_id - new id for the diag.
2217  ! (inout) diag_cs - structure used to regulate diagnostic output
2218  ! (inout) diag - structure representing a diagnostic
2219 
2220  type(diag_type), pointer :: tmp
2221 
2222  if (.not. diag_cs%diags(diag_id)%in_use) then
2223  diag => diag_cs%diags(diag_id)
2224  else
2225  allocate(diag)
2226  tmp => diag_cs%diags(diag_id)%next
2227  diag_cs%diags(diag_id)%next => diag
2228  diag%next => tmp
2229  endif
2230  diag%in_use = .true.
2231 
Here is the caller graph for this function:

◆ attach_cell_methods()

subroutine mom_diag_mediator::attach_cell_methods ( integer, intent(in)  id,
type(axes_grp), intent(in)  axes,
character(len=*), intent(out)  ostring,
character(len=*), intent(in), optional  cell_methods,
character(len=*), intent(in), optional  x_cell_method,
character(len=*), intent(in), optional  y_cell_method,
character(len=*), intent(in), optional  v_cell_method,
logical, intent(in), optional  v_extensive 
)
private

Attaches "cell_methods" attribute to a variable based on defaults for axes_grp or optional arguments.

Parameters
[in]idHandle to diagnostic
[in]axesContainer w/ up to 3 integer handles that indicates axes for this field
[out]ostringThe cell_methods strings that would appear in the file
[in]cell_methodsString to append as cell_methods attribute. Use '' to have no attribute. If present, this overrides the default constructed from the default for each individual axis direction.
[in]x_cell_methodSpecifies the cell method for the x-direction. Use '' have no method.
[in]y_cell_methodSpecifies the cell method for the y-direction. Use '' have no method.
[in]v_cell_methodSpecifies the cell method for the vertical direction. Use '' have no method.
[in]v_extensiveTrue for vertically extensive fields (vertically integrated). Default/absent for intensive.

Definition at line 1396 of file MOM_diag_mediator.F90.

References mom_error_handler::mom_error().

Referenced by register_diag_field_expand_cmor().

1396  integer, intent(in) :: id !< Handle to diagnostic
1397  type(axes_grp), intent(in) :: axes !< Container w/ up to 3 integer handles that indicates axes for this field
1398  character(len=*), intent(out) :: ostring !< The cell_methods strings that would appear in the file
1399  character(len=*), optional, intent(in) :: cell_methods !< String to append as cell_methods attribute. Use '' to have no attribute.
1400  !! If present, this overrides the default constructed from the default for
1401  !! each individual axis direction.
1402  character(len=*), optional, intent(in) :: x_cell_method !< Specifies the cell method for the x-direction. Use '' have no method.
1403  character(len=*), optional, intent(in) :: y_cell_method !< Specifies the cell method for the y-direction. Use '' have no method.
1404  character(len=*), optional, intent(in) :: v_cell_method !< Specifies the cell method for the vertical direction. Use '' have no method.
1405  logical, optional, intent(in) :: v_extensive !< True for vertically extensive fields (vertically integrated). Default/absent for intensive.
1406  ! Local variables
1407  character(len=9) :: axis_name
1408 
1409  ostring = ''
1410  if (present(cell_methods)) then
1411  if (present(x_cell_method) .or. present(y_cell_method) .or. present(v_cell_method) &
1412  .or. present(v_extensive)) then
1413  call mom_error(fatal, "attach_cell_methods: " // &
1414  'Individual direction cell method was specified along with a "cell_methods" string.')
1415  endif
1416  if (len(trim(cell_methods))>0) then
1417  call diag_field_add_attribute(id, 'cell_methods', trim(cell_methods))
1418  ostring = trim(cell_methods)
1419  endif
1420  else
1421  if (present(x_cell_method)) then
1422  if (len(trim(x_cell_method))>0) then
1423  call get_diag_axis_name(axes%handles(1), axis_name)
1424  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':'//trim(x_cell_method))
1425  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':'//trim(x_cell_method)
1426  endif
1427  else
1428  if (len(trim(axes%x_cell_method))>0) then
1429  call get_diag_axis_name(axes%handles(1), axis_name)
1430  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':'//trim(axes%x_cell_method))
1431  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':'//trim(axes%x_cell_method)
1432  endif
1433  endif
1434  if (present(y_cell_method)) then
1435  if (len(trim(y_cell_method))>0) then
1436  call get_diag_axis_name(axes%handles(2), axis_name)
1437  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':'//trim(y_cell_method))
1438  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':'//trim(y_cell_method)
1439  endif
1440  else
1441  if (len(trim(axes%y_cell_method))>0) then
1442  call get_diag_axis_name(axes%handles(2), axis_name)
1443  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':'//trim(axes%y_cell_method))
1444  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':'//trim(axes%y_cell_method)
1445  endif
1446  endif
1447  if (present(v_cell_method)) then
1448  if (present(v_extensive)) call mom_error(fatal, "attach_cell_methods: " // &
1449  'Vertical cell method was specified along with the vertically extensive flag.')
1450  if (len(trim(v_cell_method))>0) then
1451  if (axes%rank==1) then
1452  call get_diag_axis_name(axes%handles(1), axis_name)
1453  elseif (axes%rank==3) then
1454  call get_diag_axis_name(axes%handles(3), axis_name)
1455  endif
1456  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':'//trim(v_cell_method))
1457  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':'//trim(v_cell_method)
1458  endif
1459  elseif (present(v_extensive)) then
1460  if (axes%rank==1) then
1461  call get_diag_axis_name(axes%handles(1), axis_name)
1462  elseif (axes%rank==3) then
1463  call get_diag_axis_name(axes%handles(3), axis_name)
1464  endif
1465  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':sum')
1466  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':sum'
1467  else
1468  if (len(trim(axes%v_cell_method))>0) then
1469  if (axes%rank==1) then
1470  call get_diag_axis_name(axes%handles(1), axis_name)
1471  elseif (axes%rank==3) then
1472  call get_diag_axis_name(axes%handles(3), axis_name)
1473  endif
1474  call diag_field_add_attribute(id, 'cell_methods', trim(axis_name)//':'//trim(axes%v_cell_method))
1475  ostring = trim(adjustl(ostring))//' '//trim(axis_name)//':'//trim(axes%v_cell_method)
1476  endif
1477  endif
1478  endif
1479  ostring = adjustl(ostring)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ define_axes_group()

subroutine, public mom_diag_mediator::define_axes_group ( type(diag_ctrl), intent(in), target  diag_cs,
integer, dimension(:), intent(in)  handles,
type(axes_grp), intent(out)  axes,
integer, intent(in), optional  nz,
integer, intent(in), optional  vertical_coordinate_number,
character(len=*), intent(in), optional  x_cell_method,
character(len=*), intent(in), optional  y_cell_method,
character(len=*), intent(in), optional  v_cell_method,
logical, intent(in), optional  is_h_point,
logical, intent(in), optional  is_q_point,
logical, intent(in), optional  is_u_point,
logical, intent(in), optional  is_v_point,
logical, intent(in), optional  is_layer,
logical, intent(in), optional  is_interface,
logical, intent(in), optional  is_native,
logical, intent(in), optional  needs_remapping,
logical, intent(in), optional  needs_interpolating,
type(axes_grp), optional, target  xyave_axes 
)

Defines a group of "axes" from list of handles.

Parameters
[in]diag_csDiagnostics control structure
[in]handlesA list of 1D axis handles
[out]axesThe group of 1D axes
[in]nzNumber of layers in this diagnostic grid
[in]vertical_coordinate_numberIndex number for vertical coordinate
[in]x_cell_methodA x-direction cell method used to construct the "cell_methods" attribute in CF convention
[in]y_cell_methodA y-direction cell method used to construct the "cell_methods" attribute in CF convention
[in]v_cell_methodA vertical direction cell method used to construct the "cell_methods" attribute in CF convention
[in]is_h_pointIf true, indicates this axes group for h-point located fields
[in]is_q_pointIf true, indicates this axes group for q-point located fields
[in]is_u_pointIf true, indicates this axes group for u-point located fields
[in]is_v_pointIf true, indicates this axes group for v-point located fields
[in]is_layerIf true, indicates that this axes group is for a layer vertically-located field.
[in]is_interfaceIf true, indicates that this axes group is for an interface vertically-located field.
[in]is_nativeIf true, indicates that this axes group is for a native model grid. False for any other grid.
[in]needs_remappingIf true, indicates that this axes group is for a intensive layer-located field that must be remapped to these axes. Used for rank>2.
[in]needs_interpolatingIf true, indicates that this axes group is for a sampled interface-located field that must be interpolated to these axes. Used for rank>2.
xyave_axesThe corresponding axes group for horizontally area-average diagnostics

Definition at line 434 of file MOM_diag_mediator.F90.

References i2s(), and mom_error_handler::mom_error().

Referenced by set_axes_info().

434  type(diag_ctrl), target, intent(in) :: diag_cs !< Diagnostics control structure
435  integer, dimension(:), intent(in) :: handles !< A list of 1D axis handles
436  type(axes_grp), intent(out) :: axes !< The group of 1D axes
437  integer, optional, intent(in) :: nz !< Number of layers in this diagnostic grid
438  integer, optional, intent(in) :: vertical_coordinate_number !< Index number for vertical coordinate
439  character(len=*), optional, intent(in) :: x_cell_method !< A x-direction cell method used to construct the "cell_methods" attribute in CF convention
440  character(len=*), optional, intent(in) :: y_cell_method !< A y-direction cell method used to construct the "cell_methods" attribute in CF convention
441  character(len=*), optional, intent(in) :: v_cell_method !< A vertical direction cell method used to construct the "cell_methods" attribute in CF convention
442  logical, optional, intent(in) :: is_h_point !< If true, indicates this axes group for h-point located fields
443  logical, optional, intent(in) :: is_q_point !< If true, indicates this axes group for q-point located fields
444  logical, optional, intent(in) :: is_u_point !< If true, indicates this axes group for u-point located fields
445  logical, optional, intent(in) :: is_v_point !< If true, indicates this axes group for v-point located fields
446  logical, optional, intent(in) :: is_layer !< If true, indicates that this axes group is for a layer vertically-located field.
447  logical, optional, intent(in) :: is_interface !< If true, indicates that this axes group is for an interface vertically-located field.
448  logical, optional, intent(in) :: is_native !< If true, indicates that this axes group is for a native model grid. False for any other grid.
449  logical, optional, intent(in) :: needs_remapping !< If true, indicates that this axes group is for a intensive layer-located field
450  !! that must be remapped to these axes. Used for rank>2.
451  logical, optional, intent(in) :: needs_interpolating !< If true, indicates that this axes group is for a sampled interface-located field
452  !! that must be interpolated to these axes. Used for rank>2.
453  type(axes_grp), optional, target :: xyave_axes !< The corresponding axes group for horizontally area-average diagnostics
454  ! Local variables
455  integer :: n
456 
457  n = size(handles)
458  if (n<1 .or. n>3) call mom_error(fatal, "define_axes_group: wrong size for list of handles!")
459  allocate( axes%handles(n) )
460  axes%id = i2s(handles, n) ! Identifying string
461  axes%rank = n
462  axes%handles(:) = handles(:)
463  axes%diag_cs => diag_cs ! A [circular] link back to the diag_cs structure
464  if (present(x_cell_method)) then
465  if (axes%rank<2) call mom_error(fatal, 'define_axes_group: ' // &
466  'Can not set x_cell_method for rank<2.')
467  axes%x_cell_method = trim(x_cell_method)
468  else
469  axes%x_cell_method = ''
470  endif
471  if (present(y_cell_method)) then
472  if (axes%rank<2) call mom_error(fatal, 'define_axes_group: ' // &
473  'Can not set y_cell_method for rank<2.')
474  axes%y_cell_method = trim(y_cell_method)
475  else
476  axes%y_cell_method = ''
477  endif
478  if (present(v_cell_method)) then
479  if (axes%rank/=1 .and. axes%rank/=3) call mom_error(fatal, 'define_axes_group: ' // &
480  'Can not set v_cell_method for rank<>1 or 3.')
481  axes%v_cell_method = trim(v_cell_method)
482  else
483  axes%v_cell_method = ''
484  endif
485  if (present(nz)) axes%nz = nz
486  if (present(vertical_coordinate_number)) axes%vertical_coordinate_number = vertical_coordinate_number
487  if (present(is_h_point)) axes%is_h_point = is_h_point
488  if (present(is_q_point)) axes%is_q_point = is_q_point
489  if (present(is_u_point)) axes%is_u_point = is_u_point
490  if (present(is_v_point)) axes%is_v_point = is_v_point
491  if (present(is_layer)) axes%is_layer = is_layer
492  if (present(is_interface)) axes%is_interface = is_interface
493  if (present(is_native)) axes%is_native = is_native
494  if (present(needs_remapping)) axes%needs_remapping = needs_remapping
495  if (present(needs_interpolating)) axes%needs_interpolating = needs_interpolating
496  if (present(xyave_axes)) axes%xyave_axes => xyave_axes
497 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ describe_option()

subroutine mom_diag_mediator::describe_option ( character(len=*), intent(in)  opt_name,
character(len=*), intent(in)  value,
type(diag_ctrl), intent(in)  diag_CS 
)
private

Definition at line 1695 of file MOM_diag_mediator.F90.

Referenced by log_available_diag().

1695  character(len=*), intent(in) :: opt_name, value
1696  type(diag_ctrl), intent(in) :: diag_cs
1697 
1698  character(len=240) :: mesg
1699  integer :: len_ind
1700 
1701  len_ind = len_trim(value) ! Add error handling for long values?
1702 
1703  mesg = " ! "//trim(opt_name)//": "//trim(value)
1704  write(diag_cs%doc_unit, '(a)') trim(mesg)
Here is the caller graph for this function:

◆ diag_masks_set()

subroutine, public mom_diag_mediator::diag_masks_set ( type(ocean_grid_type), intent(in), target  G,
integer, intent(in)  nz,
real, intent(in)  missing_value,
type(diag_ctrl), pointer  diag_cs 
)

diag_masks_set sets up the 2d and 3d masks for diagnostics

Parameters
[in]gThe ocean grid type.
[in]nzThe number of layers in the model's native grid.
[in]missing_valueA value to use for masked points.
diag_csA pointer to a type with many variables used for diagnostics

Definition at line 2002 of file MOM_diag_mediator.F90.

Referenced by mom::initialize_mom().

2002  type(ocean_grid_type), target, intent(in) :: g !< The ocean grid type.
2003  integer, intent(in) :: nz !< The number of layers in the model's native grid.
2004  real, intent(in) :: missing_value !< A value to use for masked points.
2005  type(diag_ctrl), pointer :: diag_cs !< A pointer to a type with many variables
2006  !! used for diagnostics
2007  ! Local variables
2008  integer :: k
2009 
2010  diag_cs%mask2dT => g%mask2dT
2011  diag_cs%mask2dBu=> g%mask2dBu
2012  diag_cs%mask2dCu=> g%mask2dCu
2013  diag_cs%mask2dCv=> g%mask2dCv
2014  allocate(diag_cs%mask3dTL(g%isd:g%ied,g%jsd:g%jed,1:nz))
2015  allocate(diag_cs%mask3dBL(g%IsdB:g%IedB,g%JsdB:g%JedB,1:nz))
2016  allocate(diag_cs%mask3dCuL(g%IsdB:g%IedB,g%jsd:g%jed,1:nz))
2017  allocate(diag_cs%mask3dCvL(g%isd:g%ied,g%JsdB:g%JedB,1:nz))
2018  do k=1,nz
2019  diag_cs%mask3dTL(:,:,k) = diag_cs%mask2dT (:,:)
2020  diag_cs%mask3dBL(:,:,k) = diag_cs%mask2dBu(:,:)
2021  diag_cs%mask3dCuL(:,:,k) = diag_cs%mask2dCu(:,:)
2022  diag_cs%mask3dCvL(:,:,k) = diag_cs%mask2dCv(:,:)
2023  enddo
2024  allocate(diag_cs%mask3dTi(g%isd:g%ied,g%jsd:g%jed,1:nz+1))
2025  allocate(diag_cs%mask3dBi(g%IsdB:g%IedB,g%JsdB:g%JedB,1:nz+1))
2026  allocate(diag_cs%mask3dCui(g%IsdB:g%IedB,g%jsd:g%jed,1:nz+1))
2027  allocate(diag_cs%mask3dCvi(g%isd:g%ied,g%JsdB:g%JedB,1:nz+1))
2028  do k=1,nz+1
2029  diag_cs%mask3dTi(:,:,k) = diag_cs%mask2dT (:,:)
2030  diag_cs%mask3dBi(:,:,k) = diag_cs%mask2dBu(:,:)
2031  diag_cs%mask3dCui(:,:,k) = diag_cs%mask2dCu(:,:)
2032  diag_cs%mask3dCvi(:,:,k) = diag_cs%mask2dCv(:,:)
2033  enddo
2034 
2035 ! diag_cs%missing_value = missing_value
2036 
Here is the caller graph for this function:

◆ diag_mediator_close_registration()

subroutine, public mom_diag_mediator::diag_mediator_close_registration ( type(diag_ctrl), intent(inout)  diag_CS)

Definition at line 2040 of file MOM_diag_mediator.F90.

Referenced by mom_main(), and ocean_model_mod::ocean_model_init().

2040  type(diag_ctrl), intent(inout) :: diag_cs
2041 
2042  integer :: i
2043 
2044  if (diag_cs%doc_unit > -1) then
2045  close(diag_cs%doc_unit) ; diag_cs%doc_unit = -2
2046  endif
2047 
2048  do i=1, diag_cs%num_diag_coords
2049  call diag_remap_diag_registration_closed(diag_cs%diag_remap_cs(i))
2050  enddo
2051 
Here is the caller graph for this function:

◆ diag_mediator_end()

subroutine, public mom_diag_mediator::diag_mediator_end ( type(time_type), intent(in)  time,
type(diag_ctrl), intent(inout)  diag_CS,
logical, intent(in), optional  end_diag_manager 
)
Parameters
[in]end_diag_managerIf true, call diag_manager_end()

Definition at line 2055 of file MOM_diag_mediator.F90.

Referenced by mom_main(), and ocean_model_mod::ocean_model_end().

2055  type(time_type), intent(in) :: time
2056  type(diag_ctrl), intent(inout) :: diag_cs
2057  logical, optional, intent(in) :: end_diag_manager !< If true, call diag_manager_end()
2058 
2059  ! Local variables
2060  integer :: i
2061 
2062  if (diag_cs%doc_unit > -1) then
2063  close(diag_cs%doc_unit) ; diag_cs%doc_unit = -3
2064  endif
2065 
2066  deallocate(diag_cs%diags)
2067 
2068  do i=1, diag_cs%num_diag_coords
2069  call diag_remap_end(diag_cs%diag_remap_cs(i))
2070  enddo
2071 
2072  deallocate(diag_cs%mask3dTL)
2073  deallocate(diag_cs%mask3dBL)
2074  deallocate(diag_cs%mask3dCuL)
2075  deallocate(diag_cs%mask3dCvL)
2076  deallocate(diag_cs%mask3dTi)
2077  deallocate(diag_cs%mask3dBi)
2078  deallocate(diag_cs%mask3dCui)
2079  deallocate(diag_cs%mask3dCvi)
2080 
2081 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
2082  deallocate(diag_cs%h_old)
2083 #endif
2084 
2085  if (present(end_diag_manager)) then
2086  if (end_diag_manager) call diag_manager_end(time)
2087  endif
2088 
Here is the caller graph for this function:

◆ diag_mediator_infrastructure_init()

subroutine, public mom_diag_mediator::diag_mediator_infrastructure_init ( character(len=*), intent(out), optional  err_msg)

Definition at line 1814 of file MOM_diag_mediator.F90.

1814  ! This subroutine initializes the FMS diag_manager.
1815  character(len=*), optional, intent(out) :: err_msg
1816 
1817  call diag_manager_init(err_msg=err_msg)

◆ diag_mediator_init()

subroutine, public mom_diag_mediator::diag_mediator_init ( type(ocean_grid_type), intent(inout), target  G,
integer, intent(in)  nz,
type(param_file_type), intent(in)  param_file,
type(diag_ctrl), intent(inout)  diag_cs,
character(len=*), intent(in), optional  doc_file_dir 
)

diag_mediator_init initializes the MOM diag_mediator and opens the available diagnostics file, if appropriate.

Parameters
[in,out]gThe ocean grid type.
[in]nzThe number of layers in the model's native grid.
[in]param_fileParameter file structure
[in,out]diag_csA pointer to a type with many variables used for diagnostics
[in]doc_file_dirA directory in which to create the file

Definition at line 1823 of file MOM_diag_mediator.F90.

References id_clock_diag_grid_updates, id_clock_diag_mediator, id_clock_diag_remap, initialize_diag_type(), mom_error_handler::is_root_pe(), and mom_error_handler::mom_error().

1823  type(ocean_grid_type), target, intent(inout) :: g !< The ocean grid type.
1824  integer, intent(in) :: nz !< The number of layers in the model's native grid.
1825  type(param_file_type), intent(in) :: param_file !< Parameter file structure
1826  type(diag_ctrl), intent(inout) :: diag_cs !< A pointer to a type with many variables
1827  !! used for diagnostics
1828  character(len=*), optional, intent(in) :: doc_file_dir !< A directory in which to create the
1829  !! file
1830 
1831  ! This subroutine initializes the diag_mediator and the diag_manager.
1832  ! The grid type should have its dimensions set by this point, but it
1833  ! is not necessary that the metrics and axis labels be set up yet.
1834  integer :: ios, i, new_unit
1835  logical :: opened, new_file
1836  character(len=8) :: this_pe
1837  character(len=240) :: doc_file, doc_file_dflt, doc_path
1838  character(len=240), allocatable :: diag_coords(:)
1839 ! This include declares and sets the variable "version".
1840 #include "version_variable.h"
1841  character(len=40) :: mod = "MOM_diag_mediator" ! This module's name.
1842 
1843  id_clock_diag_mediator = cpu_clock_id('(Ocean diagnostics framework)', grain=clock_module)
1844  id_clock_diag_remap = cpu_clock_id('(Ocean diagnostics remapping)', grain=clock_routine)
1845  id_clock_diag_grid_updates = cpu_clock_id('(Ocean diagnostics grid updates)', grain=clock_routine)
1846 
1847  ! Allocate and initialize list of all diagnostics (and variants)
1848  allocate(diag_cs%diags(diag_alloc_chunk_size))
1849  diag_cs%next_free_diag_id = 1
1850  do i=1, diag_alloc_chunk_size
1851  call initialize_diag_type(diag_cs%diags(i))
1852  enddo
1853 
1854  ! Read all relevant parameters and write them to the model log.
1855  call log_version(param_file, mod, version, "")
1856 
1857  call get_param(param_file, mod, 'NUM_DIAG_COORDS', diag_cs%num_diag_coords, &
1858  'The number of diagnostic vertical coordinates to use.\n'//&
1859  'For each coordinate, an entry in DIAG_COORDS must be provided.', &
1860  default=1)
1861  if (diag_cs%num_diag_coords>0) then
1862  allocate(diag_coords(diag_cs%num_diag_coords))
1863  if (diag_cs%num_diag_coords==1) then ! The default is to provide just one instance of Z*
1864  call get_param(param_file, mod, 'DIAG_COORDS', diag_coords, &
1865  'A list of string tuples associating diag_table modules to\n'//&
1866  'a coordinate definition used for diagnostics. Each string\n'//&
1867  'is of the form "MODULE_SUFFIX PARAMETER_SUFFIX COORDINATE_NAME".', &
1868  default='z Z ZSTAR')
1869  else ! If using more than 1 diagnostic coordinate, all must be explicitly defined
1870  call get_param(param_file, mod, 'DIAG_COORDS', diag_coords, &
1871  'A list of string tuples associating diag_table modules to\n'//&
1872  'a coordinate definition used for diagnostics. Each string\n'//&
1873  'is of the form "MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME".', &
1874  fail_if_missing=.true.)
1875  endif
1876  allocate(diag_cs%diag_remap_cs(diag_cs%num_diag_coords))
1877  ! Initialize each diagnostic vertical coordinate
1878  do i=1, diag_cs%num_diag_coords
1879  call diag_remap_init(diag_cs%diag_remap_cs(i), diag_coords(i))
1880  enddo
1881  deallocate(diag_coords)
1882  endif
1883 
1884  call get_param(param_file, mod, 'DIAG_MISVAL', diag_cs%missing_value, &
1885  'Set the default missing value to use for diagnostics.', &
1886  default=-1.e34)
1887 
1888  ! Keep pointers grid, h, T, S needed diagnostic remapping
1889  diag_cs%G => g
1890  diag_cs%h => null()
1891  diag_cs%T => null()
1892  diag_cs%S => null()
1893  diag_cs%eqn_of_state => null()
1894 
1895 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
1896  allocate(diag_cs%h_old(g%isd:g%ied,g%jsd:g%jed,nz))
1897  diag_cs%h_old(:,:,:) = 0.0
1898 #endif
1899 
1900  diag_cs%is = g%isc - (g%isd-1) ; diag_cs%ie = g%iec - (g%isd-1)
1901  diag_cs%js = g%jsc - (g%jsd-1) ; diag_cs%je = g%jec - (g%jsd-1)
1902  diag_cs%isd = g%isd ; diag_cs%ied = g%ied
1903  diag_cs%jsd = g%jsd ; diag_cs%jed = g%jed
1904 
1905  if (is_root_pe() .and. (diag_cs%doc_unit < 0)) then
1906  write(this_pe,'(i6.6)') pe_here()
1907  doc_file_dflt = "available_diags."//this_pe
1908  call get_param(param_file, mod, "AVAILABLE_DIAGS_FILE", doc_file, &
1909  "A file into which to write a list of all available \n"//&
1910  "ocean diagnostics that can be included in a diag_table.", &
1911  default=doc_file_dflt, do_not_log=(diag_cs%doc_unit/=-1))
1912  if (len_trim(doc_file) > 0) then
1913  new_file = .true. ; if (diag_cs%doc_unit /= -1) new_file = .false.
1914  ! Find an unused unit number.
1915  do new_unit=512,42,-1
1916  inquire( new_unit, opened=opened)
1917  if (.not.opened) exit
1918  enddo
1919  if (opened) call mom_error(fatal, &
1920  "diag_mediator_init failed to find an unused unit number.")
1921 
1922  doc_path = doc_file
1923  if (present(doc_file_dir)) then ; if (len_trim(doc_file_dir) > 0) then
1924  doc_path = trim(slasher(doc_file_dir))//trim(doc_file)
1925  endif ; endif
1926 
1927  diag_cs%doc_unit = new_unit
1928 
1929  if (new_file) then
1930  open(diag_cs%doc_unit, file=trim(doc_path), access='SEQUENTIAL', form='FORMATTED', &
1931  action='WRITE', status='REPLACE', iostat=ios)
1932  else ! This file is being reopened, and should be appended.
1933  open(diag_cs%doc_unit, file=trim(doc_path), access='SEQUENTIAL', form='FORMATTED', &
1934  action='WRITE', status='OLD', position='APPEND', iostat=ios)
1935  endif
1936  inquire(diag_cs%doc_unit, opened=opened)
1937  if ((.not.opened) .or. (ios /= 0)) then
1938  call mom_error(fatal, "Failed to open available diags file "//trim(doc_path)//".")
1939  endif
1940  endif
1941  endif
1942 
Here is the call graph for this function:

◆ diag_register_area_ids()

subroutine, public mom_diag_mediator::diag_register_area_ids ( type(diag_ctrl), intent(inout)  diag_cs,
integer, intent(in), optional  id_area_t,
integer, intent(in), optional  id_area_q 
)

Attaches the id of cell areas to axes groups for use with cell_measures.

Parameters
[in,out]diag_csDiagnostics control structure
[in]id_area_tDiag_mediator id for area of h-cells
[in]id_area_qDiag_mediator id for area of q-cells

Definition at line 389 of file MOM_diag_mediator.F90.

389  type(diag_ctrl), intent(inout) :: diag_cs !< Diagnostics control structure
390  integer, optional, intent(in) :: id_area_t !< Diag_mediator id for area of h-cells
391  integer, optional, intent(in) :: id_area_q !< Diag_mediator id for area of q-cells
392  ! Local variables
393  integer :: fms_id, i
394  if (present(id_area_t)) then
395  fms_id = diag_cs%diags(id_area_t)%fms_diag_id
396  diag_cs%axesT1%id_area = fms_id
397  diag_cs%axesTi%id_area = fms_id
398  diag_cs%axesTL%id_area = fms_id
399  do i=1, diag_cs%num_diag_coords
400  diag_cs%remap_axesTL(i)%id_area = fms_id
401  ! Note to AJA: why am I not doing TZi too?
402  enddo
403  endif
404  if (present(id_area_q)) then
405  fms_id = diag_cs%diags(id_area_q)%fms_diag_id
406  diag_cs%axesB1%id_area = fms_id
407  diag_cs%axesBi%id_area = fms_id
408  diag_cs%axesBL%id_area = fms_id
409  do i=1, diag_cs%num_diag_coords
410  diag_cs%remap_axesBL(i)%id_area = fms_id
411  enddo
412  endif

◆ diag_register_volume_ids()

subroutine, public mom_diag_mediator::diag_register_volume_ids ( type(diag_ctrl), intent(inout)  diag_cs,
integer, intent(in), optional  id_vol_t 
)

Attaches the id of cell volumes to axes groups for use with cell_measures.

Parameters
[in,out]diag_csDiagnostics control structure
[in]id_vol_tDiag_manager id for volume of h-cells

Definition at line 417 of file MOM_diag_mediator.F90.

References mom_error_handler::mom_error().

417  type(diag_ctrl), intent(inout) :: diag_cs !< Diagnostics control structure
418  integer, optional, intent(in) :: id_vol_t !< Diag_manager id for volume of h-cells
419  ! Local variables
420  integer :: fms_id
421  if (present(id_vol_t)) then
422  fms_id = diag_cs%diags(id_vol_t)%fms_diag_id
423  call mom_error(fatal,"diag_register_volume_ids: not implemented yet!")
424  endif
Here is the call graph for this function:

◆ diag_set_state_ptrs()

subroutine, public mom_diag_mediator::diag_set_state_ptrs ( real, dimension(:,:,:), intent(in), target  h,
real, dimension(:,:,:), intent(in), target  T,
real, dimension(:,:,:), intent(in), target  S,
type(eos_type), intent(in), pointer  eqn_of_state,
type(diag_ctrl), intent(inout)  diag_cs 
)
Parameters
[in]eqn_of_stateEquation of state structure

Definition at line 1946 of file MOM_diag_mediator.F90.

1946 
1947  real, dimension(:,:,:), target, intent(in) :: h, t, s
1948  type(eos_type), pointer, intent(in) :: eqn_of_state !< Equation of state structure
1949  type(diag_ctrl), intent(inout) :: diag_cs
1950 
1951  ! (inout) diag_cs - diag mediator control structure
1952  ! (in) h - a pointer to model thickness
1953  ! (in) T - a pointer to model temperature
1954  ! (in) S - a pointer to model salinity
1955 
1956  ! Keep pointers to h, T, S needed for the diagnostic remapping
1957  diag_cs%h => h
1958  diag_cs%T => t
1959  diag_cs%S => s
1960  diag_cs%eqn_of_state => eqn_of_state
1961 

◆ diag_update_remap_grids()

subroutine, public mom_diag_mediator::diag_update_remap_grids ( type(diag_ctrl), intent(inout)  diag_cs,
real, dimension(:,:,:), intent(in), optional, target  alt_h 
)

Build/update vertical grids for diagnostic remapping.

Note
The target grids need to be updated whenever sea surface height changes.
Parameters
[in,out]diag_csDiagnostics control structure
[in]alt_hUsed if remapped grids should be something other than the current thicknesses

Definition at line 1968 of file MOM_diag_mediator.F90.

References id_clock_diag_grid_updates.

Referenced by mom_bulk_mixed_layer::bulkmixedlayer(), mom_mixed_layer_restrat::mixedlayer_restrat_bml(), mom_mixed_layer_restrat::mixedlayer_restrat_general(), mom_dynamics_split_rk2::step_mom_dyn_split_rk2(), and mom_thickness_diffuse::thickness_diffuse().

1968  type(diag_ctrl), intent(inout) :: diag_cs !< Diagnostics control structure
1969  real, target, optional, intent(in ) :: alt_h(:,:,:) !< Used if remapped grids should be
1970  !! something other than the current
1971  !! thicknesses
1972  ! Local variables
1973  integer :: i
1974  real, dimension(:,:,:), pointer :: h_diag
1975 
1976  if(present(alt_h)) then
1977  h_diag => alt_h
1978  else
1979  h_diag => diag_cs%h
1980  endif
1981 
1982  if (id_clock_diag_grid_updates>0) call cpu_clock_begin(id_clock_diag_grid_updates)
1983 
1984  do i=1, diag_cs%num_diag_coords
1985  call diag_remap_update(diag_cs%diag_remap_cs(i), &
1986  diag_cs%G, h_diag, diag_cs%T, diag_cs%S, &
1987  diag_cs%eqn_of_state)
1988  enddo
1989 
1990 #if defined(DEBUG) || defined(__DO_SAFETY_CHECKS__)
1991  ! Keep a copy of H - used to check whether grids are up-to-date
1992  ! when doing remapping.
1993  diag_cs%h_old(:,:,:) = diag_cs%h(:,:,:)
1994 #endif
1995 
1996  if (id_clock_diag_grid_updates>0) call cpu_clock_end(id_clock_diag_grid_updates)
1997 
Here is the caller graph for this function:

◆ disable_averaging()

subroutine, public mom_diag_mediator::disable_averaging ( type(diag_ctrl), intent(inout)  diag_cs)

Definition at line 1001 of file MOM_diag_mediator.F90.

Referenced by mom_main(), and mom_ice_shelf::shelf_calc_flux().

1001  type(diag_ctrl), intent(inout) :: diag_cs
1002 
1003 ! Argument:
1004 ! diag - structure used to regulate diagnostic output
1005 
1006  diag_cs%time_int = 0.0
1007  diag_cs%ave_enabled = .false.
1008 
Here is the caller graph for this function:

◆ enable_averaging()

subroutine, public mom_diag_mediator::enable_averaging ( real, intent(in)  time_int_in,
type(time_type), intent(in)  time_end_in,
type(diag_ctrl), intent(inout)  diag_cs 
)

Definition at line 980 of file MOM_diag_mediator.F90.

Referenced by mom_barotropic::btstep(), mom_legacy_barotropic::legacy_btstep(), mom_main(), and mom_ice_shelf::shelf_calc_flux().

980  real, intent(in) :: time_int_in
981  type(time_type), intent(in) :: time_end_in
982  type(diag_ctrl), intent(inout) :: diag_cs
983 
984 ! This subroutine enables the accumulation of time averages over the
985 ! specified time interval.
986 
987 ! Arguments:
988 ! (in) time_int_in - time interval in s over which any
989 ! values that are offered are valid.
990 ! (in) time_end_in - end time in s of the valid interval
991 ! (inout) diag - structure used to regulate diagnostic output
992 
993 ! if (num_file==0) return
994  diag_cs%time_int = time_int_in
995  diag_cs%time_end = time_end_in
996  diag_cs%ave_enabled = .true.
Here is the caller graph for this function:

◆ get_diag_time_end()

type(time_type) function, public mom_diag_mediator::get_diag_time_end ( type(diag_ctrl), intent(in)  diag_cs)

Definition at line 1030 of file MOM_diag_mediator.F90.

1030  type(diag_ctrl), intent(in) :: diag_cs
1031  type(time_type) :: get_diag_time_end
1032 
1033 ! Argument:
1034 ! (in) diag - structure used to regulate diagnostic output
1035 
1036 ! This function returns the valid end time for diagnostics that are handled
1037 ! outside of the MOM6 infrastructure, such as via the generic tracer code.
1038 
1039  get_diag_time_end = diag_cs%time_end

◆ get_new_diag_id()

integer function mom_diag_mediator::get_new_diag_id ( type(diag_ctrl), intent(inout)  diag_cs)
private

Returns a new diagnostic id, it may be necessary to expand the diagnostics array.

Parameters
[in,out]diag_csDiagnostics control structure

Definition at line 2165 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), and initialize_diag_type().

Referenced by add_diag_to_list(), register_scalar_field(), and register_static_field().

2165  type(diag_ctrl), intent(inout) :: diag_cs !< Diagnostics control structure
2166  ! Local variables
2167  type(diag_type), dimension(:), allocatable :: tmp
2168  integer :: i
2169 
2170  if (diag_cs%next_free_diag_id > size(diag_cs%diags)) then
2171  call assert(diag_cs%next_free_diag_id - size(diag_cs%diags) == 1, &
2172  'get_new_diag_id: inconsistent diag id')
2173 
2174  ! Increase the size of diag_cs%diags and copy data over.
2175  ! Do not use move_alloc() because it is not supported by Fortran 90
2176  allocate(tmp(size(diag_cs%diags)))
2177  tmp(:) = diag_cs%diags(:)
2178  deallocate(diag_cs%diags)
2179  allocate(diag_cs%diags(size(tmp) + diag_alloc_chunk_size))
2180  diag_cs%diags(1:size(tmp)) = tmp(:)
2181  deallocate(tmp)
2182 
2183  ! Initialize new part of the diag array.
2184  do i=diag_cs%next_free_diag_id, size(diag_cs%diags)
2185  call initialize_diag_type(diag_cs%diags(i))
2186  enddo
2187  endif
2188 
2189  get_new_diag_id = diag_cs%next_free_diag_id
2190  diag_cs%next_free_diag_id = diag_cs%next_free_diag_id + 1
2191 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ i2s()

character(len=15) function mom_diag_mediator::i2s ( integer, dimension(:), intent(in)  a,
integer, intent(in), optional  n_in 
)
private

Definition at line 2092 of file MOM_diag_mediator.F90.

Referenced by define_axes_group().

2092 ! "Convert the first n elements of an integer array to a string."
2093  integer, dimension(:), intent(in) :: a
2094  integer, optional , intent(in) :: n_in
2095  character(len=15) :: i2s
2096 
2097  character(len=15) :: i2s_temp
2098  integer :: i,n
2099 
2100  n=size(a)
2101  if(present(n_in)) n = n_in
2102 
2103  i2s = ''
2104  do i=1,n
2105  write (i2s_temp, '(I4.4)') a(i)
2106  i2s = trim(i2s) //'_'// trim(i2s_temp)
2107  enddo
2108  i2s = adjustl(i2s)
Here is the caller graph for this function:

◆ initialize_diag_type()

subroutine mom_diag_mediator::initialize_diag_type ( type(diag_type), intent(inout)  diag)
private

Initializes a diag_type (used after allocating new memory)

Parameters
[in,out]diagdiag_type to be initialized

Definition at line 2196 of file MOM_diag_mediator.F90.

Referenced by diag_mediator_init(), and get_new_diag_id().

2196  type(diag_type), intent(inout) :: diag !< diag_type to be initialized
2197 
2198  diag%in_use = .false.
2199  diag%fms_diag_id = -1
2200  diag%axes => null()
2201  diag%mask2d => null()
2202  diag%mask3d => null()
2203  diag%next => null()
2204  diag%conversion_factor = 0.
2205 
Here is the caller graph for this function:

◆ log_available_diag()

subroutine mom_diag_mediator::log_available_diag ( logical, intent(in)  used,
character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  cell_methods_string,
character(len=*), intent(in)  comment,
type(diag_ctrl), intent(in)  diag_CS,
character(len=*), intent(in), optional  long_name,
character(len=*), intent(in), optional  units,
character(len=*), intent(in), optional  standard_name 
)
private

Log a diagnostic to the available diagnostics file.

Parameters
[in]usedWhether this diagnostic was in the diag_table or not
[in]module_nameName of the diagnostic module
[in]field_nameName of this diagnostic field
[in]cell_methods_stringThe spatial component of the CF cell_methods attribute
[in]commentA comment to append after [Used|Unused]
[in]diag_csThe diagnotics control structure
[in]long_nameCF long name of diagnostic
[in]unitsUnits for diagnostic
[in]standard_nameCF standardized name of diagnostic

Definition at line 2237 of file MOM_diag_mediator.F90.

References describe_option().

Referenced by register_diag_field_expand_cmor(), register_scalar_field(), and register_static_field().

2237  logical, intent(in) :: used !< Whether this diagnostic was in the diag_table or not
2238  character(len=*), intent(in) :: module_name !< Name of the diagnostic module
2239  character(len=*), intent(in) :: field_name !< Name of this diagnostic field
2240  character(len=*), intent(in) :: cell_methods_string !< The spatial component of the CF cell_methods attribute
2241  character(len=*), intent(in) :: comment !< A comment to append after [Used|Unused]
2242  type(diag_ctrl), intent(in) :: diag_cs !< The diagnotics control structure
2243  character(len=*), optional, intent(in) :: long_name !< CF long name of diagnostic
2244  character(len=*), optional, intent(in) :: units !< Units for diagnostic
2245  character(len=*), optional, intent(in) :: standard_name !< CF standardized name of diagnostic
2246  ! Local variables
2247  character(len=240) :: mesg
2248 
2249  if (used) then
2250  mesg = '"'//trim(module_name)//'", "'//trim(field_name)//'" [Used]'
2251  else
2252  mesg = '"'//trim(module_name)//'", "'//trim(field_name)//'" [Unused]'
2253  endif
2254  if (len(trim((comment)))>0) then
2255  write(diag_cs%doc_unit, '(a,x,"(",a,")")') trim(mesg),trim(comment)
2256  else
2257  write(diag_cs%doc_unit, '(a)') trim(mesg)
2258  endif
2259  if (present(long_name)) call describe_option("long_name", long_name, diag_cs)
2260  if (present(units)) call describe_option("units", units, diag_cs)
2261  if (present(standard_name)) &
2262  call describe_option("standard_name", standard_name, diag_cs)
2263  if (len(trim((cell_methods_string)))>0) &
2264  call describe_option("cell_methods", trim(cell_methods_string), diag_cs)
2265 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ocean_register_diag()

integer function, public mom_diag_mediator::ocean_register_diag ( type(vardesc), intent(in)  var_desc,
type(ocean_grid_type), intent(in)  G,
type(diag_ctrl), intent(in), target  diag_CS,
type(time_type), intent(in)  day 
)

Registers a diagnostic using the information encapsulated in the vardesc type argument and returns an integer handle to this diagostic. That integer handle is negative if the diagnostic is unused.

Returns
An integer handle to this diagnostic.
Parameters
[in]var_descThe vardesc type describing the diagnostic
[in]gThe ocean's grid type
[in]diag_csThe diagnotic control structure
[in]dayThe current model time

Definition at line 1711 of file MOM_diag_mediator.F90.

References mom_error_handler::mom_error(), mom_io::query_vardesc(), and register_diag_field().

Referenced by mom_diag_to_z::ocean_register_diag_with_z().

1711  integer :: ocean_register_diag !< An integer handle to this diagnostic.
1712  type(vardesc), intent(in) :: var_desc !< The vardesc type describing the diagnostic
1713  type(ocean_grid_type), intent(in) :: g !< The ocean's grid type
1714  type(diag_ctrl), intent(in), target :: diag_cs !< The diagnotic control structure
1715  type(time_type), intent(in) :: day !< The current model time
1716 
1717  character(len=64) :: var_name ! A variable's name.
1718  character(len=48) :: units ! A variable's units.
1719  character(len=240) :: longname ! A variable's longname.
1720  character(len=8) :: hor_grid, z_grid ! Variable grid info.
1721  type(axes_grp), pointer :: axes
1722 
1723  call query_vardesc(var_desc, units=units, longname=longname, hor_grid=hor_grid, &
1724  z_grid=z_grid, caller="ocean_register_diag")
1725 
1726  ! Use the hor_grid and z_grid components of vardesc to determine the
1727  ! desired axes to register the diagnostic field for.
1728  select case (z_grid)
1729 
1730  case ("L")
1731  select case (hor_grid)
1732  case ("q")
1733  axes => diag_cs%axesBL
1734  case ("h")
1735  axes => diag_cs%axesTL
1736  case ("u")
1737  axes => diag_cs%axesCuL
1738  case ("v")
1739  axes => diag_cs%axesCvL
1740  case ("Bu")
1741  axes => diag_cs%axesBL
1742  case ("T")
1743  axes => diag_cs%axesTL
1744  case ("Cu")
1745  axes => diag_cs%axesCuL
1746  case ("Cv")
1747  axes => diag_cs%axesCvL
1748  case ("z")
1749  axes => diag_cs%axeszL
1750  case default
1751  call mom_error(fatal, "ocean_register_diag: " // &
1752  "unknown hor_grid component "//trim(hor_grid))
1753  end select
1754 
1755  case ("i")
1756  select case (hor_grid)
1757  case ("q")
1758  axes => diag_cs%axesBi
1759  case ("h")
1760  axes => diag_cs%axesTi
1761  case ("u")
1762  axes => diag_cs%axesCui
1763  case ("v")
1764  axes => diag_cs%axesCvi
1765  case ("Bu")
1766  axes => diag_cs%axesBi
1767  case ("T")
1768  axes => diag_cs%axesTi
1769  case ("Cu")
1770  axes => diag_cs%axesCui
1771  case ("Cv")
1772  axes => diag_cs%axesCvi
1773  case ("z")
1774  axes => diag_cs%axeszi
1775  case default
1776  call mom_error(fatal, "ocean_register_diag: " // &
1777  "unknown hor_grid component "//trim(hor_grid))
1778  end select
1779 
1780  case ("1")
1781  select case (hor_grid)
1782  case ("q")
1783  axes => diag_cs%axesB1
1784  case ("h")
1785  axes => diag_cs%axesT1
1786  case ("u")
1787  axes => diag_cs%axesCu1
1788  case ("v")
1789  axes => diag_cs%axesCv1
1790  case ("Bu")
1791  axes => diag_cs%axesB1
1792  case ("T")
1793  axes => diag_cs%axesT1
1794  case ("Cu")
1795  axes => diag_cs%axesCu1
1796  case ("Cv")
1797  axes => diag_cs%axesCv1
1798  case default
1799  call mom_error(fatal, "ocean_register_diag: " // &
1800  "unknown hor_grid component "//trim(hor_grid))
1801  end select
1802 
1803  case default
1804  call mom_error(fatal,&
1805  "ocean_register_diag: unknown z_grid component "//trim(z_grid))
1806  end select
1807 
1808  ocean_register_diag = register_diag_field("ocean_model", trim(var_name), &
1809  axes, day, trim(longname), trim(units), missing_value = -1.0e+34)
1810 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ post_data_0d()

subroutine mom_diag_mediator::post_data_0d ( integer, intent(in)  diag_field_id,
real, intent(in)  field,
type(diag_ctrl), intent(in), target  diag_cs,
logical, intent(in), optional  is_static 
)
private

Definition at line 516 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), and id_clock_diag_mediator.

516  integer, intent(in) :: diag_field_id
517  real, intent(in) :: field
518  type(diag_ctrl), target, intent(in) :: diag_cs
519  logical, optional, intent(in) :: is_static
520 
521 ! Arguments:
522 ! (in) diag_field_id - the id for an output variable returned by a
523 ! previous call to register_diag_field.
524 ! (in) field - 0-d array being offered for output or averaging.
525 ! (inout) diag_cs - structure used to regulate diagnostic output.
526 ! (in,opt) is_static - If true, this is a static field that is always offered.
527 ! (in,opt) mask - If present, use this real array as the data mask.
528 
529  logical :: used, is_stat
530  type(diag_type), pointer :: diag => null()
531 
532  if (id_clock_diag_mediator>0) call cpu_clock_begin(id_clock_diag_mediator)
533  is_stat = .false. ; if (present(is_static)) is_stat = is_static
534 
535  ! Iterate over list of diag 'variants', e.g. CMOR aliases, call send_data
536  ! for each one.
537  call assert(diag_field_id < diag_cs%next_free_diag_id, &
538  'post_data_0d: Unregistered diagnostic id')
539  diag => diag_cs%diags(diag_field_id)
540  do while (associated(diag))
541  if (is_stat) then
542  used = send_data(diag%fms_diag_id, field)
543  elseif (diag_cs%ave_enabled) then
544  used = send_data(diag%fms_diag_id, field, diag_cs%time_end)
545  endif
546  diag => diag%next
547  enddo
548 
549  if (id_clock_diag_mediator>0) call cpu_clock_end(id_clock_diag_mediator)
Here is the call graph for this function:

◆ post_data_1d_k()

subroutine, public mom_diag_mediator::post_data_1d_k ( integer, intent(in)  diag_field_id,
real, dimension(:), intent(in)  field,
type(diag_ctrl), intent(in), target  diag_cs,
logical, intent(in), optional  is_static 
)

Definition at line 553 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), and id_clock_diag_mediator.

Referenced by mom_diapyc_energy_req::diapyc_energy_req_calc().

553  integer, intent(in) :: diag_field_id
554  real, intent(in) :: field(:)
555  type(diag_ctrl), target, intent(in) :: diag_cs
556  logical, optional, intent(in) :: is_static
557 
558 ! Arguments:
559 ! (in) diag_field_id - id for an output variable returned by a
560 ! previous call to register_diag_field.
561 ! (in) field - 3-d array being offered for output or averaging
562 ! (inout) diag_cs - structure used to regulate diagnostic output
563 ! (in) static - If true, this is a static field that is always offered.
564 
565  logical :: used ! The return value of send_data is not used for anything.
566  logical :: is_stat
567  integer :: isv, iev, jsv, jev
568  type(diag_type), pointer :: diag => null()
569 
570  if (id_clock_diag_mediator>0) call cpu_clock_begin(id_clock_diag_mediator)
571  is_stat = .false. ; if (present(is_static)) is_stat = is_static
572 
573  ! Iterate over list of diag 'variants', e.g. CMOR aliases.
574  call assert(diag_field_id < diag_cs%next_free_diag_id, &
575  'post_data_1d_k: Unregistered diagnostic id')
576  diag => diag_cs%diags(diag_field_id)
577  do while (associated(diag))
578  if (is_stat) then
579  used = send_data(diag%fms_diag_id, field)
580  elseif (diag_cs%ave_enabled) then
581  used = send_data(diag%fms_diag_id, field, diag_cs%time_end, weight=diag_cs%time_int)
582  endif
583  diag => diag%next
584  enddo
585 
586  if (id_clock_diag_mediator>0) call cpu_clock_end(id_clock_diag_mediator)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ post_data_2d()

subroutine mom_diag_mediator::post_data_2d ( integer, intent(in)  diag_field_id,
real, dimension(:,:), intent(in)  field,
type(diag_ctrl), intent(in), target  diag_cs,
logical, intent(in), optional  is_static,
real, dimension(:,:), intent(in), optional  mask 
)
private

Definition at line 590 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), id_clock_diag_mediator, and post_data_2d_low().

590  integer, intent(in) :: diag_field_id
591  real, intent(in) :: field(:,:)
592  type(diag_ctrl), target, intent(in) :: diag_cs
593  logical, optional, intent(in) :: is_static
594  real, optional, intent(in) :: mask(:,:)
595 
596 ! Arguments:
597 ! (in) diag_field_id - id for an output variable returned by a
598 ! previous call to register_diag_field.
599 ! (in) field - 2-d array being offered for output or averaging.
600 ! (inout) diag_cs - structure used to regulate diagnostic output.
601 ! (in,opt) is_static - If true, this is a static field that is always offered.
602 ! (in,opt) mask - If present, use this real array as the data mask.
603 
604  type(diag_type), pointer :: diag => null()
605 
606  if (id_clock_diag_mediator>0) call cpu_clock_begin(id_clock_diag_mediator)
607 
608  ! Iterate over list of diag 'variants' (e.g. CMOR aliases) and post each.
609  call assert(diag_field_id < diag_cs%next_free_diag_id, &
610  'post_data_2d: Unregistered diagnostic id')
611  diag => diag_cs%diags(diag_field_id)
612  do while (associated(diag))
613  call post_data_2d_low(diag, field, diag_cs, is_static, mask)
614  diag => diag%next
615  enddo
616 
617  if (id_clock_diag_mediator>0) call cpu_clock_end(id_clock_diag_mediator)
Here is the call graph for this function:

◆ post_data_2d_low()

subroutine mom_diag_mediator::post_data_2d_low ( type(diag_type), intent(in)  diag,
real, dimension(:,:), intent(in), target  field,
type(diag_ctrl), intent(in)  diag_cs,
logical, intent(in), optional  is_static,
real, dimension(:,:), intent(in), optional  mask 
)
private

Definition at line 621 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), and mom_error_handler::mom_error().

Referenced by post_data_2d().

621  type(diag_type), intent(in) :: diag
622  real, target, intent(in) :: field(:,:)
623  type(diag_ctrl), intent(in) :: diag_cs
624  logical, optional, intent(in) :: is_static
625  real, optional, intent(in) :: mask(:,:)
626 
627 ! Arguments:
628 ! (in) diag - structure representing the diagnostic to post
629 ! (in) field - 2-d array being offered for output or averaging
630 ! (inout) diag_cs - structure used to regulate diagnostic output
631 ! (in,opt) is_static - If true, this is a static field that is always offered.
632 ! (in,opt) mask - If present, use this real array as the data mask.
633 
634  real, dimension(:,:), pointer :: locfield => null()
635  logical :: used, is_stat
636  integer :: isv, iev, jsv, jev
637 
638  is_stat = .false. ; if (present(is_static)) is_stat = is_static
639 
640  ! Determine the propery array indices, noting that because of the (:,:)
641  ! declaration of field, symmetric arrays are using a SW-grid indexing,
642  ! but non-symmetric arrays are using a NE-grid indexing. Send_data
643  ! actually only uses the difference between ie and is to determine
644  ! the output data size and assumes that halos are symmetric.
645  isv = diag_cs%is ; iev = diag_cs%ie ; jsv = diag_cs%js ; jev = diag_cs%je
646 
647  if ( size(field,1) == diag_cs%ied-diag_cs%isd +1 ) then
648  isv = diag_cs%is ; iev = diag_cs%ie ! Data domain
649  elseif ( size(field,1) == diag_cs%ied-diag_cs%isd +2 ) then
650  isv = diag_cs%is ; iev = diag_cs%ie+1 ! Symmetric data domain
651  elseif ( size(field,1) == diag_cs%ie-diag_cs%is +1 ) then
652  isv = 1 ; iev = diag_cs%ie + 1-diag_cs%is ! Computational domain
653  elseif ( size(field,1) == diag_cs%ie-diag_cs%is +2 ) then
654  isv = 1 ; iev = diag_cs%ie + 2-diag_cs%is ! Symmetric computational domain
655  else
656  call mom_error(fatal,"post_data_2d_low: peculiar size in i-direction")
657  endif
658  if ( size(field,2) == diag_cs%jed-diag_cs%jsd +1 ) then
659  jsv = diag_cs%js ; jev = diag_cs%je ! Data domain
660  elseif ( size(field,2) == diag_cs%jed-diag_cs%jsd +2 ) then
661  jsv = diag_cs%js ; jev = diag_cs%je+1 ! Symmetric data domain
662  elseif ( size(field,2) == diag_cs%je-diag_cs%js +1 ) then
663  jsv = 1 ; jev = diag_cs%je + 1-diag_cs%js ! Computational domain
664  elseif ( size(field,1) == diag_cs%je-diag_cs%js +2 ) then
665  jsv = 1 ; jev = diag_cs%je + 2-diag_cs%js ! Symmetric computational domain
666  else
667  call mom_error(fatal,"post_data_2d_low: peculiar size in j-direction")
668  endif
669 
670  if (diag%conversion_factor/=0.) then
671  allocate( locfield( lbound(field,1):ubound(field,1), lbound(field,2):ubound(field,2) ) )
672  locfield(isv:iev,jsv:jev) = field(isv:iev,jsv:jev) * diag%conversion_factor
673  else
674  locfield => field
675  endif
676 
677  if (is_stat) then
678  if (present(mask)) then
679  call assert(size(locfield) == size(mask), &
680  'post_data_2d_low is_stat: mask size mismatch: '//diag%debug_str)
681  used = send_data(diag%fms_diag_id, locfield, &
682  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=mask)
683  !elseif(associated(diag%mask2d)) then
684  ! used = send_data(diag%fms_diag_id, locfield, &
685  ! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=diag%mask2d)
686  else
687  used = send_data(diag%fms_diag_id, locfield, &
688  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev)
689  endif
690  elseif (diag_cs%ave_enabled) then
691  if (present(mask)) then
692  call assert(size(locfield) == size(mask), &
693  'post_data_2d_low: mask size mismatch: '//diag%debug_str)
694  used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
695  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
696  weight=diag_cs%time_int, rmask=mask)
697  elseif(associated(diag%mask2d)) then
698  used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
699  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
700  weight=diag_cs%time_int, rmask=diag%mask2d)
701  else
702  used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
703  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
704  weight=diag_cs%time_int)
705  endif
706  endif
707  if (diag%conversion_factor/=0.) deallocate( locfield )
708 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ post_data_3d()

subroutine mom_diag_mediator::post_data_3d ( integer, intent(in)  diag_field_id,
real, dimension(:,:,:), intent(in)  field,
type(diag_ctrl), intent(in), target  diag_cs,
logical, intent(in), optional  is_static,
real, dimension(:,:,:), intent(in), optional  mask,
real, dimension(:,:,:), intent(in), optional, target  alt_h 
)
private

Definition at line 712 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), id_clock_diag_mediator, id_clock_diag_remap, mom_error_handler::mom_error(), and post_data_3d_low().

712 
713  integer, intent(in) :: diag_field_id
714  real, intent(in) :: field(:,:,:)
715  type(diag_ctrl), target, intent(in) :: diag_cs
716  logical, optional, intent(in) :: is_static
717  real, optional, intent(in) :: mask(:,:,:)
718  real, target, optional, intent(in) :: alt_h(:,:,:)
719 
720 ! Arguments:
721 ! (in) diag_field_id - id for an output variable returned by a
722 ! previous call to register_diag_field.
723 ! (in) field - 3-d array being offered for output or averaging
724 ! (inout) diag - structure used to regulate diagnostic output
725 ! (in) static - If true, this is a static field that is always offered.
726 ! (in,opt) mask - If present, use this real array as the data mask.
727 
728  type(diag_type), pointer :: diag => null()
729  integer :: nz, i, j, k
730  real, dimension(:,:,:), allocatable :: remapped_field
731  logical :: staggered_in_x, staggered_in_y
732  real, dimension(:,:,:), pointer :: h_diag
733 
734  if(present(alt_h)) then
735  h_diag => alt_h
736  else
737  h_diag => diag_cs%h
738  endif
739 
740  if (id_clock_diag_mediator>0) call cpu_clock_begin(id_clock_diag_mediator)
741 
742  ! Iterate over list of diag 'variants', e.g. CMOR aliases, different vertical
743  ! grids, and post each.
744  call assert(diag_field_id < diag_cs%next_free_diag_id, &
745  'post_data_3d: Unregistered diagnostic id')
746  diag => diag_cs%diags(diag_field_id)
747  do while (associated(diag))
748  call assert(associated(diag%axes), 'post_data_3d: axes is not associated')
749 
750  staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
751  staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
752 
753  if (diag%v_extensive .and. .not.diag%axes%is_native) then
754  ! The field is vertically integrated and needs to be re-gridded
755  if (present(mask)) then
756  call mom_error(fatal,"post_data_3d: no mask for regridded field.")
757  endif
758 
759  if (id_clock_diag_remap>0) call cpu_clock_begin(id_clock_diag_remap)
760  allocate(remapped_field(size(field,1), size(field,2), diag%axes%nz))
761  call vertically_reintegrate_diag_field( &
762  diag_cs%diag_remap_cs(diag%axes%vertical_coordinate_number), &
763  diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
764  diag%mask3d, diag_cs%missing_value, field, remapped_field)
765  if (id_clock_diag_remap>0) call cpu_clock_end(id_clock_diag_remap)
766  if (associated(diag%mask3d)) then
767  ! Since 3d masks do not vary in the vertical, just use as much as is
768  ! needed.
769  call post_data_3d_low(diag, remapped_field, diag_cs, is_static, &
770  mask=diag%mask3d(:,:,:diag%axes%nz))
771  else
772  call post_data_3d_low(diag, remapped_field, diag_cs, is_static)
773  endif
774  if (id_clock_diag_remap>0) call cpu_clock_begin(id_clock_diag_remap)
775  deallocate(remapped_field)
776  if (id_clock_diag_remap>0) call cpu_clock_end(id_clock_diag_remap)
777  elseif (diag%axes%needs_remapping) then
778  ! Remap this field to another vertical coordinate.
779  if (present(mask)) then
780  call mom_error(fatal,"post_data_3d: no mask for regridded field.")
781  endif
782 
783  if (id_clock_diag_remap>0) call cpu_clock_begin(id_clock_diag_remap)
784  allocate(remapped_field(size(field,1), size(field,2), diag%axes%nz))
785  call diag_remap_do_remap(diag_cs%diag_remap_cs( &
786  diag%axes%vertical_coordinate_number), &
787  diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
788  diag%mask3d, diag_cs%missing_value, field, remapped_field)
789  if (id_clock_diag_remap>0) call cpu_clock_end(id_clock_diag_remap)
790  if (associated(diag%mask3d)) then
791  ! Since 3d masks do not vary in the vertical, just use as much as is
792  ! needed.
793  call post_data_3d_low(diag, remapped_field, diag_cs, is_static, &
794  mask=diag%mask3d(:,:,:diag%axes%nz))
795  else
796  call post_data_3d_low(diag, remapped_field, diag_cs, is_static)
797  endif
798  if (id_clock_diag_remap>0) call cpu_clock_begin(id_clock_diag_remap)
799  deallocate(remapped_field)
800  if (id_clock_diag_remap>0) call cpu_clock_end(id_clock_diag_remap)
801  elseif (diag%axes%needs_interpolating) then
802  ! Interpolate this field to another vertical coordinate.
803  if (present(mask)) then
804  call mom_error(fatal,"post_data_3d: no mask for regridded field.")
805  endif
806 
807  if (id_clock_diag_remap>0) call cpu_clock_begin(id_clock_diag_remap)
808  allocate(remapped_field(size(field,1), size(field,2), diag%axes%nz+1))
809  call vertically_interpolate_diag_field(diag_cs%diag_remap_cs( &
810  diag%axes%vertical_coordinate_number), &
811  diag_cs%G, h_diag, staggered_in_x, staggered_in_y, &
812  diag%mask3d, diag_cs%missing_value, field, remapped_field)
813  if (id_clock_diag_remap>0) call cpu_clock_end(id_clock_diag_remap)
814  if (associated(diag%mask3d)) then
815  ! Since 3d masks do not vary in the vertical, just use as much as is
816  ! needed.
817  call post_data_3d_low(diag, remapped_field, diag_cs, is_static, &
818  mask=diag%mask3d(:,:,:diag%axes%nz+1))
819  else
820  call post_data_3d_low(diag, remapped_field, diag_cs, is_static)
821  endif
822  if (id_clock_diag_remap>0) call cpu_clock_begin(id_clock_diag_remap)
823  deallocate(remapped_field)
824  if (id_clock_diag_remap>0) call cpu_clock_end(id_clock_diag_remap)
825  else
826  call post_data_3d_low(diag, field, diag_cs, is_static, mask)
827  endif
828  diag => diag%next
829  enddo
830  if (id_clock_diag_mediator>0) call cpu_clock_end(id_clock_diag_mediator)
831 
Here is the call graph for this function:

◆ post_data_3d_low()

subroutine mom_diag_mediator::post_data_3d_low ( type(diag_type), intent(in)  diag,
real, dimension(:,:,:), intent(in), target  field,
type(diag_ctrl), intent(in)  diag_cs,
logical, intent(in), optional  is_static,
real, dimension(:,:,:), intent(in), optional  mask 
)
private

Definition at line 835 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), mom_error_handler::mom_error(), and post_xy_average().

Referenced by post_data_3d().

835  type(diag_type), intent(in) :: diag
836  real, target, intent(in) :: field(:,:,:)
837  type(diag_ctrl), intent(in) :: diag_cs
838  logical, optional, intent(in) :: is_static
839  real, optional, intent(in) :: mask(:,:,:)
840 
841 ! Arguments:
842 ! (in) diag - the diagnostic to post.
843 ! (in) field - 3-d array being offered for output or averaging
844 ! (inout) diag_cs - structure used to regulate diagnostic output
845 ! (in) static - If true, this is a static field that is always offered.
846 ! (in,opt) mask - If present, use this real array as the data mask.
847 
848  real, dimension(:,:,:), pointer :: locfield => null()
849  logical :: used ! The return value of send_data is not used for anything.
850  logical :: is_stat
851  integer :: isv, iev, jsv, jev
852 
853  is_stat = .false. ; if (present(is_static)) is_stat = is_static
854 
855  ! Determine the proper array indices, noting that because of the (:,:)
856  ! declaration of field, symmetric arrays are using a SW-grid indexing,
857  ! but non-symmetric arrays are using a NE-grid indexing. Send_data
858  ! actually only uses the difference between ie and is to determine
859  ! the output data size and assumes that halos are symmetric.
860  isv = diag_cs%is ; iev = diag_cs%ie ; jsv = diag_cs%js ; jev = diag_cs%je
861 
862  if ( size(field,1) == diag_cs%ied-diag_cs%isd +1 ) then
863  isv = diag_cs%is ; iev = diag_cs%ie ! Data domain
864  elseif ( size(field,1) == diag_cs%ied-diag_cs%isd +2 ) then
865  isv = diag_cs%is ; iev = diag_cs%ie+1 ! Symmetric data domain
866  elseif ( size(field,1) == diag_cs%ie-diag_cs%is +1 ) then
867  isv = 1 ; iev = diag_cs%ie + 1-diag_cs%is ! Computational domain
868  elseif ( size(field,1) == diag_cs%ie-diag_cs%is +2 ) then
869  isv = 1 ; iev = diag_cs%ie + 2-diag_cs%is ! Symmetric computational domain
870  else
871  call mom_error(fatal,"post_data_3d_low: peculiar size in i-direction")
872  endif
873  if ( size(field,2) == diag_cs%jed-diag_cs%jsd +1 ) then
874  jsv = diag_cs%js ; jev = diag_cs%je ! Data domain
875  elseif ( size(field,2) == diag_cs%jed-diag_cs%jsd +2 ) then
876  jsv = diag_cs%js ; jev = diag_cs%je+1 ! Symmetric data domain
877  elseif ( size(field,2) == diag_cs%je-diag_cs%js +1 ) then
878  jsv = 1 ; jev = diag_cs%je + 1-diag_cs%js ! Computational domain
879  elseif ( size(field,1) == diag_cs%je-diag_cs%js +2 ) then
880  jsv = 1 ; jev = diag_cs%je + 2-diag_cs%js ! Symmetric computational domain
881  else
882  call mom_error(fatal,"post_data_3d_low: peculiar size in j-direction")
883  endif
884 
885  if (diag%conversion_factor/=0.) then
886  allocate( locfield( lbound(field,1):ubound(field,1), lbound(field,2):ubound(field,2), &
887  lbound(field,3):ubound(field,3) ) )
888  locfield(isv:iev,jsv:jev,:) = field(isv:iev,jsv:jev,:) * diag%conversion_factor
889  else
890  locfield => field
891  endif
892 
893  if (diag%fms_diag_id>0) then
894  if (is_stat) then
895  if (present(mask)) then
896  call assert(size(locfield) == size(mask), &
897  'post_data_3d_low is_stat: mask size mismatch: '//diag%debug_str)
898  used = send_data(diag%fms_diag_id, locfield, &
899  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=mask)
900  !elseif(associated(diag%mask3d)) then
901  ! used = send_data(diag_field_id, locfield, &
902  ! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=diag%mask3d)
903  else
904  used = send_data(diag%fms_diag_id, locfield, &
905  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev)
906  endif
907  elseif (diag_cs%ave_enabled) then
908  if (present(mask)) then
909  call assert(size(locfield) == size(mask), &
910  'post_data_3d_low: mask size mismatch: '//diag%debug_str)
911  used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
912  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
913  weight=diag_cs%time_int, rmask=mask)
914  elseif(associated(diag%mask3d)) then
915  call assert(size(locfield) == size(diag%mask3d), &
916  'post_data_3d_low: mask3d size mismatch: '//diag%debug_str)
917  used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
918  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
919  weight=diag_cs%time_int, rmask=diag%mask3d)
920  else
921  used = send_data(diag%fms_diag_id, locfield, diag_cs%time_end, &
922  is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, &
923  weight=diag_cs%time_int)
924  endif
925  endif
926  endif
927  if (diag%fms_xyave_diag_id>0) then
928  call post_xy_average(diag_cs, diag, locfield)
929  endif
930  if (diag%conversion_factor/=0.) deallocate( locfield )
931 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ post_xy_average()

subroutine mom_diag_mediator::post_xy_average ( type(diag_ctrl), intent(in)  diag_cs,
type(diag_type), intent(in)  diag,
real, dimension(:,:,:), intent(in), target  field 
)
private

Post the horizontally area-averaged diagnostic.

Parameters
[in]diagThis diagnostic
[in]fieldDiagnostic field
[in]diag_csDiagnostics mediator control structure

Definition at line 936 of file MOM_diag_mediator.F90.

References mom_error_handler::assert(), and mom_diag_remap::horizontally_average_diag_field().

Referenced by post_data_3d_low().

936  type(diag_type), intent(in) :: diag !< This diagnostic
937  real, target, intent(in) :: field(:,:,:) !< Diagnostic field
938  type(diag_ctrl), intent(in) :: diag_cs !< Diagnostics mediator control structure
939  ! Local variable
940  real, dimension(size(field,3)) :: averaged_field
941  logical :: staggered_in_x, staggered_in_y, used
942  integer :: nz, remap_nz, coord
943 
944  if (.not. diag_cs%ave_enabled) then
945  return
946  endif
947 
948  staggered_in_x = diag%axes%is_u_point .or. diag%axes%is_q_point
949  staggered_in_y = diag%axes%is_v_point .or. diag%axes%is_q_point
950 
951  if (diag%axes%is_native) then
952  call horizontally_average_diag_field(diag_cs%G, diag_cs%h, &
953  staggered_in_x, staggered_in_y, &
954  diag%axes%is_layer, diag%v_extensive, &
955  diag_cs%missing_value, field, averaged_field)
956  else
957  nz = size(field, 3)
958  coord = diag%axes%vertical_coordinate_number
959  remap_nz = diag_cs%diag_remap_cs(coord)%nz
960 
961  call assert(diag_cs%diag_remap_cs(coord)%initialized, &
962  'post_xy_average: remap_cs not initialized.')
963 
964  call assert(implies(diag%axes%is_layer, nz == remap_nz), &
965  'post_xy_average: layer field dimension mismatch.')
966  call assert(implies(.not. diag%axes%is_layer, nz == remap_nz+1), &
967  'post_xy_average: interface field dimension mismatch.')
968 
969  call horizontally_average_diag_field(diag_cs%G, diag_cs%diag_remap_cs(coord)%h, &
970  staggered_in_x, staggered_in_y, &
971  diag%axes%is_layer, diag%v_extensive, &
972  diag_cs%missing_value, field, averaged_field)
973  endif
974 
975  used = send_data(diag%fms_xyave_diag_id, averaged_field, diag_cs%time_end, &
976  weight=diag_cs%time_int)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_averaging_enabled()

logical function, public mom_diag_mediator::query_averaging_enabled ( type(diag_ctrl), intent(in)  diag_cs,
real, intent(out), optional  time_int,
type(time_type), intent(out), optional  time_end 
)

Definition at line 1014 of file MOM_diag_mediator.F90.

Referenced by mom_lateral_mixing_coeffs::calc_resoln_function(), mom_lateral_mixing_coeffs::calc_slope_functions(), mom_lateral_mixing_coeffs::calc_visbeck_coeffs(), mom_diabatic_driver::diabatic(), mom_forcing_type::forcing_diagnostics(), mom_forcing_type::mech_forcing_diags(), and mom_opacity::set_opacity().

1014  type(diag_ctrl), intent(in) :: diag_cs
1015  real, optional, intent(out) :: time_int
1016  type(time_type), optional, intent(out) :: time_end
1017  logical :: query_averaging_enabled
1018 
1019 ! Arguments:
1020 ! (in) diag - structure used to regulate diagnostic output
1021 ! (out,opt) time_int - current setting of diag%time_int, in s
1022 ! (out,opt) time_end - current setting of diag%time_end
1023 
1024  if (present(time_int)) time_int = diag_cs%time_int
1025  if (present(time_end)) time_end = diag_cs%time_end
1026  query_averaging_enabled = diag_cs%ave_enabled
Here is the caller graph for this function:

◆ register_diag_field()

integer function, public mom_diag_mediator::register_diag_field ( character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
type(axes_grp), intent(in), target  axes,
type(time_type), intent(in)  init_time,
character(len=*), intent(in), optional  long_name,
character(len=*), intent(in), optional  units,
real, intent(in), optional  missing_value,
real, dimension(2), intent(in), optional  range,
logical, intent(in), optional  mask_variant,
character(len=*), intent(in), optional  standard_name,
logical, intent(in), optional  verbose,
logical, intent(in), optional  do_not_log,
character(len=*), intent(out), optional  err_msg,
character(len=*), intent(in), optional  interp_method,
integer, intent(in), optional  tile_count,
character(len=*), intent(in), optional  cmor_field_name,
character(len=*), intent(in), optional  cmor_long_name,
character(len=*), intent(in), optional  cmor_units,
character(len=*), intent(in), optional  cmor_standard_name,
character(len=*), intent(in), optional  cell_methods,
character(len=*), intent(in), optional  x_cell_method,
character(len=*), intent(in), optional  y_cell_method,
character(len=*), intent(in), optional  v_cell_method,
real, intent(in), optional  conversion,
logical, intent(in), optional  v_extensive 
)

Returns the "diag_mediator" handle for a group (native, CMOR, z-coord, ...) of diagnostics derived from one field.

Parameters
[in]module_nameName of this module, usually "ocean_model" or "ice_shelf_model"
[in]field_nameName of the diagnostic field
[in]axesContainer w/ up to 3 integer handles that indicates axes for this field
[in]init_timeTime at which a field is first available?
[in]long_nameLong name of a field.
[in]unitsUnits of a field.
[in]standard_nameStandardized name associated with a field
[in]missing_valueA value that indicates missing values.
[in]rangeValid range of a variable (not used in MOM?)
[in]mask_variantIf true a logical mask must be provided with post_data calls (not used in MOM?)
[in]verboseIf true, FMS is verbose (not used in MOM?)
[in]do_not_logIf true, do not log something (not used in MOM?)
[out]err_msgString into which an error message might be placed (not used in MOM?)
[in]interp_methodIf 'none' indicates the field should not be interpolated as a scalar
[in]tile_countno clue (not used in MOM?)
[in]cmor_field_nameCMOR name of a field
[in]cmor_long_nameCMOR long name of a field
[in]cmor_unitsCMOR units of a field
[in]cmor_standard_nameCMOR standardized name associated with a field
[in]cell_methodsString to append as cell_methods attribute. Use '' to have no attribute. If present, this overrides the default constructed from the default for each individual axis direction.
[in]x_cell_methodSpecifies the cell method for the x-direction. Use '' have no method.
[in]y_cell_methodSpecifies the cell method for the y-direction. Use '' have no method.
[in]v_cell_methodSpecifies the cell method for the vertical direction. Use '' have no method.
[in]conversionA value to multiply data by before writing to file
[in]v_extensiveTrue for vertically extensive fields (vertically integrated). Default/absent for intensive.

Definition at line 1048 of file MOM_diag_mediator.F90.

References register_diag_field_expand_cmor().

Referenced by mom_ale::ale_register_diags(), mom_coriolisadv::coriolisadv_init(), mom_diapyc_energy_req::diapyc_energy_req_init(), mom_diffconvection::diffconvection_init(), mom_int_tide_input::int_tide_input_init(), mom_kpp::kpp_init(), mom_neutral_diffusion::neutral_diffusion_diag_init(), and ocean_register_diag().

1048  character(len=*), intent(in) :: module_name !< Name of this module, usually "ocean_model" or "ice_shelf_model"
1049  character(len=*), intent(in) :: field_name !< Name of the diagnostic field
1050  type(axes_grp), target, intent(in) :: axes !< Container w/ up to 3 integer handles that indicates axes for this field
1051  type(time_type), intent(in) :: init_time !< Time at which a field is first available?
1052  character(len=*), optional, intent(in) :: long_name !< Long name of a field.
1053  character(len=*), optional, intent(in) :: units !< Units of a field.
1054  character(len=*), optional, intent(in) :: standard_name !< Standardized name associated with a field
1055  real, optional, intent(in) :: missing_value !< A value that indicates missing values.
1056  real, optional, intent(in) :: range(2) !< Valid range of a variable (not used in MOM?)
1057  logical, optional, intent(in) :: mask_variant !< If true a logical mask must be provided with post_data calls (not used in MOM?)
1058  logical, optional, intent(in) :: verbose !< If true, FMS is verbose (not used in MOM?)
1059  logical, optional, intent(in) :: do_not_log !< If true, do not log something (not used in MOM?)
1060  character(len=*), optional, intent(out):: err_msg !< String into which an error message might be placed (not used in MOM?)
1061  character(len=*), optional, intent(in) :: interp_method !< If 'none' indicates the field should not be interpolated as a scalar
1062  integer, optional, intent(in) :: tile_count !< no clue (not used in MOM?)
1063  character(len=*), optional, intent(in) :: cmor_field_name !< CMOR name of a field
1064  character(len=*), optional, intent(in) :: cmor_long_name !< CMOR long name of a field
1065  character(len=*), optional, intent(in) :: cmor_units !< CMOR units of a field
1066  character(len=*), optional, intent(in) :: cmor_standard_name !< CMOR standardized name associated with a field
1067  character(len=*), optional, intent(in) :: cell_methods !< String to append as cell_methods attribute. Use '' to have no attribute.
1068  !! If present, this overrides the default constructed from the default for
1069  !! each individual axis direction.
1070  character(len=*), optional, intent(in) :: x_cell_method !< Specifies the cell method for the x-direction. Use '' have no method.
1071  character(len=*), optional, intent(in) :: y_cell_method !< Specifies the cell method for the y-direction. Use '' have no method.
1072  character(len=*), optional, intent(in) :: v_cell_method !< Specifies the cell method for the vertical direction. Use '' have no method.
1073  real, optional, intent(in) :: conversion !< A value to multiply data by before writing to file
1074  logical, optional, intent(in) :: v_extensive !< True for vertically extensive fields (vertically integrated). Default/absent for intensive.
1075  ! Local variables
1076  real :: mom_missing_value
1077  type(diag_ctrl), pointer :: diag_cs
1078  type(axes_grp), pointer :: remap_axes => null()
1079  integer :: dm_id, i
1080  character(len=256) :: new_module_name
1081  logical :: active
1082 
1083  mom_missing_value = axes%diag_cs%missing_value
1084  if(present(missing_value)) mom_missing_value = missing_value
1085 
1086  diag_cs => axes%diag_cs
1087  dm_id = -1
1088 
1089  ! Register the native diagnostic
1090  active = register_diag_field_expand_cmor(dm_id, module_name, field_name, axes, &
1091  init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
1092  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1093  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1094  interp_method=interp_method, tile_count=tile_count, &
1095  cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
1096  cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
1097  cell_methods=cell_methods, x_cell_method=x_cell_method, &
1098  y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
1099  conversion=conversion, v_extensive=v_extensive)
1100 
1101  ! For each diagnostic coordinate register the diagnostic again under a different module name
1102  do i=1,diag_cs%num_diag_coords
1103  new_module_name = trim(module_name)//'_'//trim(diag_cs%diag_remap_cs(i)%diag_module_suffix)
1104 
1105  ! Register diagnostics remapped to z vertical coordinate
1106  if (axes%rank == 3) then
1107  remap_axes => null()
1108  if ((axes%id .eq. diag_cs%axesTL%id)) then
1109  remap_axes => diag_cs%remap_axesTL(i)
1110  elseif(axes%id .eq. diag_cs%axesBL%id) then
1111  remap_axes => diag_cs%remap_axesBL(i)
1112  elseif(axes%id .eq. diag_cs%axesCuL%id ) then
1113  remap_axes => diag_cs%remap_axesCuL(i)
1114  elseif(axes%id .eq. diag_cs%axesCvL%id) then
1115  remap_axes => diag_cs%remap_axesCvL(i)
1116  elseif(axes%id .eq. diag_cs%axesTi%id) then
1117  remap_axes => diag_cs%remap_axesTi(i)
1118  elseif(axes%id .eq. diag_cs%axesBi%id) then
1119  remap_axes => diag_cs%remap_axesBi(i)
1120  elseif(axes%id .eq. diag_cs%axesCui%id ) then
1121  remap_axes => diag_cs%remap_axesCui(i)
1122  elseif(axes%id .eq. diag_cs%axesCvi%id) then
1123  remap_axes => diag_cs%remap_axesCvi(i)
1124  endif
1125  ! When the MOM_diag_to_Z module has been obsoleted we can assume remap_axes will
1126  ! always exist but in the mean-time we have to do this check:
1127  ! call assert(associated(remap_axes), 'register_diag_field: remap_axes not set')
1128  if (associated(remap_axes)) then
1129  if (remap_axes%needs_remapping .or. remap_axes%needs_interpolating) then
1130  active = register_diag_field_expand_cmor(dm_id, new_module_name, field_name, remap_axes, &
1131  init_time, long_name=long_name, units=units, missing_value=mom_missing_value, &
1132  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1133  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1134  interp_method=interp_method, tile_count=tile_count, &
1135  cmor_field_name=cmor_field_name, cmor_long_name=cmor_long_name, &
1136  cmor_units=cmor_units, cmor_standard_name=cmor_standard_name, &
1137  cell_methods=cell_methods, x_cell_method=x_cell_method, &
1138  y_cell_method=y_cell_method, v_cell_method=v_cell_method, &
1139  conversion=conversion, v_extensive=v_extensive)
1140  if (active) then
1141  call diag_remap_set_active(diag_cs%diag_remap_cs(i))
1142  endif
1143  endif ! remap_axes%needs_remapping
1144  endif ! associated(remap_axes)
1145  endif ! axes%rank == 3
1146  enddo ! i
1147 
1148  register_diag_field = dm_id
1149 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_diag_field_expand_axes()

integer function mom_diag_mediator::register_diag_field_expand_axes ( character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
type(axes_grp), intent(in), target  axes,
type(time_type), intent(in)  init_time,
character(len=*), intent(in), optional  long_name,
character(len=*), intent(in), optional  units,
real, intent(in), optional  missing_value,
real, dimension(2), intent(in), optional  range,
logical, intent(in), optional  mask_variant,
character(len=*), intent(in), optional  standard_name,
logical, intent(in), optional  verbose,
logical, intent(in), optional  do_not_log,
character(len=*), intent(out), optional  err_msg,
character(len=*), intent(in), optional  interp_method,
integer, intent(in), optional  tile_count 
)
private

Returns an FMS id from register_diag_field_fms (the diag_manager routine) after expanding axes (axes-group) into handles and conditionally adding an FMS area_id for cell_measures.

Parameters
[in]module_nameName of this module, usually "ocean_model" or "ice_shelf_model"
[in]field_nameName of the diagnostic field
[in]axesContainer w/ up to 3 integer handles that indicates axes for this field
[in]init_timeTime at which a field is first available?
[in]long_nameLong name of a field.
[in]unitsUnits of a field.
[in]standard_nameStandardized name associated with a field
[in]missing_valueA value that indicates missing values.
[in]rangeValid range of a variable (not used in MOM?)
[in]mask_variantIf true a logical mask must be provided with post_data calls (not used in MOM?)
[in]verboseIf true, FMS is verbose (not used in MOM?)
[in]do_not_logIf true, do not log something (not used in MOM?)
[out]err_msgString into which an error message might be placed (not used in MOM?)
[in]interp_methodIf 'none' indicates the field should not be interpolated as a scalar
[in]tile_countno clue (not used in MOM?)

Definition at line 1311 of file MOM_diag_mediator.F90.

Referenced by register_diag_field_expand_cmor().

1311  character(len=*), intent(in) :: module_name !< Name of this module, usually "ocean_model" or "ice_shelf_model"
1312  character(len=*), intent(in) :: field_name !< Name of the diagnostic field
1313  type(axes_grp), target, intent(in) :: axes !< Container w/ up to 3 integer handles that indicates axes for this field
1314  type(time_type), intent(in) :: init_time !< Time at which a field is first available?
1315  character(len=*), optional, intent(in) :: long_name !< Long name of a field.
1316  character(len=*), optional, intent(in) :: units !< Units of a field.
1317  character(len=*), optional, intent(in) :: standard_name !< Standardized name associated with a field
1318  real, optional, intent(in) :: missing_value !< A value that indicates missing values.
1319  real, optional, intent(in) :: range(2) !< Valid range of a variable (not used in MOM?)
1320  logical, optional, intent(in) :: mask_variant !< If true a logical mask must be provided with post_data calls (not used in MOM?)
1321  logical, optional, intent(in) :: verbose !< If true, FMS is verbose (not used in MOM?)
1322  logical, optional, intent(in) :: do_not_log !< If true, do not log something (not used in MOM?)
1323  character(len=*), optional, intent(out):: err_msg !< String into which an error message might be placed (not used in MOM?)
1324  character(len=*), optional, intent(in) :: interp_method !< If 'none' indicates the field should not be interpolated as a scalar
1325  integer, optional, intent(in) :: tile_count !< no clue (not used in MOM?)
1326  ! Local variables
1327  integer :: fms_id, area_id
1328 
1329  ! This gets the cell area associated with the grid location of this variable
1330  area_id = axes%id_area
1331 
1332  ! Get the FMS diagnostic id
1333  if (present(interp_method) .or. axes%is_h_point) then
1334  ! If interp_method is provided we must use it
1335  if (area_id>0) then
1336  fms_id = register_diag_field_fms(module_name, field_name, axes%handles, &
1337  init_time, long_name=long_name, units=units, missing_value=missing_value, &
1338  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1339  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1340  interp_method=interp_method, tile_count=tile_count, area=area_id)
1341  else
1342  fms_id = register_diag_field_fms(module_name, field_name, axes%handles, &
1343  init_time, long_name=long_name, units=units, missing_value=missing_value, &
1344  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1345  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1346  interp_method=interp_method, tile_count=tile_count)
1347  endif
1348  else
1349  ! If interp_method is not provided and the field is not at an h-point then interp_method='none'
1350  if (area_id>0) then
1351  fms_id = register_diag_field_fms(module_name, field_name, axes%handles, &
1352  init_time, long_name=long_name, units=units, missing_value=missing_value, &
1353  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1354  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1355  interp_method='none', tile_count=tile_count, area=area_id)
1356  else
1357  fms_id = register_diag_field_fms(module_name, field_name, axes%handles, &
1358  init_time, long_name=long_name, units=units, missing_value=missing_value, &
1359  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1360  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1361  interp_method='none', tile_count=tile_count)
1362  endif
1363  endif
1364 
1365  register_diag_field_expand_axes = fms_id
1366 
Here is the caller graph for this function:

◆ register_diag_field_expand_cmor()

logical function mom_diag_mediator::register_diag_field_expand_cmor ( integer, intent(inout)  dm_id,
character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
type(axes_grp), intent(in), target  axes,
type(time_type), intent(in)  init_time,
character(len=*), intent(in), optional  long_name,
character(len=*), intent(in), optional  units,
real, intent(in), optional  missing_value,
real, dimension(2), intent(in), optional  range,
logical, intent(in), optional  mask_variant,
character(len=*), intent(in), optional  standard_name,
logical, intent(in), optional  verbose,
logical, intent(in), optional  do_not_log,
character(len=*), intent(out), optional  err_msg,
character(len=*), intent(in), optional  interp_method,
integer, intent(in), optional  tile_count,
character(len=*), intent(in), optional  cmor_field_name,
character(len=*), intent(in), optional  cmor_long_name,
character(len=*), intent(in), optional  cmor_units,
character(len=*), intent(in), optional  cmor_standard_name,
character(len=*), intent(in), optional  cell_methods,
character(len=*), intent(in), optional  x_cell_method,
character(len=*), intent(in), optional  y_cell_method,
character(len=*), intent(in), optional  v_cell_method,
real, intent(in), optional  conversion,
logical, intent(in), optional  v_extensive 
)
private

Returns True if either the native of CMOr version of the diagnostic were registered. Updates 'dm_id' after calling register_diag_field_expand_axes() for both native and CMOR variants of the field.

Parameters
[in,out]dm_idThe diag_mediator ID for this diagnostic group
[in]module_nameName of this module, usually "ocean_model" or "ice_shelf_model"
[in]field_nameName of the diagnostic field
[in]axesContainer w/ up to 3 integer handles that indicates axes for this field
[in]init_timeTime at which a field is first available?
[in]long_nameLong name of a field.
[in]unitsUnits of a field.
[in]standard_nameStandardized name associated with a field
[in]missing_valueA value that indicates missing values.
[in]rangeValid range of a variable (not used in MOM?)
[in]mask_variantIf true a logical mask must be provided with post_data calls (not used in MOM?)
[in]verboseIf true, FMS is verbose (not used in MOM?)
[in]do_not_logIf true, do not log something (not used in MOM?)
[out]err_msgString into which an error message might be placed (not used in MOM?)
[in]interp_methodIf 'none' indicates the field should not be interpolated as a scalar
[in]tile_countno clue (not used in MOM?)
[in]cmor_field_nameCMOR name of a field
[in]cmor_long_nameCMOR long name of a field
[in]cmor_unitsCMOR units of a field
[in]cmor_standard_nameCMOR standardized name associated with a field
[in]cell_methodsString to append as cell_methods attribute. Use '' to have no attribute. If present, this overrides the default constructed from the default for each individual axis direction.
[in]x_cell_methodSpecifies the cell method for the x-direction. Use '' have no method.
[in]y_cell_methodSpecifies the cell method for the y-direction. Use '' have no method.
[in]v_cell_methodSpecifies the cell method for the vertical direction. Use '' have no method.
[in]conversionA value to multiply data by before writing to file
[in]v_extensiveTrue for vertically extensive fields (vertically integrated). Default/absent for intensive.

Definition at line 1159 of file MOM_diag_mediator.F90.

References add_diag_to_list(), attach_cell_methods(), mom_error_handler::is_root_pe(), log_available_diag(), and register_diag_field_expand_axes().

Referenced by register_diag_field().

1159  integer, intent(inout) :: dm_id !< The diag_mediator ID for this diagnostic group
1160  character(len=*), intent(in) :: module_name !< Name of this module, usually "ocean_model" or "ice_shelf_model"
1161  character(len=*), intent(in) :: field_name !< Name of the diagnostic field
1162  type(axes_grp), target, intent(in) :: axes !< Container w/ up to 3 integer handles that indicates axes for this field
1163  type(time_type), intent(in) :: init_time !< Time at which a field is first available?
1164  character(len=*), optional, intent(in) :: long_name !< Long name of a field.
1165  character(len=*), optional, intent(in) :: units !< Units of a field.
1166  character(len=*), optional, intent(in) :: standard_name !< Standardized name associated with a field
1167  real, optional, intent(in) :: missing_value !< A value that indicates missing values.
1168  real, optional, intent(in) :: range(2) !< Valid range of a variable (not used in MOM?)
1169  logical, optional, intent(in) :: mask_variant !< If true a logical mask must be provided with post_data calls (not used in MOM?)
1170  logical, optional, intent(in) :: verbose !< If true, FMS is verbose (not used in MOM?)
1171  logical, optional, intent(in) :: do_not_log !< If true, do not log something (not used in MOM?)
1172  character(len=*), optional, intent(out):: err_msg !< String into which an error message might be placed (not used in MOM?)
1173  character(len=*), optional, intent(in) :: interp_method !< If 'none' indicates the field should not be interpolated as a scalar
1174  integer, optional, intent(in) :: tile_count !< no clue (not used in MOM?)
1175  character(len=*), optional, intent(in) :: cmor_field_name !< CMOR name of a field
1176  character(len=*), optional, intent(in) :: cmor_long_name !< CMOR long name of a field
1177  character(len=*), optional, intent(in) :: cmor_units !< CMOR units of a field
1178  character(len=*), optional, intent(in) :: cmor_standard_name !< CMOR standardized name associated with a field
1179  character(len=*), optional, intent(in) :: cell_methods !< String to append as cell_methods attribute. Use '' to have no attribute.
1180  !! If present, this overrides the default constructed from the default for
1181  !! each individual axis direction.
1182  character(len=*), optional, intent(in) :: x_cell_method !< Specifies the cell method for the x-direction. Use '' have no method.
1183  character(len=*), optional, intent(in) :: y_cell_method !< Specifies the cell method for the y-direction. Use '' have no method.
1184  character(len=*), optional, intent(in) :: v_cell_method !< Specifies the cell method for the vertical direction. Use '' have no method.
1185  real, optional, intent(in) :: conversion !< A value to multiply data by before writing to file
1186  logical, optional, intent(in) :: v_extensive !< True for vertically extensive fields (vertically integrated). Default/absent for intensive.
1187  ! Local variables
1188  real :: mom_missing_value
1189  type(diag_ctrl), pointer :: diag_cs
1190  type(diag_type), pointer :: this_diag => null()
1191  integer :: fms_id, fms_xyave_id
1192  character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name, cm_string, msg
1193 
1194  mom_missing_value = axes%diag_cs%missing_value
1195  if(present(missing_value)) mom_missing_value = missing_value
1196 
1197  register_diag_field_expand_cmor = .false.
1198  diag_cs => axes%diag_cs
1199 
1200  ! Set up the 'primary' diagnostic, first get an underlying FMS id
1201  fms_id = register_diag_field_expand_axes(module_name, field_name, axes, init_time, &
1202  long_name=long_name, units=units, missing_value=mom_missing_value, &
1203  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1204  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1205  interp_method=interp_method, tile_count=tile_count)
1206  call attach_cell_methods(fms_id, axes, cm_string, &
1207  cell_methods, x_cell_method, y_cell_method, v_cell_method, &
1208  v_extensive=v_extensive)
1209  if (is_root_pe() .and. diag_cs%doc_unit > 0) then
1210  msg = ''
1211  if (present(cmor_field_name)) msg = 'CMOR equivalent is "'//trim(cmor_field_name)//'"'
1212  call log_available_diag(fms_id>0, module_name, field_name, cm_string, &
1213  msg, diag_cs, long_name, units, standard_name)
1214  endif
1215  ! Associated horizontally area-averaged diagnostic
1216  fms_xyave_id = diag_field_not_found
1217  if (associated(axes%xyave_axes)) then
1218  fms_xyave_id = register_diag_field_expand_axes(module_name, trim(field_name)//'_xyave', &
1219  axes%xyave_axes, init_time, &
1220  long_name=long_name, units=units, missing_value=mom_missing_value, &
1221  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1222  verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
1223  interp_method=interp_method, tile_count=tile_count)
1224  call attach_cell_methods(fms_xyave_id, axes%xyave_axes, cm_string, &
1225  cell_methods, v_cell_method, v_extensive=v_extensive)
1226  if (is_root_pe() .and. diag_cs%doc_unit > 0) then
1227  msg = ''
1228  if (present(cmor_field_name)) msg = 'CMOR equivalent is "'//trim(cmor_field_name)//'_xyave"'
1229  call log_available_diag(fms_xyave_id>0, module_name, trim(field_name)//'_xyave', cm_string, &
1230  msg, diag_cs, long_name, units, standard_name)
1231  endif
1232  endif
1233  this_diag => null()
1234  if (fms_id /= diag_field_not_found .or. fms_xyave_id /= diag_field_not_found) then
1235  call add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
1236  this_diag%fms_xyave_diag_id = fms_xyave_id
1237 
1238  if (present(v_extensive)) this_diag%v_extensive = v_extensive
1239  if (present(conversion)) this_diag%conversion_factor = conversion
1240  register_diag_field_expand_cmor = .true.
1241  endif
1242 
1243  ! For the CMOR variation of the above diagnostic
1244  if (present(cmor_field_name)) then
1245  ! Fallback values for strings set to "NULL"
1246  posted_cmor_units = "not provided" !
1247  posted_cmor_standard_name = "not provided" ! Values might be able to be replaced with a CS%missing field?
1248  posted_cmor_long_name = "not provided" !
1249 
1250  ! If attributes are present for MOM variable names, use them first for the register_diag_field
1251  ! call for CMOR verison of the variable
1252  if (present(units)) posted_cmor_units = units
1253  if (present(standard_name)) posted_cmor_standard_name = standard_name
1254  if (present(long_name)) posted_cmor_long_name = long_name
1255 
1256  ! If specified in the call to register_diag_field, override attributes with the CMOR versions
1257  if (present(cmor_units)) posted_cmor_units = cmor_units
1258  if (present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
1259  if (present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
1260 
1261  fms_id = register_diag_field_expand_axes(module_name, cmor_field_name, axes, init_time, &
1262  long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1263  missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
1264  standard_name=trim(posted_cmor_standard_name), verbose=verbose, do_not_log=do_not_log, &
1265  err_msg=err_msg, interp_method=interp_method, tile_count=tile_count)
1266  call attach_cell_methods(fms_id, axes, cm_string, &
1267  cell_methods, x_cell_method, y_cell_method, v_cell_method, &
1268  v_extensive=v_extensive)
1269  if (is_root_pe() .and. diag_cs%doc_unit > 0) then
1270  msg = 'native name is "'//trim(field_name)//'"'
1271  call log_available_diag(fms_id>0, module_name, cmor_field_name, cm_string, &
1272  msg, diag_cs, posted_cmor_long_name, posted_cmor_units, &
1273  posted_cmor_standard_name)
1274  endif
1275  ! Associated horizontally area-averaged diagnostic
1276  fms_xyave_id = diag_field_not_found
1277  if (associated(axes%xyave_axes)) then
1278  fms_xyave_id = register_diag_field_expand_axes(module_name, trim(cmor_field_name)//'_xyave', &
1279  axes%xyave_axes, init_time, &
1280  long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1281  missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
1282  standard_name=trim(posted_cmor_standard_name), verbose=verbose, do_not_log=do_not_log, &
1283  err_msg=err_msg, interp_method=interp_method, tile_count=tile_count)
1284  call attach_cell_methods(fms_xyave_id, axes%xyave_axes, cm_string, &
1285  cell_methods, v_cell_method, v_extensive=v_extensive)
1286  if (is_root_pe() .and. diag_cs%doc_unit > 0) then
1287  msg = 'native name is "'//trim(field_name)//'_xyave"'
1288  call log_available_diag(fms_xyave_id>0, module_name, trim(cmor_field_name)//'_xyave', cm_string, &
1289  msg, diag_cs, posted_cmor_long_name, posted_cmor_units, &
1290  posted_cmor_standard_name)
1291  endif
1292  endif
1293  this_diag => null()
1294  if (fms_id /= diag_field_not_found .or. fms_xyave_id /= diag_field_not_found) then
1295  call add_diag_to_list(diag_cs, dm_id, fms_id, this_diag, axes, module_name, field_name, msg)
1296  this_diag%fms_xyave_diag_id = fms_xyave_id
1297 
1298  if (present(v_extensive)) this_diag%v_extensive = v_extensive
1299  if (present(conversion)) this_diag%conversion_factor = conversion
1300  register_diag_field_expand_cmor = .true.
1301  endif
1302  endif
1303 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_scalar_field()

integer function, public mom_diag_mediator::register_scalar_field ( character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
type(time_type), intent(in)  init_time,
type(diag_ctrl), intent(inout)  diag_cs,
character(len=*), intent(in), optional  long_name,
character(len=*), intent(in), optional  units,
real, intent(in), optional  missing_value,
real, dimension(2), intent(in), optional  range,
character(len=*), intent(in), optional  standard_name,
logical, intent(in), optional  do_not_log,
character(len=*), intent(out), optional  err_msg,
character(len=*), intent(in), optional  interp_method,
character(len=*), intent(in), optional  cmor_field_name,
character(len=*), intent(in), optional  cmor_long_name,
character(len=*), intent(in), optional  cmor_units,
character(len=*), intent(in), optional  cmor_standard_name 
)

Definition at line 1486 of file MOM_diag_mediator.F90.

References alloc_diag_with_id(), mom_error_handler::assert(), get_new_diag_id(), mom_error_handler::is_root_pe(), and log_available_diag().

1486  integer :: register_scalar_field
1487  character(len=*), intent(in) :: module_name, field_name
1488  type(time_type), intent(in) :: init_time
1489  type(diag_ctrl), intent(inout) :: diag_cs
1490  character(len=*), optional, intent(in) :: long_name, units, standard_name
1491  real, optional, intent(in) :: missing_value, range(2)
1492  logical, optional, intent(in) :: do_not_log
1493  character(len=*), optional, intent(out):: err_msg
1494  character(len=*), optional, intent(in) :: interp_method
1495  character(len=*), optional, intent(in) :: cmor_field_name, cmor_long_name
1496  character(len=*), optional, intent(in) :: cmor_units, cmor_standard_name
1497 
1498  ! Output: An integer handle for a diagnostic array.
1499  ! Arguments:
1500  ! (in) module_name - name of this module, usually "ocean_model" or "ice_shelf_model".
1501  ! (in) field_name - name of the diagnostic field.
1502  ! (in) init_time - time at which a field is first available?
1503  ! (inout) diag_cs - structure used to regulate diagnostic output
1504  ! (in,opt) long_name - long name of a field
1505  ! (in,opt) units - units of a field
1506  ! (in,opt) missing_value - indicates missing values
1507  ! (in,opt) standard_name - standardized name associated with a field
1508 
1509  ! Following params have yet to be used in MOM.
1510  ! (in,opt) range - valid range of a variable
1511  ! (in,opt) verbose - If true, FMS is verbosed
1512  ! (in,opt) do_not_log - If true, do not log something
1513  ! (out,opt) err_msg - character string into which an error message might be placed
1514  ! (in,opt) interp_method - If 'none' indicates the field should not be interpolated as a scalar
1515  ! (in,opt) tile_count - no clue
1516 
1517  real :: mom_missing_value
1518  integer :: dm_id, fms_id
1519  type(diag_type), pointer :: diag => null(), cmor_diag => null()
1520  character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name
1521 
1522  mom_missing_value = diag_cs%missing_value
1523  if(present(missing_value)) mom_missing_value = missing_value
1524 
1525  dm_id = -1
1526  diag => null()
1527  cmor_diag => null()
1528 
1529  fms_id = register_diag_field_fms(module_name, field_name, init_time, &
1530  long_name=long_name, units=units, missing_value=mom_missing_value, &
1531  range=range, standard_name=standard_name, do_not_log=do_not_log, err_msg=err_msg)
1532  if (fms_id /= diag_field_not_found) then
1533  dm_id = get_new_diag_id(diag_cs)
1534  call alloc_diag_with_id(dm_id, diag_cs, diag)
1535  call assert(associated(diag), 'register_scalar_field: diag allocation failed')
1536  diag%fms_diag_id = fms_id
1537  diag%debug_str = trim(module_name)//"-"//trim(field_name)
1538  endif
1539 
1540  if (present(cmor_field_name)) then
1541  ! Fallback values for strings set to "not provided"
1542  posted_cmor_units = "not provided"
1543  posted_cmor_standard_name = "not provided"
1544  posted_cmor_long_name = "not provided"
1545 
1546  ! If attributes are present for MOM variable names, use them first for the register_static_field
1547  ! call for CMOR verison of the variable
1548  if (present(units)) posted_cmor_units = units
1549  if (present(standard_name)) posted_cmor_standard_name = standard_name
1550  if (present(long_name)) posted_cmor_long_name = long_name
1551 
1552  ! If specified in the call to register_static_field, override attributes with the CMOR versions
1553  if (present(cmor_units)) posted_cmor_units = cmor_units
1554  if (present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
1555  if (present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
1556 
1557  fms_id = register_diag_field_fms(module_name, cmor_field_name, init_time, &
1558  long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1559  missing_value=mom_missing_value, range=range, &
1560  standard_name=trim(posted_cmor_standard_name), do_not_log=do_not_log, err_msg=err_msg)
1561  if (fms_id /= diag_field_not_found) then
1562  if (dm_id == -1) then
1563  dm_id = get_new_diag_id(diag_cs)
1564  endif
1565  call alloc_diag_with_id(dm_id, diag_cs, cmor_diag)
1566  cmor_diag%fms_diag_id = fms_id
1567  cmor_diag%debug_str = trim(module_name)//"-"//trim(cmor_field_name)
1568  endif
1569  endif
1570 
1571  ! Document diagnostics in list of available diagnostics
1572  if (is_root_pe() .and. diag_cs%doc_unit > 0) then
1573  call log_available_diag(associated(diag), module_name, field_name, '', '', diag_cs, &
1574  long_name, units, standard_name)
1575  if (present(cmor_field_name)) then
1576  call log_available_diag(associated(cmor_diag), module_name, cmor_field_name, &
1577  '', '', diag_cs, posted_cmor_long_name, posted_cmor_units, &
1578  posted_cmor_standard_name)
1579  endif
1580  endif
1581 
1582  register_scalar_field = dm_id
1583 
Here is the call graph for this function:

◆ register_static_field()

integer function, public mom_diag_mediator::register_static_field ( character(len=*), intent(in)  module_name,
character(len=*), intent(in)  field_name,
type(axes_grp), intent(in)  axes,
character(len=*), intent(in), optional  long_name,
character(len=*), intent(in), optional  units,
real, intent(in), optional  missing_value,
real, dimension(2), intent(in), optional  range,
logical, intent(in), optional  mask_variant,
character(len=*), intent(in), optional  standard_name,
logical, intent(in), optional  do_not_log,
character(len=*), intent(in), optional  interp_method,
integer, intent(in), optional  tile_count,
character(len=*), intent(in), optional  cmor_field_name,
character(len=*), intent(in), optional  cmor_long_name,
character(len=*), intent(in), optional  cmor_units,
character(len=*), intent(in), optional  cmor_standard_name,
integer, intent(in), optional  area 
)

Registers a static diagnostic, returning an integer handle.

Parameters
[in]areafms_id for area_t

Definition at line 1591 of file MOM_diag_mediator.F90.

References alloc_diag_with_id(), mom_error_handler::assert(), get_new_diag_id(), mom_error_handler::is_root_pe(), and log_available_diag().

Referenced by mom_geothermal::geothermal_init().

1591  integer :: register_static_field
1592  character(len=*), intent(in) :: module_name, field_name
1593  type(axes_grp), intent(in) :: axes
1594  character(len=*), optional, intent(in) :: long_name, units, standard_name
1595  real, optional, intent(in) :: missing_value, range(2)
1596  logical, optional, intent(in) :: mask_variant, do_not_log
1597  character(len=*), optional, intent(in) :: interp_method
1598  integer, optional, intent(in) :: tile_count
1599  character(len=*), optional, intent(in) :: cmor_field_name, cmor_long_name
1600  character(len=*), optional, intent(in) :: cmor_units, cmor_standard_name
1601  integer, optional, intent(in) :: area !< fms_id for area_t
1602 
1603  ! Output: An integer handle for a diagnostic array.
1604  ! Arguments:
1605  ! (in) module_name - name of this module, usually "ocean_model" or "ice_shelf_model".
1606  ! (in) field_name - name of the diagnostic field
1607  ! (in) axes - container with up to 3 integer handles that indicates axes for this field
1608  ! (in,opt) long_name - long name of a field
1609  ! (in,opt) units - units of a field
1610  ! (in,opt) missing_value - A value that indicates missing values.
1611  ! (in,opt) standard_name - standardized name associated with a field
1612 
1613  ! Following params have yet to be used in MOM.
1614  ! (in,opt) range - valid range of a variable
1615  ! (in,opt) mask_variant - If true a logical mask must be provided with post_data calls
1616  ! (in,opt) do_not_log - If true, do not log something
1617  ! (in,opt) interp_method - If 'none' indicates the field should not be interpolated as a scalar
1618  ! (in,opt) tile_count - no clue
1619 
1620  real :: mom_missing_value
1621  type(diag_ctrl), pointer :: diag_cs
1622  type(diag_type), pointer :: diag => null(), cmor_diag => null()
1623  integer :: dm_id, fms_id, cmor_id
1624  character(len=256) :: posted_cmor_units, posted_cmor_standard_name, posted_cmor_long_name
1625 
1626  mom_missing_value = axes%diag_cs%missing_value
1627  if(present(missing_value)) mom_missing_value = missing_value
1628 
1629  diag_cs => axes%diag_cs
1630  dm_id = -1
1631  diag => null()
1632  cmor_diag => null()
1633 
1634  fms_id = register_static_field_fms(module_name, field_name, axes%handles, &
1635  long_name=long_name, units=units, missing_value=mom_missing_value, &
1636  range=range, mask_variant=mask_variant, standard_name=standard_name, &
1637  do_not_log=do_not_log, &
1638  interp_method=interp_method, tile_count=tile_count, area=area)
1639  if (fms_id /= diag_field_not_found) then
1640  dm_id = get_new_diag_id(diag_cs)
1641  call alloc_diag_with_id(dm_id, diag_cs, diag)
1642  call assert(associated(diag), 'register_static_field: diag allocation failed')
1643  diag%fms_diag_id = fms_id
1644  diag%debug_str = trim(module_name)//"-"//trim(field_name)
1645  endif
1646 
1647  if (present(cmor_field_name)) then
1648  ! Fallback values for strings set to "not provided"
1649  posted_cmor_units = "not provided"
1650  posted_cmor_standard_name = "not provided"
1651  posted_cmor_long_name = "not provided"
1652 
1653  ! If attributes are present for MOM variable names, use them first for the register_static_field
1654  ! call for CMOR verison of the variable
1655  if (present(units)) posted_cmor_units = units
1656  if (present(standard_name)) posted_cmor_standard_name = standard_name
1657  if (present(long_name)) posted_cmor_long_name = long_name
1658 
1659  ! If specified in the call to register_static_field, override attributes with the CMOR versions
1660  if (present(cmor_units)) posted_cmor_units = cmor_units
1661  if (present(cmor_standard_name)) posted_cmor_standard_name = cmor_standard_name
1662  if (present(cmor_long_name)) posted_cmor_long_name = cmor_long_name
1663 
1664  fms_id = register_static_field_fms(module_name, cmor_field_name, &
1665  axes%handles, long_name=trim(posted_cmor_long_name), units=trim(posted_cmor_units), &
1666  missing_value=mom_missing_value, range=range, mask_variant=mask_variant, &
1667  standard_name=trim(posted_cmor_standard_name), do_not_log=do_not_log, &
1668  interp_method=interp_method, tile_count=tile_count, area=area)
1669  if (fms_id /= diag_field_not_found) then
1670  if (dm_id == -1) then
1671  dm_id = get_new_diag_id(diag_cs)
1672  endif
1673  call alloc_diag_with_id(dm_id, diag_cs, cmor_diag)
1674  cmor_diag%fms_diag_id = fms_id
1675  cmor_diag%debug_str = trim(module_name)//"-"//trim(cmor_field_name)
1676  endif
1677  endif
1678 
1679  ! Document diagnostics in list of available diagnostics
1680  if (is_root_pe() .and. diag_cs%doc_unit > 0) then
1681  call log_available_diag(associated(diag), module_name, field_name, '', '', diag_cs, &
1682  long_name, units, standard_name)
1683  if (present(cmor_field_name)) then
1684  call log_available_diag(associated(cmor_diag), module_name, cmor_field_name, &
1685  '', '', diag_cs, posted_cmor_long_name, posted_cmor_units, &
1686  posted_cmor_standard_name)
1687  endif
1688  endif
1689 
1690  register_static_field = dm_id
1691 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_axes_info()

subroutine, public mom_diag_mediator::set_axes_info ( type(ocean_grid_type), intent(inout)  G,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
type(diag_ctrl), intent(inout)  diag_cs,
logical, intent(in), optional  set_vertical 
)

Sets up diagnostics axes.

Parameters
[in,out]gOcean grid structure
[in]gvocean vertical grid structure
[in]param_fileParameter file structure
[in,out]diag_csDiagnostics control structure
[in]set_verticalIf true or missing, set up vertical axes

Definition at line 213 of file MOM_diag_mediator.F90.

References define_axes_group().

Referenced by mom::initialize_mom().

213  type(ocean_grid_type), intent(inout) :: g !< Ocean grid structure
214  type(verticalgrid_type), intent(in) :: gv !< ocean vertical grid structure
215  type(param_file_type), intent(in) :: param_file !< Parameter file structure
216  type(diag_ctrl), intent(inout) :: diag_cs !< Diagnostics control structure
217  logical, optional, intent(in) :: set_vertical !< If true or missing, set up
218  !! vertical axes
219  ! Local variables
220  integer :: id_xq, id_yq, id_zl, id_zi, id_xh, id_yh
221  integer :: i, k, nz
222  real :: zlev(gv%ke), zinter(gv%ke+1)
223  logical :: set_vert
224 
225  set_vert = .true. ; if (present(set_vertical)) set_vert = set_vertical
226 
227  if(g%symmetric) then
228  id_xq = diag_axis_init('xq', g%gridLonB(g%isgB:g%iegB), g%x_axis_units, 'x', &
229  'q point nominal longitude', domain2=g%Domain%mpp_domain)
230  id_yq = diag_axis_init('yq', g%gridLatB(g%jsgB:g%jegB), g%y_axis_units, 'y', &
231  'q point nominal latitude', domain2=g%Domain%mpp_domain)
232  else
233  id_xq = diag_axis_init('xq', g%gridLonB(g%isg:g%ieg), g%x_axis_units, 'x', &
234  'q point nominal longitude', domain2=g%Domain%mpp_domain)
235  id_yq = diag_axis_init('yq', g%gridLatB(g%jsg:g%jeg), g%y_axis_units, 'y', &
236  'q point nominal latitude', domain2=g%Domain%mpp_domain)
237  endif
238  id_xh = diag_axis_init('xh', g%gridLonT(g%isg:g%ieg), g%x_axis_units, 'x', &
239  'h point nominal longitude', domain2=g%Domain%mpp_domain)
240  id_yh = diag_axis_init('yh', g%gridLatT(g%jsg:g%jeg), g%y_axis_units, 'y', &
241  'h point nominal latitude', domain2=g%Domain%mpp_domain)
242 
243  if (set_vert) then
244  nz = gv%ke
245  zinter(1:nz+1) = gv%sInterface(1:nz+1)
246  zlev(1:nz) = gv%sLayer(1:nz)
247  id_zl = diag_axis_init('zl', zlev, trim(gv%zAxisUnits), 'z', &
248  'Layer '//trim(gv%zAxisLongName), &
249  direction=gv%direction)
250  id_zi = diag_axis_init('zi', zinter, trim(gv%zAxisUnits), 'z', &
251  'Interface '//trim(gv%zAxisLongName), &
252  direction=gv%direction)
253  else
254  id_zl = -1 ; id_zi = -1
255  endif
256 
257  ! Vertical axes for the interfaces and layers
258  call define_axes_group(diag_cs, (/ id_zi /), diag_cs%axesZi, &
259  v_cell_method='point', is_interface=.true.)
260  call define_axes_group(diag_cs, (/ id_zl /), diag_cs%axesZL, &
261  v_cell_method='mean', is_layer=.true.)
262 
263  ! Axis groupings for the model layers
264  call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zl /), diag_cs%axesTL, &
265  x_cell_method='mean', y_cell_method='mean', v_cell_method='mean', &
266  is_h_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
267  call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zl /), diag_cs%axesBL, &
268  x_cell_method='point', y_cell_method='point', v_cell_method='mean', &
269  is_q_point=.true., is_layer=.true.)
270  call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zl /), diag_cs%axesCuL, &
271  x_cell_method='point', y_cell_method='mean', v_cell_method='mean', &
272  is_u_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
273  call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zl /), diag_cs%axesCvL, &
274  x_cell_method='mean', y_cell_method='point', v_cell_method='mean', &
275  is_v_point=.true., is_layer=.true., xyave_axes=diag_cs%axesZL)
276 
277  ! Axis groupings for the model interfaces
278  call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zi /), diag_cs%axesTi, &
279  x_cell_method='mean', y_cell_method='mean', v_cell_method='point', &
280  is_h_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
281  call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zi /), diag_cs%axesBi, &
282  x_cell_method='point', y_cell_method='point', v_cell_method='point', &
283  is_q_point=.true., is_interface=.true.)
284  call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zi /), diag_cs%axesCui, &
285  x_cell_method='point', y_cell_method='mean', v_cell_method='point', &
286  is_u_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
287  call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zi /), diag_cs%axesCvi, &
288  x_cell_method='mean', y_cell_method='point', v_cell_method='point', &
289  is_v_point=.true., is_interface=.true., xyave_axes=diag_cs%axesZi)
290 
291  ! Axis groupings for 2-D arrays
292  call define_axes_group(diag_cs, (/ id_xh, id_yh /), diag_cs%axesT1, &
293  x_cell_method='mean', y_cell_method='mean', is_h_point=.true.)
294  call define_axes_group(diag_cs, (/ id_xq, id_yq /), diag_cs%axesB1, &
295  x_cell_method='point', y_cell_method='point', is_q_point=.true.)
296  call define_axes_group(diag_cs, (/ id_xq, id_yh /), diag_cs%axesCu1, &
297  x_cell_method='point', y_cell_method='mean', is_u_point=.true.)
298  call define_axes_group(diag_cs, (/ id_xh, id_yq /), diag_cs%axesCv1, &
299  x_cell_method='mean', y_cell_method='point', is_v_point=.true.)
300 
301  if (diag_cs%num_diag_coords>0) then
302  allocate(diag_cs%remap_axesZL(diag_cs%num_diag_coords))
303  allocate(diag_cs%remap_axesTL(diag_cs%num_diag_coords))
304  allocate(diag_cs%remap_axesBL(diag_cs%num_diag_coords))
305  allocate(diag_cs%remap_axesCuL(diag_cs%num_diag_coords))
306  allocate(diag_cs%remap_axesCvL(diag_cs%num_diag_coords))
307  allocate(diag_cs%remap_axesZi(diag_cs%num_diag_coords))
308  allocate(diag_cs%remap_axesTi(diag_cs%num_diag_coords))
309  allocate(diag_cs%remap_axesBi(diag_cs%num_diag_coords))
310  allocate(diag_cs%remap_axesCui(diag_cs%num_diag_coords))
311  allocate(diag_cs%remap_axesCvi(diag_cs%num_diag_coords))
312  endif
313 
314  do i=1, diag_cs%num_diag_coords
315  ! For each possible diagnostic coordinate
316  call diag_remap_configure_axes(diag_cs%diag_remap_cs(i), gv, param_file)
317 
318  ! This vertical coordinate has been configured so can be used.
319  if (diag_remap_axes_configured(diag_cs%diag_remap_cs(i))) then
320 
321  ! This fetches the 1D-axis id for layers and interfaces and overwrite
322  ! id_zl and id_zi from above. It also returns the number of layers.
323  call diag_remap_get_axes_info(diag_cs%diag_remap_cs(i), nz, id_zl, id_zi)
324 
325  ! Axes for z layers
326  call define_axes_group(diag_cs, (/ id_zl /), diag_cs%remap_axesZL(i), &
327  nz=nz, vertical_coordinate_number=i, &
328  v_cell_method='mean', &
329  is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true.)
330  call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zl /), diag_cs%remap_axesTL(i), &
331  nz=nz, vertical_coordinate_number=i, &
332  x_cell_method='mean', y_cell_method='mean', v_cell_method='mean', &
333  is_h_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
334  xyave_axes=diag_cs%remap_axesZL(i))
335 
336  !! \note Remapping for B points is not yet implemented so needs_remapping is not provided for remap_axesBL
337  call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zl /), diag_cs%remap_axesBL(i), &
338  nz=nz, vertical_coordinate_number=i, &
339  x_cell_method='point', y_cell_method='point', v_cell_method='mean', &
340  is_q_point=.true., is_layer=.true., is_native=.false.)
341 
342  call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zl /), diag_cs%remap_axesCuL(i), &
343  nz=nz, vertical_coordinate_number=i, &
344  x_cell_method='point', y_cell_method='mean', v_cell_method='mean', &
345  is_u_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
346  xyave_axes=diag_cs%remap_axesZL(i))
347 
348  call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zl /), diag_cs%remap_axesCvL(i), &
349  nz=nz, vertical_coordinate_number=i, &
350  x_cell_method='mean', y_cell_method='point', v_cell_method='mean', &
351  is_v_point=.true., is_layer=.true., is_native=.false., needs_remapping=.true., &
352  xyave_axes=diag_cs%remap_axesZL(i))
353 
354  ! Axes for z interfaces
355  call define_axes_group(diag_cs, (/ id_zi /), diag_cs%remap_axesZi(i), &
356  nz=nz, vertical_coordinate_number=i, &
357  v_cell_method='point', &
358  is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true.)
359  call define_axes_group(diag_cs, (/ id_xh, id_yh, id_zi /), diag_cs%remap_axesTi(i), &
360  nz=nz, vertical_coordinate_number=i, &
361  x_cell_method='mean', y_cell_method='mean', v_cell_method='point', &
362  is_h_point=.true., is_interface=.true., is_native=.false., needs_interpolating=.true., &
363  xyave_axes=diag_cs%remap_axesZi(i))
364 
365  !! \note Remapping for B points is not yet implemented so needs_remapping is not provided for remap_axesBi
366  call define_axes_group(diag_cs, (/ id_xq, id_yq, id_zi /), diag_cs%remap_axesBi(i), &
367  nz=nz, vertical_coordinate_number=i, &
368  x_cell_method='point', y_cell_method='point', v_cell_method='point', &
369  is_q_point=.true., is_interface=.true., is_native=.false.)
370 
371  call define_axes_group(diag_cs, (/ id_xq, id_yh, id_zi /), diag_cs%remap_axesCui(i), &
372  nz=nz, vertical_coordinate_number=i, &
373  x_cell_method='point', y_cell_method='mean', v_cell_method='point', &
374  is_u_point=.true., is_interface=.true., is_native=.false., &
375  needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
376 
377  call define_axes_group(diag_cs, (/ id_xh, id_yq, id_zi /), diag_cs%remap_axesCvi(i), &
378  nz=nz, vertical_coordinate_number=i, &
379  x_cell_method='mean', y_cell_method='point', v_cell_method='point', &
380  is_v_point=.true., is_interface=.true., is_native=.false., &
381  needs_interpolating=.true., xyave_axes=diag_cs%remap_axesZi(i))
382  endif
383  enddo
384 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_diag_mask()

subroutine mom_diag_mediator::set_diag_mask ( type(diag_type), intent(inout), pointer  diag,
type(diag_ctrl), intent(in), target  diag_cs,
type(axes_grp), intent(in)  axes 
)
private

Associates the mask pointers within diag with the appropriate mask based on the axes group.

Parameters
[in]diag_csDiag_mediator control structure
[in,out]diagThis diag type
[in]axesAxes group

Definition at line 2113 of file MOM_diag_mediator.F90.

Referenced by add_diag_to_list().

2113  type(diag_ctrl), target, intent(in) :: diag_cs !< Diag_mediator control structure
2114  type(diag_type), pointer, intent(inout) :: diag !< This diag type
2115  type(axes_grp), intent(in) :: axes !< Axes group
2116 
2117  diag%mask2d => null()
2118  diag%mask3d => null()
2119 
2120  if (axes%rank .eq. 3) then
2121  if (axes%is_layer) then
2122  if (axes%is_h_point) then
2123  diag%mask3d => diag_cs%mask3dTL
2124  elseif (axes%is_q_point) then
2125  diag%mask3d => diag_cs%mask3dBL
2126  elseif (axes%is_u_point) then
2127  diag%mask3d => diag_cs%mask3dCuL
2128  elseif (axes%is_v_point) then
2129  diag%mask3d => diag_cs%mask3dCvL
2130  endif
2131  elseif (axes%is_interface) then
2132  if (axes%is_h_point) then
2133  diag%mask3d => diag_cs%mask3dTi
2134  elseif (axes%is_q_point) then
2135  diag%mask3d => diag_cs%mask3dBi
2136  elseif (axes%is_u_point) then
2137  diag%mask3d => diag_cs%mask3dCui
2138  elseif (axes%is_v_point) then
2139  diag%mask3d => diag_cs%mask3dCvi
2140  endif
2141  endif
2142 
2143  !call assert(associated(diag%mask3d), "set_diag_mask: Invalid 3d axes id."// &
2144  ! " diag:"//diag%debug_str)
2145  elseif(axes%rank .eq. 2) then
2146 
2147  if (axes%is_h_point) then
2148  diag%mask2d => diag_cs%mask2dT
2149  elseif (axes%is_q_point) then
2150  diag%mask2d => diag_cs%mask2dBu
2151  elseif (axes%is_u_point) then
2152  diag%mask2d => diag_cs%mask2dCu
2153  elseif (axes%is_v_point) then
2154  diag%mask2d => diag_cs%mask2dCv
2155  endif
2156 
2157  !call assert(associated(diag%mask2d), "set_diag_mask.F90: Invalid 2d axes id."// &
2158  ! " diag:"//diag%debug_str)
2159  endif
2160 
Here is the caller graph for this function:

◆ set_diag_mediator_grid()

subroutine, public mom_diag_mediator::set_diag_mediator_grid ( type(ocean_grid_type), intent(inout)  G,
type(diag_ctrl), intent(inout)  diag_cs 
)
Parameters
[in,out]gThe ocean's grid structure

Definition at line 501 of file MOM_diag_mediator.F90.

501  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure
502  type(diag_ctrl), intent(inout) :: diag_cs
503 
504 ! Arguments:
505 ! (inout) G - ocean grid structure
506 ! (inout) diag - structure used to regulate diagnostic output
507 
508  diag_cs%is = g%isc - (g%isd-1) ; diag_cs%ie = g%iec - (g%isd-1)
509  diag_cs%js = g%jsc - (g%jsd-1) ; diag_cs%je = g%jec - (g%jsd-1)
510  diag_cs%isd = g%isd ; diag_cs%ied = g%ied
511  diag_cs%jsd = g%jsd ; diag_cs%jed = g%jed
512 

Variable Documentation

◆ id_clock_diag_grid_updates

integer mom_diag_mediator::id_clock_diag_grid_updates
private

Definition at line 207 of file MOM_diag_mediator.F90.

Referenced by diag_mediator_init(), and diag_update_remap_grids().

◆ id_clock_diag_mediator

integer mom_diag_mediator::id_clock_diag_mediator

Definition at line 207 of file MOM_diag_mediator.F90.

Referenced by diag_mediator_init(), post_data_0d(), post_data_1d_k(), post_data_2d(), and post_data_3d().

207 integer :: id_clock_diag_mediator, id_clock_diag_remap, id_clock_diag_grid_updates

◆ id_clock_diag_remap

integer mom_diag_mediator::id_clock_diag_remap
private

Definition at line 207 of file MOM_diag_mediator.F90.

Referenced by diag_mediator_init(), and post_data_3d().