PUBLIC INTERFACE ~ PUBLIC DATA ~ PUBLIC ROUTINES ~ NAMELIST ~ DIAGNOSTIC FIELDS ~ ERROR MESSAGES ~ REFERENCES ~ NOTES

## Module field_manager_mod

Contact: William Cooke
Reviewers: Richard D. Slater , Matthew Harrison , John P. Dunne
Change History: WebCVS Log

#### OVERVIEW

The field manager reads entries from a field table and stores this information along with the type of field it belongs to. This allows the component models to query the field manager to see if non-default methods of operation are desired. In essence the field table is a powerful type of namelist. Default values can be provided for all the fields through a namelist, individual fields can be modified through the field table however.

An example of field table entries could be

    "tracer","atmos_mod","sphum"/

    "tracer","atmos_mod","sf6"
    "longname","sulf_hex"
    "advection_scheme_horiz","2nd_order"
    "Profile_type","Fixed","surface_value = 0.0E+00"/

    "prog_tracers","ocean_mod","age_global"
    horizontal-advection-scheme = mdfl_sweby
    vertical-advection-scheme = mdfl_sweby
    file_in = INPUT/ocean_age.res.nc
    file_out = RESTART/ocean_age.res.nc/

The field table consists of entries in the following format.
The first line of an entry should consist of three quoted strings.
The first quoted string will tell the field manager what type of field it is.
The second quoted string will tell the field manager which model the field is being applied to. The supported types at present are

          "coupler_mod" for the coupler,
          "atmos_mod" for the atmosphere model,
          "ocean_mod" for the ocean model,
          "land_mod" for the land model, and,
          "ice_mod" for the ice model.

The third quoted string should be a unique name that can be used as a query.
The second and following lines of each entry are called methods in this context. Methods can be developed within any module and these modules can query the field manager to find any methods that are supplied in the field table.
These lines can be coded quite flexibly.
The line can consist of two or three quoted strings or a simple unquoted string.
If the line consists two or three quoted strings, then the first string will be an identifier that the querying module will ask for.
The second string will be a name that the querying module can use to set up values for the module.
The third string, if present, can supply parameters to the calling module that can be parsed and used to further modify values.
If the line consists of a simple unquoted string then quotes are not allowed in any part of the line.
An entry is ended with a backslash (/) as the final character in a row.
Comments can be inserted in the field table by having a # as the first character in the line.
In the example above we have three field entries.
The first is a simple declaration of a tracer called "sphum".
The second is for a tracer called "sf6". In this case a field named "longname" will be given the value "sulf_hex". A field named "advection_scheme_horiz" will be given the value "2nd_order". Finally a field name "Profile_type" will be given a child field called "Fixed", and that field will be given a field called "surface_value" with a real value of 0.0E+00.
The third entry is an example of a oceanic age tracer. Note that the method lines are formatted differently here. This is the flexibility mentioned above.
With these formats, a number of restrictions are required.
The following formats are equally valid.

          "longname","sulf_hex"
          "longname = sulf_hex"
          longname = sulf_hex

However the following is not valid.

          longname = "sulf_hex"

In the SF6 example above the last line of the entry could be written in the following ways.

          "Profile_type","Fixed","surface_value = 0.0E+00"/
          Profile_type/Fixed/surface_value = 0.0E+00/

Values supplied with fields are converted to the various types with the following assumptions.

     Real values : These values contain a decimal point or are in exponential format.
        These values only support e or E format for exponentials.
        e.g. 10.0, 1e10 and 1E10 are considered to be real numbers.

     Integer values : These values only contain numbers.
        e.g 10 is an integer. 10.0 and 1e10 are not.

     Logical values : These values are supplied as one of the following formats.
        T, .T., TRUE, .TRUE.
        t, .t., true, .true.
        F, .F., FALSE, .FALSE.
        f, .f., false, .false.
        These will be converted to T or F in a dump of the field.

     Character strings : These values are assumed to be strings if a character
        other than an e (or E) is in the value. Numbers can be suppled in the value.
        If the value does not meet the criteria for a real, integer or logical type,
        it is assumed to be a character type.

The entries within the field table can be designed by the individual authors of code to allow modification of their routines.

#### OTHER MODULES USED

       mpp_mod
    mpp_io_mod
       fms_mod

#### PUBLIC INTERFACE

field_manager_init:
  Routine to initialize the field manager.
field_manager_end:
  Destructor for field manager.
strip_front_blanks:
  A routine to strip whitespace from the start of character strings.
find_field_index:
  Function to return the index of the field.
get_field_info:
  This routine allows access to field information given an index.
get_field_method:
  A routine to get a specified method.
get_field_methods:
  A routine to obtain all the methods associated with a field.
parse:
  A function to parse an integer or an array of integers, a real or an array of reals, a string or an array of strings.
fm_change_list:
  Change the current list. Return true on success, false otherwise
fm_change_root:
  Change the root list
fm_dump_list:
  A function to list properties associated with a field.
fm_exists:
  A function to test whether a named field exists.
fm_get_index:
  A function to return the index of a named field.
fm_get_current_list:
  A function to return the full path of the current list.
fm_get_length:
  A function to return how many elements are contained within the named list or entry.
fm_get_type:
  A function to return the type of the named field.
fm_get_value:
  An overloaded function to find and extract a value for a named field.
fm_intersection:
  A function to find the common names of the sub-fields in a list of fields.
fm_loop_over_list:
  A function for looping over a list.
fm_new_list:
  A function to create a new list.
fm_new_value:
  An overloaded function to assign a value to a field.
fm_reset_loop:
  Resets the loop variable. For use in conjunction with fm_loop_over_list.
fm_return_root:
  Return the root list to the value at initialization
fm_modify_name:
  This function allows a user to rename a field without modifying the contents of the field.
fm_query_method:
  This is a function that provides the capability to return parameters associated with a field in a pair of strings.
fm_copy_list:
  A function that allows the user to copy a field and add a suffix to the name of the new field.
fm_find_methods:
  This function retrieves all the methods associated with a field.
fm_set_verbosity:
  A subroutine to set the verbosity of the field manager output.

#### PUBLIC DATA

Name | Type | Value | Units | Description
--- | --- | --- | --- | ---
fm_field_name_len | integer, parameter | 32 | --- | The length of a character string representing the field name.
fm_path_name_len | integer, parameter | 512 | --- | The length of a character string representing the field path.
fm_string_len | integer, parameter | 128 | --- | The length of a character string representing character values for the field.
fm_type_name_len | integer, parameter | 8 | --- | The length of a character string representing the various types that the values of the field can take.
NUM_MODELS | integer, parameter | 5 | --- | Number of models (ATMOS, OCEAN, LAND, ICE, COUPLER).
NO_FIELD | integer, parameter | -1 | --- | The value returned if a field is not defined.
MODEL_ATMOS | integer, parameter | 1 | --- | Atmospheric model.
MODEL_OCEAN | integer, parameter | 2 | --- | Ocean model.
MODEL_LAND | integer, parameter | 3 | --- | Land model.
MODEL_ICE | integer, parameter | 4 | --- | Ice model.
MODEL_COUPLER | integer, parameter | 5 | --- | Ice model.
MODEL_NAMES | character(len=11), parameter | --- | --- | Model names, e.g. MODEL_NAMES(MODEL_OCEAN) is 'oceanic'

#### PUBLIC ROUTINES

1. #### field_manager_init

       call field_manager_init (nfields, table_name)

   DESCRIPTION
     This routine reads from a file containing formatted strings. These formatted strings contain information on which schemes are needed within various modules. The field manager does not initialize any of those schemes however. It simply holds the information and is queried by the appropriate module.
   INPUT

     `table_name` | The name of the field table. The default name is field_table. [character, optional, dimension(len=128)]

   OUTPUT

     `nfields` | The number of fields. [integer]

2. #### field_manager_end

       call field_manager_end

   DESCRIPTION
     This subroutine writes to the logfile that the user is exiting field_manager and changes the initialized flag to false.

3. #### strip_front_blanks

       call strip_front_blanks (name)

   DESCRIPTION
     This subroutine removes spaces and tabs from the start of a character string.

4. #### find_field_index

       value= find_field_index ( model, field_name ) value=find_field_index( field_name )

   DESCRIPTION
     This function when passed a model number and a field name will return the index of the field within the field manager. This index can be used to access other information from the field manager.
   INPUT

     `model` | The number indicating which model is used. [integer]
     `field_name` | The name of the field that an index is being requested for. [character]
     `field_name` | The path to the name of the field that an index is being requested for. [character]

   OUTPUT

     `find_field_index` | The index of the field corresponding to field_name. [integer]
     `find_field_index` | The index of the field corresponding to field_name. [integer]

5. #### get_field_info

       call get_field_info ( n,fld_type,fld_name,model,num_methods )

   DESCRIPTION
     When passed an index, this routine will return the type of field, the name of the field, the model which the field is associated and the number of methods associated with the field.
   INPUT

     `n` | The field index. [integer]

   OUTPUT

     `fld_type` | The field type. [character, dimension(*)]
     `fld_name` | The name of the field. [character, dimension(*)]
     `model` | The number indicating which model is used. [integer]
     `num_methods` | The number of methods. [integer]

6. #### get_field_method

       call get_field_method ( n,m,method )

   DESCRIPTION
     This routine, when passed a field index and a method index will return the method text associated with the field(n) method(m).
   INPUT

     `n` | The field index. [integer]
     `m` | The method index. [integer]

   OUTPUT

     `method` | The m-th method of field with index n. [type(method_type)]

7. #### get_field_methods

       call get_field_methods ( n,methods )

   DESCRIPTION
     When passed a field index, this routine will return the text associated with all the methods attached to the field.
   INPUT

     `n` | The field index. [integer]

   OUTPUT

     `method` | An array of methods for field with index n. [type(method_type), dimension(:)]

8. #### parse

       number = parse (text, label, value)

   DESCRIPTION
     Parse is an integer function that decodes values from a text string. The text string has the form: "label=list" where "label" is an arbitrary user defined label describing the values being decoded, and "list" is a list of one or more values separated by commas. The values may be integer, real, or character. Parse returns the number of values decoded.
   INPUT

     `text` | The text string from which the values will be parsed. [character(len=*)]
     `label` | A label which describes the values being decoded. [character(len=*)]

   OUTPUT

     `value` | The value or values that have been decoded. [integer, real, character(len=*)]
     `parse` | The number of values that have been decoded. This allows a user to define a large array and fill it partially with values from a list. This should be the size of the value array. [integer]

9. #### fm_change_list

       success = fm_change_list (name)

   DESCRIPTION
     This function changes the currect list to correspond to the list named name. If the first character of name is the list separator (/) then the list will search for "name" starting from the root of the field tree. Otherwise it will search for name starting from the current list.
   INPUT

     `name` | The name of a list that the user wishes to change to. [character(len=*)]

   OUTPUT

     `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]

10. #### fm_change_root

        success = fm_change_root (name)

    DESCRIPTION
      This function changes the root of the field tree to correspond to the field named name. An example of a use of this would be if code is interested in a subset of fields with a common base. This common base could be set using fm_change_root and fields could be referenced using this root.
      This function should be used in conjunction with fm_return_root.
    INPUT

      `name` | The name of the field which the user wishes to become the root. [character(len=*)]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]

11. #### fm_dump_list

        success = fm_dump_list (name, recursive = .true.)

    DESCRIPTION
      This function writes the contents of the field named "name" to stdout. If recursive is present and .true., then this function writes out the contents of any subfields associated with the field named "name".
    INPUT

      `name` | The name of the field for which output is requested. [character(len=*)]
      `recursive` | If present and .true., then a recursive listing of fields will be performed. [logical, optional]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]

12. #### fm_exists

        success = fm_exists (name)

    DESCRIPTION
      This function determines is a field exists, relative to the current list, and returns true if the list exists, false otherwise.
    INPUT

      `name` | The name of the field that is being queried. [character(len=*)]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]

13. #### fm_get_index

        index = fm_get_index (name)

    DESCRIPTION
      Returns the index for name, returns the parameter NO_FIELD if it does not exist. If the first character of the named field is the list peparator, then the named field will be relative to the root of the field tree. Otherwise the named field will be relative to the current list.
    INPUT

      `name` | The name of a field that the user wishes to get an index for. [character(len=*)]

    OUTPUT

      `index` | The index of the named field if it exists. Otherwise the parameter NO_FIELD. [index]

14. #### fm_get_current_list

        path = fm_get_current_list ()

    DESCRIPTION
      This function returns the full path for the current list. A blank path indicates an error condition has occurred.
    OUTPUT

      `path` | The path corresponding to the current list. [character(len=fm_path_name_len)]

15. #### fm_get_length

        length = fm_get_length (name)

    DESCRIPTION
      This function returns the list or entry length for the named list or entry. If the named field or entry does not exist, a value of 0 is returned.
    INPUT

      `name` | The name of a list or entry that the user wishes to get the length of. [character(len=*)]

    OUTPUT

      `length` | The number of elements that the field name has. [integer]

16. #### fm_get_type

        name_field_type = fm_get_type (name)

    DESCRIPTION
      This function returns the type of the field for name. This indicates whether the named field is a "list" (has children fields), or has values of type "integer", "real", "logical" or "string". If it does not exist it returns a blank string.
    INPUT

      `name` | The name of a field that the user wishes to find the type of. [character(len=*)]

    OUTPUT

      `name_field_type` | A string containing the type of the named field. [character(len=8)]

17. #### fm_get_value

        success = fm_get_value (name, value, index)

    DESCRIPTION
      Find and extract the value for name. The value may be of type real, integer, logical or character. If a single value from an array of values is required, an optional index can be supplied. Return true for success and false for failure
    INPUT

      `name` | The name of a field that the user wishes to get a value for. [character(len=*)]
      `index` | An optional index to retrieve a single value from an array. [integer, optional]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]
      `value` | The value associated with the named field. [integer, real, logical or character]

18. #### fm_intersection

        return_p => fm_intersection (lists,dim)

    DESCRIPTION
      Return a pointer to an fm_array_list of the intersection of an array of lists, ignoring the contents of the values, but just returning the names. Return false on the end of the intersection.
    INPUT

      `dim` | The dimension of lists. [dim]
      `lists` | A list of fields that the user wishes to find the common fields of. [character(len=*), dimension(dim)]

    OUTPUT

      `return_p` | A pointer to a list of names that are common to the fields provided in lists. [type (fm_array_list_def), pointer]

19. #### fm_loop_over_list

        success = fm_loop_over_list (list, name, field_type, index)

    DESCRIPTION
      Loop over the list, setting the name, type and index of the next field. Return false at the end of the loop.
    INPUT

      `list` | The name of a list to loop over. [character(len=*)]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]
      `name` | The name of a field from list. [character(len=*)]
      `field_type` | The type of a list entry. [character(len=fm_type_name_len)]
      `index` | The index of tje field within the list. [integer]

20. #### fm_new_list

        index = fm_new_list (name, create, keep)

    DESCRIPTION
      Allocate and initialize a new list and return the index of the list. If an error occurs return the parameter NO_FIELD.
    INPUT

      `name` | The name of a list that the user wishes to create. [character(len=*)]
      `create` | If present and .true., create the list if it does not exist. [logical, optional]
      `keep` | If present and .true., make this list the current list. [logical, optional]

    OUTPUT

      `index` | The index of the newly created list. [integer]

21. #### fm_new_value

        field_index = fm_new_value (name, value, [create], [index], [append])

    DESCRIPTION
      Allocate and initialize a new value and return the index. If an error condition occurs the parameter NO_FIELD is returned.
      If the type of the field is changing (e.g. real values being transformed to integers), then any previous values for the field are removed and replaced by the value passed in the present call to this function.
      If append is present and .true., then index cannot be greater than 0 if it is present.
    INPUT

      `name` | The name of a field that the user wishes to create a value for. [character(len=*)]
      `value` | The value that the user wishes to apply to the named field. [integer, real, logical, or character(len=*)]
      `create` | If present and .true., then a value for this field will be created. [logical, optional]
      `index` | The index to an array of values that the user wishes to apply a new value. [integer, optional]
      `append` | If present and .true., then append the value to an array of the present values. If present and .true., then index cannot be greater than 0. [logical, optional]

    OUTPUT

      `field_index` | An index for the named field. [integer]

22. #### fm_reset_loop

        call fm_reset_loop

    DESCRIPTION
      Resets the loop variable. For use in conjunction with fm_loop_over_list.

23. #### fm_return_root

        call fm_return_root

    DESCRIPTION
      Return the root list to the value at initialization. For use in conjunction with fm_change_root.
      Users should use this routine before leaving their routine if they previously used fm_change_root.

24. #### fm_modify_name

        success = fm_modify_name (oldname, newname)

    DESCRIPTION
      Function to modify the name of a field. Should be used with caution.
    INPUT

      `oldname` | The name of a field that the user wishes to change the name of. [character(len=*)]
      `newname` | The name that the user wishes to change the name of the field to. [character(len=*)]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]

25. #### fm_query_method

        success = fm_query_method (name, method_name, method_control)

    DESCRIPTION
      Given a name return a list of method names and control strings. This function should return strings similar to those in the field table if a comma delimited format is being used.
    INPUT

      `name` | The name of a list that the user wishes to change to. [character(len=*)]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]
      `method_name` | The name of a parameter associated with the named field. [character(len=*)]
      `method_control` | The value of parameters associated with the named field. [character(len=*)]

26. #### fm_copy_list

        index = fm_copy_list (list_name, suffix, create)

    DESCRIPTION
      Given the name of a pre-existing field and a suffix, this function will create a new field. The name of the new field will be that of the old field with a suffix supplied by the user.
    INPUT

      `list_name` | The name of a field that the user wishes to copy.. [character(len=*)]
      `suffix` | The suffix that will be added to list_name when the field is copied. [character(len=*)]

    OUTPUT

      `index` | The index of the field that has been created by the copy. [integer]

27. #### fm_find_methods

        success = fm_find_methods (list_name, methods, control )

    DESCRIPTION
      This function retrieves all the methods associated with a field. This is different from fm_query_method in that this function gets all the methods associated as opposed to 1 method.
    INPUT

      `list_name` | The name of a list that the user wishes to find methods for. [character(len=*)]

    OUTPUT

      `success` | A flag to indicate whether the function operated with (FALSE) or without (TRUE) errors. [logical]
      `methods` | An array of the methods associated with list_name. [character(len=*)]
      `control` | An array of the parameters associated with methods. [character(len=*)]

28. #### fm_set_verbosity

        call fm_set_verbosity (verbosity)

    DESCRIPTION
      This subroutine will set the level of verbosity in the module. Currently, verbosity is either on (1) or off (0). However, in the future, "on" may have more granularity. If no argument is given, then, if verbosity is on it will be turned off, and is off, will be turned to the default on level. If verbosity is negative then it is turned off. Values greater than the maximum will be set to the maximum.
    INPUT

      `verbosity` | The level of verbosity required by the user. [integer, optional]

#### PUBLIC TYPES

method_type

This method_type is a way to allow a component module to alter the parameters it needs for various tracers. In essence this is a way to modify a namelist. A namelist can supply default parameters for all tracers. This method will allow the user to modify these default parameters for an individual tracer. An example could be that the user wishes to use second order advection on a tracer and also use fourth order advection on a second tracer within the same model run. The default advection could be second order and the field table would then indicate that the second tracer requires fourth order advection. This would be parsed by the advection routine.
`method_type :: method_type`

This string represents a tag that a module using this method can key on. Typically this should contain some reference to the module that is calling it.
[character, dimension(128)]

`method_type :: method_name`

This is the name of a method which the module can parse and use to assign different default values to a field method.
[character, dimension(128)]

`method_type :: method_control`

This is the string containing parameters that the module can use as values for a field method. These should override default values within the module.
[character, dimension(256)]

method_type_short

This method_type is the same as method_type except that the method_control string is not present. This is used when you wish to change to a scheme within a module but do not need to pass parameters.
`method_type_short :: method_type`

see method_type :: method_type above.
[character, dimension(128)]

`method_type_short :: method_name`

see method_type :: method_name above.
[character, dimension(128)]

method_type_very_short

This method_type is the same as method_type except that the method_control and method_name strings are not present. This is used when you wish to change to a scheme within a module but do not need to pass parameters.
`method_type_short :: method_type`

see method_type :: method_type above.
[character, dimension(128)]

#### DATA SETS

None.

#### ERROR MESSAGES

NOTE in field_manager_init
  No field table available, so no fields are being registered.
  The field table does not exist.
FATAL in field_manager_init
  Too many fields in field table header entry.
  There are more that 3 fields in the field table header entry. The entry should look like "Field_Type","Model_Type","Field_Name" or "Field_Type","Model_Type"
FATAL in field_manager_init
  Unterminated field in field table header entry.
  There is an unterminated or unquoted string in the field table entry. call mpp_error(FATAL,trim(error_header)//'Unterminated field in field_table header entry.'//trim(record))
NOTE in field_manager_init
  Creating list name = list_name.
  A field is being created called list_name.
FATAL in field_manager_init
  Could not set field list for list_name.
  A field called list_name could not be created.
FATAL in field_manager_init
  The model name is unrecognised : model_name
  The model name being supplied in the field entry is unrecognised. This should be the second string in the first line of the field entry. Recognised names are atmos_mod, ice_mod, land_mod and ocean_mod.
FATAL in field_manager_init
  max fields exceeded
  Maximum number of fields for this module has been exceeded.
FATAL in field_manager_init
  Too many fields in field entry.
  There are more that 3 fields in the tracer entry. This is probably due to separating the parameters entry into multiple strings. The entry should look like "Type","Name","Control1=XXX,Control2=YYY" and not like "Type","Name","Control1=XXX","Control2=YYY"
FATAL in field_manager_init
  Unterminated field in field entry.
  There is an unterminated or unquoted string in the field table entry.
FATAL in field_manager_init
  Unterminated field in field entry.
  Bad format for field entry (comma without equals sign)
FATAL in field_manager_init
  Unterminated field in field entry.
  Too many fields in field entry
FATAL in field_manager_init
  Maximum number of methods for field exceeded
  Maximum number of methods allowed for entries in the field table has been exceeded.
NOTE in field_manager_init
  Field with identical name and model name duplicate found, skipping
  The name of the field and the model name are identical. Skipping that field.
FATAL in field_manager_init
  error reading field table
  There is an error in reading the field table.
FATAL in get_field_info
  invalid field index
  The field index is invalid because it is less than 1 or greater than the number of fields.
FATAL in get_field_method
  invalid field index
  The field index is invalid because it is less than 1 or greater than the number of fields.
FATAL in get_field_method
  invalid method index
  The method index is invalid because it is less than 1 or greater than the number of methods.
FATAL in get_field_methods
  invalid field index
  The field index is invalid because it is less than 1 or greater than the number of fields.
FATAL in get_field_methods
  method array too small
  The method array is smaller than the number of methods.

top