PUBLIC INTERFACE ~ PUBLIC ROUTINES ~ ERROR MESSAGES

## Module diag_util_mod

Contact: Seth Underwood
Reviewers:
Change History: WebCVS Log

#### OVERVIEW

Functions and subroutines necessary for the `diag_manager_mod`.

`diag_util_mod` is a set of Fortran functions and subroutines used by the `diag_manager_mod`.

#### OTHER MODULES USED

       diag_data_mod
       diag_axis_mod
     diag_output_mod
       diag_grid_mod
             fms_mod
          fms_io_mod
     mpp_domains_mod
    time_manager_mod
          mpp_io_mod
             mpp_mod
       constants_mod

#### PUBLIC INTERFACE

get_subfield_size:
  Get the size, start, and end indices for output fields.
get_subfield_vert_size:
  Get size, start and end indices for output fields.
log_diag_field_info:
  Writes brief diagnostic field info to the log file.
update_bounds:
  Update the `output_fields` min and max boundaries.
check_out_of_bounds:
  Checks if the array indices for `output_fields(out_num)` are outside the `output_fields(out_num)%buffer` upper and lower bounds.
check_bounds_are_exact_dynamic:
  Check if the array indices for `output_fields(out_num)` are equal to the `output_fields(out_num)%buffer` upper and lower bounds.
check_bounds_are_exact_static:
  Check if the array indices for `output_fields(out_num)` are equal to the `output_fields(out_num)%buffer` upper and lower bounds.
init_file:
  Initialize the output file.
sync_file_times:
  Synchronize the file's start and close times with the model start and end times.
diag_time_inc:
  Return the next time data/file is to be written based on the frequency and units.
find_input_field:
  Return the field number for the given module name, field name, and tile number.
init_input_field:
  Initialize the input field.
init_output_field:
  Initialize the output field.
get_date_dif:
  Return the difference between two times in units.
diag_data_out:
  Write data out to file.
write_static:
  Output all static fields in this file
check_duplicate_output_fields:
  Checks to see if `output_name` and `output_file` are unique in `output_fields`.

#### PUBLIC ROUTINES

1. #### get_subfield_size

       SUBROUTINE get_subfield_size (axes, outnum)

   DESCRIPTION
     Get the size, start and end indices for `output_fields(outnum)`, then fill in `output_fields(outnum)%output_grid%(start_indx, end_indx)`
   INPUT

     `axes` | Axes of the `input_field`. [INTEGER, DIMENSION(:)]
     `outnum` | Position in array `output_fields`. [INTEGER]

2. #### get_subfield_vert_size

       SUBROUTINE get_subfield_vert_size (axes, outnum)

   DESCRIPTION
     Get size, start and end indices for `output_fields(outnum)`, fill in `output_fields(outnum)%output_grid%(start_indx, end_indx)`.
   INPUT

     `axes` | Axes of the `input_field` [INTEGER, DIMENSION(:)]
     `outnum` | Position in array `output_fields`. [INTEGER]

3. #### log_diag_field_info

       SUBROUTINE log_diag_field_info (module_name, field_name, axes, long_name, units, missing_value, range, dynamic)

   DESCRIPTION
     If the `do_diag_field_log` namelist parameter is .TRUE., then a line briefly describing diagnostic field is added to the log file. Normally users should not call this subroutine directly, since it is called by register_static_field and register_diag_field if do_not_log is not set to .TRUE.. It is used, however, in LM3 to avoid excessive logs due to the number of fields registered for each of the tile types. LM3 code uses a do_not_log parameter in the registration calls, and subsequently calls this subroutine to log field information under a generic name.
   INPUT

     `module_name` | Module name. [CHARACTER(len=*)]
     `field_name` | Field name. [CHARACTER(len=*)]
     `axes` | Axis IDs. [INTEGER, DIMENSION(:)]
     `long_name` | Long name for field. [CHARACTER(len=*), OPTIONAL]
     `units` | Unit of field. [CHARACTER(len=*), OPTIONAL]
     `missing_value` | Missing value value. [REAL, OPTIONAL]
     `range` | Valid range of values for field. [REAL, DIMENSION(2), OPTIONAL]
     `dynamic` | `.TRUE.` if field is not static. [LOGICAL, OPTIONAL]

4. #### update_bounds

       SUBROUTINE update_bounds (out_num, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k)

   DESCRIPTION
     Update the `output_fields` x, y, and z min and max boundaries (array indices).
   INPUT

     `out_num` | `output_field` ID. [INTEGER]
     `lower_i` | Lower `i` bound. [INTEGER]
     `upper_i` | Upper `i` bound. [INTEGER]
     `lower_j` | Lower `j` bound. [INTEGER]
     `upper_j` | Upper `j` bound. [INTEGER]
     `lower_k` | Lower `k` bound. [INTEGER]
     `upper_k` | Upper `k` bound. [INTEGER]

5. #### check_out_of_bounds

       SUBROUTINE check_out_of_bounds (out_num, diag_field_id, err_msg)

   DESCRIPTION
     `check_out_of_bounds` verifies the array min and max indices in the x, y, and z directions of `output_fields(out_num)` are not outside the upper and lower array boundaries of `output_fields(out_num)%buffer`. If the min and max indices are outside the upper and lower bounds of the buffer array, then `check_out_of_bounds` returns an error string.
   INPUT

     `out_num` | Output field ID number. [INTEGER]
     `diag_field_id` | Input field ID number. [INTEGER]

   OUTPUT

     `err_msg` | Return status of `check_out_of_bounds`. An empty error string indicates the x, y, and z indices are not outside the buffer array boundaries. [CHARACTER(len=*)]

6. #### check_bounds_are_exact_dynamic

       SUBROUTINE check_bounds_are_exact_dynamic (out_num, diag_field_id, Time, err_msg)

   DESCRIPTION
     `check_bounds_are_exact_dynamic` checks if the min and max array indices for `output_fields(out_num)` are equal to the upper and lower bounds of `output_fields(out_num)%buffer`. This check is only performed if `output_fields(out_num)%Time_of_prev_field_data` doesn't equal `Time` or `Time_zero`. `check_bounds_are_exact_dynamic` returns an error string if the array indices do not match the buffer bounds.
   INPUT

     `out_num` | Output field ID number. [INTEGER]
     `diag_field_id` | Input field ID number. [INTEGER]
     `Time` | Time to use in check. The check is only performed if `output_fields(out_num)%Time_of_prev_field_data` is not equal to `Time` or `Time_zero`. [TYPE(time_type)]

   OUTPUT

     `err_msg` | Return status of `check_bounds_are_exact_dynamic`. An empty error string indicates the x, y, and z indices are equal to the buffer array boundaries. [CHARACTER(len=*)]

7. #### check_bounds_are_exact_static

       SUBROUTINE check_bounds_are_exact_static (out_num, diag_field_id, err_msg)

   DESCRIPTION
   INPUT

     `out_num` | Output field ID [INTEGER]
     `diag_field_id` | Input field ID. [INTEGER]

   OUTPUT

     `err_msg` | [CHARACTER(len=*)]

8. #### init_file

       SUBROUTINE init_file (name, output_freq, output_units, format, time_units long_name, tile_count, new_file_freq, new_file_freq_units, start_time, file_duration, file_duration_units)

   DESCRIPTION
     Initialize the output file.
   INPUT

     `name` | File name. [CHARACTER(len=*)]
     `output_freq` | How often data is to be written to the file. [INTEGER]
     `output_units` | The output frequency unit. (MIN, HOURS, DAYS, etc.) [INTEGER]
     `format` | Number type/kind the data is to be written out to the file. [INTEGER]
     `time_units` | Time axis units. [INTEGER]
     `log_name` | Long name for time axis. [CHARACTER(len=*)]
     `tile_count` | Tile number. [INTEGER]
     `new_file_freq` | How often a new file is to be created. [INTEGER, OPTIONAL]
     `new_file_freq_units` | The new file frequency unit. (MIN, HOURS, DAYS, etc.) [INTEGER, OPTIONAL]
     `start_time` | Time when the file is to start [TYPE(time_type), OPTIONAL]
     `file_duration` | How long file is to be used. [INTEGER, OPTIONAL]
     `file_duration_units` | File duration unit. (MIN, HOURS, DAYS, etc.) [INTEGER, OPTIONAL]

9. #### sync_file_times

       SUBROUTINE sync_file_times (init_time)

   DESCRIPTION
     `sync_file_times` checks to see if the file start time is less than the model's init time (passed in as the only argument). If it is less, then the both the file start time and end time are synchronized using the passed in initial time and the duration as calculated by the `diag_time_inc` function. `sync_file_times` will also increase the `next_open` until it is greater than the init_time.
   INPUT

     `file_id` | The file ID [INTEGER]
     `init_time` | Initial time use for the synchronization. [TYPE(time_type)]

   OUTPUT

     `err_msg` | Return error message [CHARACTER(len=*), OPTIONAL]

10. #### diag_time_inc

        TYPE(time_type) FUNCTION diag_time_inc (time, output_freq, output_units, err_msg)

    DESCRIPTION
      Return the next time data/file is to be written. This value is based on the current time and the frequency and units. Function completed successful if the optional `err_msg` is empty.
    INPUT

      `time` | Current model time. [TYPE(time_type)]
      `output_freq` | Output frequency number value. [INTEGER]
      `output_units` | Output frequency unit. [INTEGER]

    OUTPUT

      `err_msg` | Function error message. An empty string indicates the next output time was found successfully. [CHARACTER, OPTIONAL]

11. #### find_input_field

        INTEGER FUNCTION find_input_field (module_name, field_name, tile_count)

    DESCRIPTION
      Return the field number for the given module name, field name and tile number. A return value of `-1` indicates the field was not found.
    INPUT

      `module_name` | Module name. [CHARACTER(len=*)]
      `field_name` | field name. [CHARACTER(len=*)]
      `tile_count` | Tile number. [INTEGER]

12. #### init_input_field

        SUBROUTINE init_input_field (module_name, field_name, tile_count)

    DESCRIPTION
    INPUT

      `module_name` | Module name. [CHARACTER(len=*)]
      `field_name` | Input field name. [CHARACTER(len=*)]
      `tile_count` | Tile number. [INTEGER]

13. #### init_output_field

        SUBROUTINE init_output_field (module_name, field_name, output_name, output_file time_method, pack, tile_count, local_coord)

    DESCRIPTION
      Initialize the output field.
    INPUT

      `module_name` | Module name. [CHARACTER(len=*)]
      `field_name` | Output field name. [CHARACTER(len=*)]
      `output_name` | Output name written to file. [CHARACTER(len=*)]
      `output_file` | File where field should be written. [CHARACTER(len=*)]
      `time_method` | Data reduction method. See diag_manager_mod for valid methods. [CHARACTER(len=*)]
      `pack` | Packing method. [INTEGER]
      `tile_count` | Tile number. [INTEGER]
      `local_coord` | Region to be written. If missing, then all data to be written. [INTEGER, OPTIONAL]

14. #### get_date_dif

        REAL FUNCTION get_date_dif (t2, t1, units)

    DESCRIPTION
      Calculate and return the difference between the two times given in the unit given using the function `t2 - t1`.
    INPUT

      `t2` | Most recent time. [TYPE(time_type)]
      `t1` | Most distant time. [TYPE(time_type)]
      `units` | Unit of return value. [INTEGER]

15. #### diag_data_out

        SUBROUTINE diag_data_out (file, field, dat, time, fianl_call_in, static_write_in)

    DESCRIPTION
      Write data out to file, and if necessary flush the buffers.
    INPUT

      `file` | File ID. [INTEGER]
      `field` | Field ID. [INTEGER]
      `time` | Current model time. [TYPE(time_type)]
      `final_call_in` | `.TRUE.` if this is the last write for file. [LOGICAL, OPTIONAL]
      `static_write_in` | `.TRUE.` if static fields are to be written to file. [LOGICAL, OPTIONAL]

    INPUT/OUTPUT

      `dat` | Data to write out. [REAL, DIMENSION(:,:,:,:)]

16. #### write_static

        SUBROUTINE write_static (file)

    DESCRIPTION
      Write the static data to the file.
    INPUT

      `file` | File ID. [INTEGER]

17. #### check_duplicate_output_fields

        SUBROUTINE check_duplicate_output_fields (err_msg)

    DESCRIPTION
      Check to see if `output_name` and `output_file` are unique in `output_fields`. An empty `err_msg` indicates no duplicates found.
    OUTPUT

      `err_msg` | Error message. If empty, then no duplicates found. [CHARACTER(len=*), OPTIONAL]

#### ERROR MESSAGES

FATAL in get_subfield_size
  wrong order of axes. X should come first.
FATAL in get_subfield_size
  wrong order of axes, Y should come second.
FATAL in get_subfield_size
  wrong values in vertical axis of region
FATAL in get_subfield_size
  i should equal 3 for z axis
FATAL in get_subfield_size
  Wrong axis_cart
FATAL in get_subfield_size
  can not find gstart_indx/gend_indx for <output_fields(outnum)%output_name>, check region bounds for axis <i>.
FATAL in get_subfield_size
  axis(3) should be Z-axis
FATAL in get_subfield_size
  wrong values in vertical axis of region
FATAL in get_subfield_size
  No domain available
FATAL in get_subfield_size
  wrong compute domain indices
FATAL in get_subfield_size
  <output_fields(outnum)%output_name> error at i = <i>
FATAL in get_subfield_vert_size
  wrong order of axes, X should come first
FATAL in get_subfield_vert_size
  wrong order of axes, Y should come second
FATAL in get_subfield_vert_size
  wrong values in vertical axis of region
FATAL in get_subfield_vert_size
  i should equal 3 for z axis
FATAL in get_subfield_vert_size
  Wrong axis_cart
FATAL in get_subfield_vert_size
  can not find gstart_indx/gend_indx for <output_fields(outnum)%output_name> check region bounds for axis
FATAL in init_file
  max_files exceeded, increase max_files via the max_files variable in the namelist diag_manager_nml.
FATAL in init_file
  close time GREATER than next_open time, check file duration, file frequency in <files(num_files)%name>
FATAL in init_input_field
  max_input_fields exceeded, increase it via diag_manager_nml
FATAL in init_output_field
  max_output_fields = <max_output_fields> exceeded. Increase via diag_manager_nml
FATAL in init_output_field
  module_name/field_name <module_name>/<field_name>[/tile_count=<tile_count>] NOT registered
FATAL in init_output_field
  MAX_OUT_PER_IN_FIELD = <MAX_OUT_PER_IN_FIELD> exceeded for <module_name>/<field_name>, increase MAX_OUT_PER_IN_FIELD in diag_data.F90.
FATAL in init_output_field
  file <file_name> is NOT found in the diag_table.
FATAL in init_output_field
  file <output_file> is not initialized for tile_count = <tile_count>
FATAL in init_output_field
  MAX_FIELDS_PER_FILE = <MAX_FIELDS_PER_FILE> exceeded. Increase MAX_FIELDS_PER_FILE in diag_data.F90.
FATAL in init_output_field
  could not find integer number of diurnal samples in string "<t_method>"
FATAL in init_output_field
  The integer value of diurnal samples must be greater than zero.
FATAL in init_output_field
  improper time method in diag_table for output field <output_name>
FATAL in get_date_dif
  variable t2 is less than in variable t1
FATAL in get_date_dif
  months not supported as output units
FATAL in get_date_dif
  years not suppored as output units
FATAL in get_date_dif
  illegal time units

#### FUTURE PLANS

- Make an interface `check_bounds_are_exact` for the subroutines `check_bounds_are_exact_static` and `check_bounds_are_exact_dynamic`.

             INTERFACE check_bounds_are_exact
               MODULE PROCEDURE check_bounds_are_exact_static
               MODULE PROCEDURE check_bounds_are_exact_dynamic
             END INTERFACE check_bounds_are_exact

top