#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the Common Development
# and Distribution License Version 1.0 (the "License").
#
# You can obtain a copy of the license at
# http://www.opensource.org/licenses/CDDL-1.0.  See the License for the
# specific language governing permissions and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each file and
# include the License file in a prominent location with the name LICENSE.CDDL.
# If applicable, add the following below this CDDL HEADER, with the fields
# enclosed by brackets "[]" replaced with your own identifying information:
#
# Portions Copyright (c) [yyyy] [name of copyright owner]. All rights reserved.
#
# CDDL HEADER END
#

#
# Copyright (c) 2013--2014, Regents of the University of Minnesota.
# All rights reserved.
#
# Contributors:
#    Ryan S. Elliott
#    Ellad B. Tadmor
#    Valeriu Smirichinski
#

################################################################################
#
# Release: This file is part of the kim-api-v1.6.3 package.
#
################################################################################


Description of the KIM API library routines:

This file provides a basic description of the KIM API library routines.  For
each function the main description is for the C interface.  The C++ interface
is always the same as the C interface, but is called as a member-function of
the KIM_API_model object whose name does not include the `KIM_API_' part of the
C interface function name.  (For example, to call KIM_API_model_compute() in
C++, you would use the code `mdl->model_compute()'.)  The Fortran interface
uses the iso_c_binding framework introduced in Fortran 2003.  This interface is
identical to the C interface, except for the "get/set multiple" api functions
which are described at the end of this file.  C api functions of type void are
implemented as Fortran Subroutines and all other C api functions are
implemented as Fortran Functions.

NOTE: older versions of this package used the "Cray Pointer" Fortran extension
to support C/Fortran interoperability.  This is no longer supported and the
Cray pointer bindings have been removed.

Pointers to data versus pointers to methods (functions):

In general it is not portable to store a pointer to a method in a pointer to
data variable.  This requires that we have separate library routines for
storing and retrieving data and method pointers.  Additionally, for C/C++ the
following typedef is provided:

         typedef void (* func_ptr)();

This provides a generic function pointer type and is used in the associated
get/set method routines.

In the following description several constants are used:

STATUS codes: The KIM API uses a set of defined status code keys to return
              information to the user.  These symbolic code keys are defined in
              the KIM_API_status.h file which can be #include'd by any source
              file.  The codes associated with these keys (defined in
              KIM_API_status.h) are subject to change and should not be used
              directly.  By convention, any status code, `kimerror', returned
              by a KIM API library routine that is less than KIM_STATUS_OK
              (i.e., "kimerror < KIM_STATUS_OK") indicates an error has
              occurred.

==============================  GLOBAL METHODS  ==============================

int KIM_API_file_init(void *kimmdl, char *simkimfile, char *modelname);

    This routine creates the KIM API object that can store every pointer to the
    data described in the KIM descriptor file for the model.  It also checks if
    arguments described in descriptor files (Simulators and Models) are
    compatible with KIM standard naming convention (stored in the file
    `standard.kim') and if Models are compatible with simulators.  It will
    return KIM_STATUS_OK upon successful completion or KIM_STATUS_FAIL
    otherwise.  Also if it is unsuccessful, kimmdl will have NULL value.

    Here the process of matching a Simulator KIM descriptor file and a Model
    KIM descriptor file is described in detail.  For a final positive match
    result to occur, a positive match must be obtained in EACH AND EVERY ONE of
    the below steps:

    (1) Syntax and standard conformance: The Simulator and Model KIM descriptor
        files are read.  Each item in the file is parsed and compared for
        correct syntax and conformance with the `standard.kim' file.  If both
        the files a syntactically correct and conform to the `standard.kim'
        file definitions, a positive match is obtained.  Otherwise, a negative
        match is obtained and the routine returns KIM_STATUS_FAIL.

    (2) Unit matching: If the Model's Unit_Handling value is `flexible' a
        positive match is obtained and the routine skips to the next step
        below.  Otherwise, the Simulator's base unit values are compared, one
        by one, to the Model's base unit values.  If all five values are equal,
        a positive match is obtained.  Otherwise, a negative match is obtained
        and the routine returns KIM_STATUS_FAIL.

    (3) Particle species matching: For each particle species symbol name listed
        by the Simulator, the Model's list of particle species symbol names is
        searched for the corresponding entry.  If every particle species symbol
        listed by the Simulator is found in the Model's symbol list, a positive
        match is obtained.  If both the Model's and Simulator's list are empty,
        then the Model and Simulator support a single "unnamed" particle
        species and a positive match is obtained.  Otherwise, a negative match
        is obtained and the routine returns KIM_STATUS_FAIL.

    (4) Neighbor list access matching: The following is a list of the possible
        cases and their matching result.

              Simulator   Model         Matching Result
              ----------- ------------- ---------------
              Iter        Iter          positive match
              Iter        Loca          negative match
              Iter        Iter&Loca     positive match
              Iter        Both          negative match
              Loca        Iter          negative match
              Loca        Loca          positive match
              Loca        Iter&Loca     positive match
              Loca        Both          negative match
              Iter&Loca   Iter          positive match
              Iter&Loca   Loca          positive match
              Iter&Loca   Iter&Loca     positive match
              Iter&Loca   Both          positive match
              Both        Iter          positive match
              Both        Loca          positive match
              Both        Iter&Loca     positive match
              Both        Both          positive match

    (5) NBC method matching: If one or more of the Simulator's listed NBC
        methods is also in the Model's listed NBC methods a positive match is
        obtained.  When more than one common NBC method exists, the NBC method
        listed closest to the top of the Simulator's NBC method list is
        selected as the "active" NBC method.  If no common NBC methods are
        listed a negative match is obtained and the routine returns
        KIM_STATUS_FAIL.

    (6) Matching for MODEL_INPUT arguments required by active NBC method:
        Depending on the active NBC method (determined in step (5) above), the
        Model's and Simulator's MODEL_INPUT section must include the following
        arguments:

              CLUSTER:
                    `coordinates'

              NEIGH_PURE_H:
                    `coordinates'
                    `numberContributingParticles'
                    `neighObject'
                    `get_neigh'

              NEIGH_PURE_F:
                    `coordinates'
                    `neighObject'
                    `get_neigh'

              NEIGH_RVEC_H:
                    `coordinates'
                    `numberContributingParticles'
                    `neighObject'
                    `get_neigh'

              NEIGH_RVEC_F:
                    `coordinates'
                    `neighObject'
                    `get_neigh'

              MI_OPBC_H:
                    `coordinates'
                    `boxSideLengths'
                    `numberContributingParticles'
                    `neighObject'
                    `get_neigh'

              MI_OPBC_F:
                    `coordinates'
                    `boxSideLengths'
                    `neighObject'
                    `get_neigh'

        If all required arguments are found in both the Model's and Simulator's
        list of MODEL_INPUT arguments, then a positive match is obtained.
        Otherwise, a negative match is obtained and the routine returned
        KIM_STATUS_FAIL.

    (7) Mandatory arguments matching: The following arguments are mandatory and
        must be included in any KIM descriptor file:

              MODEL_INPUT section
                `numberOfParticles'
                `numberOfSpecies'
                `particleSpecies'    (not required if the PARTICLE_SPECIES
                                     section is empty.  That is, if the Model
                                     and Simulator only support a single
                                     "unnamed" particle species.)
                `coordinates'        (this has already been confirmed in step 6)
              MODEL_OUTPUT section
                `compute'
                `reinit'
                `destroy'
                `cutoff'

        If all of the above arguments (except possibly, as described above,
        `particleSpecies') are present in both the Model and Simulator KIM
        descriptor files, then a positive match is obtained.  Otherwise, a
        negative match is obtained and the routine returns KIM_STATUS_FAIL.

    (8) MODEL_INPUT matching: If the Model's MODEL_INPUT list of arguments
        includes `process_dEdr' or `process_d2Edr2', then its MODEL_OUTPUT list
        of arguments may not contain `virial', `particleVirial', or `hessian'.
        If it does, a negative match is obtained and the routine returns
        KIM_STATUS_FAIL.

        If the Simulator's MODEL_INPUT list of arguments includes
        `process_dEdr' or `process_d2Edr2', then its MODEL_OUTPUT list of
        arguments may not contain `virial', `particleVirial', or `hessian'.  If
        it does, a negative match is obtained and the routine returns
        KIM_STATUS_FAIL.

        If the Model's MODEL_INPUT list of arguments contains `process_dEdr'
        and the Simulator's MODEL_INPUT list of arguments does not contain
        `process_dEdr', then (in memory) the routine adds `virial' and
        `particleVirial' arguments, with the `optional' keyword, to the Model's
        MODEL_OUTPUT list of arguments.

        If the Model's MODEL_INPUT list of arguments contains `process_dEdr'
        and `process_d2Edr2', then (in memory) the routine adds `hessian', with
        the `optional' keyword, to the Model's MODEL_OUTPUT list of arguments.

        For each non-optional argument in the Model's MODEL_INPUT list of
        arguments, a corresponding entry must exist in the Simulator's
        MODEL_INPUT list of arguments.  If at least one such argument is
        missing from the Simulator's list, a negative match is obtained and the
        routine returns KIM_STATUS_FAIL.

        For each argument in the Simulator's MODEL_INPUT list of arguments, a
        corresponding entry (either "optional" or required) must exist in the
        Model's MODEL_INPUT list of arguments.  If all such arguments are
        present, then a positive match is obtained.  If at least one such
        argument is missing from the Model's list, a negative match is obtained
        and the routine returns KIM_STATUS_FAIL.

        Finally, all optional arguments in the Model's MODEL_INPUT list of
        arguments which are not contained in the Simulator's MODEL_INPUT list
        of arguments have their `compute' flag set to KIM_COMPUTE_FALSE.

    (9) MODEL_OUTPUT matching: For each non-optional argument in the Model's
        MODEL_OUTPUT list of arguments, a corresponding entry must exist in the
        Simulator's MODEL_OUTPUT list of arguments.  If at least one such
        argument is missing from the Simulator's list, a negative match is
        obtained and the routine returns KIM_STATUS_FAIL.

        For each argument in the Simulator's MODEL_OUTPUT list of arguments, a
        corresponding entry (either "optional" or required) must exist in the
        Model's MODEL_OUTPUT list of arguments.  If all such arguments are
        present, then a positive match is obtained.  If at least one such
        argument is missing from the Model's list, a negative match is obtained
        and the routine returns KIM_STATUS_FAIL.

	For each argument in the Simulator's MODEL_OUTPUT list of arguments,
	the argument's `compute' flag is set to KIM_COMPUTE_TRUE.  If the
	`virial' or `particleVirial' arguments were added to the Model's
	MODEL_OUTPUT list of arguments in step 8 and any of these arguments are
	contained in the Simulator's MODEL_OUTPUT list of arguments, then the
	`process_dEdr' argument's `compute' flag is set to KIM_COMPUTE_TRUE.
	If the `hessian' argument was added to the Model's MODEL_OUTPUT list of
	arguments in step 8 and this argument is in the Simulator's
	MODEL_OUTPUT list of arguments, then the `compute' flags of the
	`process_dEdr' and `process_d2Edr2' arguments are set to
	KIM_COMPUTE_TRUE.

Arguments:

      void *kimmdl
              reference pointer to KIM_API_model object (in C++ style, the
              definition will be (KIM_API_model **)).

      char *simkimfile
              null terminated character string giving the relative or absolute
              path name to the Simulator's KIM descriptor file.

      char *modelname
              null terminated character string that defines the Model name.
              The routine uses this name to find the character string in memory
              that contains the Model's descriptor (.kim) file.  At compile
              time the descriptor file is stored in the Model's binary library
              file.  Thus, it is necessary to perform a `make' of the KIM API
              package after editing a Model's ".kim" file.

******************************************************************************

int KIM_API_string_init(void *kimmdl, char *simdescriptor, char *modelname);

    This routine performs the same function as the KIM_API_file_init() routine.
    However, in this case the argument `simkimname' is a (long) null (or eof)
    terminated string with the complete content of the Simulator's KIM
    descriptor file.

    For a description of the process of matching a Simulator KIM descriptor
    file and a Model KIM descriptor file performed by this routine, see the
    entry for KIM_API_file_init() above.

Arguments:

      void *kimmdl
              reference pointer to KIM_API_model object (in C++ style the
              definition will be (KIM_API_model **)).

      char *simdescriptor
              null ( char(0) ) or eof terminated character string with the
              complete content of the Simulator's KIM descriptor file.

      char *modelname
              null terminated character string that defines the Model name.
              The routine uses this name to find the character string in memory
              that contains the Model's descriptor (.kim) file.  At compile
              time the descriptor file is stored in the Model's binary library
              file.  Thus, it is necessary to perform a `make' of the KIM API
              package after editing a Model's ".kim" file.

******************************************************************************

int KIM_API_get_version(const char** const version);

    This routine outputs the full SemVer version string for the KIM API.

Return value:
      KIM_STATUS_OK

Arguments:
      const char** const version
              the KIM API SemVer version string.

******************************************************************************

int KIM_API_get_version_major(int* const major);

    This routine outputs the Major version number for the KIM API.

Return value:
      KIM_STATUS_OK

Arguments:
      int* const major
              the KIM API Major version number.

******************************************************************************

int KIM_API_get_version_minor(int* const minor);

    This routine outputs the Minor version number for the KIM API.

Return value:
      KIM_STATUS_OK

Arguments:
      int* const minor
              the KIM API Minor version number.

******************************************************************************

int KIM_API_get_version_prerelease(const char** const prerelease);

    This routine outputs the Prerelease string for the KIM API.

Return value:
      KIM_STATUS_OK

Arguments:
      const char** const prerelease
              the KIM API SemVer Prerelease string.

******************************************************************************

int KIM_API_get_version_build_metadata(const char** const build_metadata);

    This routine outputs the Build metadata string for the KIM API.

Return value:
      KIM_STATUS_OK

Arguments:
      const char** const build_metadata
              the KIM API SemVer Build metadata string.

******************************************************************************

int KIM_API_version_newer(const char* const versionA, const char* const versionB, int* const result);

    This routine compares two SemVer version strings and outputs the
    precedent.  That is, it answers the question: Is versionA > versionB?.

Return value:
      KIM_STATUS_OK   -- suscessful completion
      KIM_STATUS_FAIL -- one of the two version strings is invalid

Arguments:
      const char* const versionA
              the first SemVer version string.

      const char* const versionB
              the second SemVer version string.

      int* const result
              the result of the comparison.  result=1 if versionA > versionB.
              result=0 if versionA <= versionB.  result=-1 if the function
              returns KIM_STATUS_FAIL.

******************************************************************************

int KIM_API_model_info(void *kimmdl, char *modelname);

    This routine creates a KIM API object that represents the capabilities of a
    Model.  Standard library routines (described below) can be used to probe
    this object in order to determine (most) of the items listed in the Model's
    KIM descriptor file. For example, A Simulator could determine what particle
    species are supported by a Model and adjust it's calculations
    appropriately.  Return value: KIM_STATUS_OK if successful and
    KIM_STATUS_FAIL if unsuccessful.

Arguments:

      void *kimmdl
              reference pointer to KIM_API_model object (in C++ style, the
              definition will be (KIM_API_model **)).

      char *modelname
              null terminated character string that defines the Model name.
              The routine uses this name to find the character string in memory
              that contains the Model's descriptor (.kim) file.  At compile
              time the descriptor file is stored in the Model's binary library
              file.  Thus, it is necessary to perform a `make' of the KIM API
              package after editing a Model's ".kim" file.

******************************************************************************

void KIM_API_allocate(void *kimmdl, int nParticles, int nSpecies, int *kimerror);

    This routine allocates memory for each data argument stored in the
    initialized KIM API object kimmdl.  It will return with an error code if an
    error occurs during allocation.  KIM_API_allocate should not be used in
    conjunction with KIM_API_set_data for array data (this would create a
    memory leak).

    NOTE: Prior to calling this routine a valid KIM API object must be obtained
          by calling KIM_API_file_init().  However, calling this routine
          multiple times with the same KIM API object will cause a memory leak.

    Here the process of allocating memory for KIM API arguments and updating
    their associated shape values is described in detail (See also, the
    discussion of the `Shape' string component of the `Data' line type
    contained in the `standard.kim' file.):

    (1) For each argument in the Model's MODEL_INPUT, MODEL_OUTPUT, and
        MODEL_PARAMETERS lists of arguments, the routine converts the shape
        string, specified in the KIM descriptor file, into an integer shape
        array.  The three supported non-integer string values: `:',
        `numberOfParticles', `numberSpecies' are converted to 0, the value of
        the `nParticles' argument to this routine, and the value of the
        `nSpecies' argument to this routine, respectively.  All integer extent
        values specified in the KIM descriptor file are simply transferred into
        the integer shape array.  (NOTE: here, the values specified in the KIM
        descriptor file take precedence over any changes that may have been
        made, via the KIM_API_set_shape() routine, to the argument's integer
        shape array values.)

    (2) For each argument in the Model's MODEL_INPUT and MODEL_OUTPUT lists of
        arguments:

              (a) If the argument has an allocated memory block associated with
                  it, from a previous call to KIM_API_allocate(), the memory
                  block is released.

              (a) If the argument type is `method' or `pointer', the argument's
                  integer shape array is set to `[]' (rank=0), nothing is
                  allocated, and the argument's pointer value is set to null.

              (b) If the argument is `optional' and its `compute' flag has is
                  KIM_COMPUTE_FALSE, the argument's first shape extent (for
                  rank>=1) is set to zero (shape[0]=0), nothing is allocated,
                  and the argument's pointer value is set to null.

              (c) If the argument has a at least one extent value in its shape
                  equal to 0, then nothing is allocated and the argument's
                  pointer value is set to null.

              (d) If the argument has rank=0 (it is a scalar) or if the
                  argument's integer shape array has all strictly positive
                  entries, then the appropriate size block of contiguous memory
                  is allocated and the argument's pointer value is set to
                  pointer to this block of memory.

    (3) For each argument in the Model's MODEL_PARAMETERS list of arguments,
        the argument's first shape extend value (when rank>=1) is set to 0
        (shape[0]=0), nothing is allocated (the Model is responsible for
        allocating parameter memory), and the argument's pointer value is set
        to null.  (NOTE: this will generally cause a memory leak if
        KIM_API_allocate() is called multiple times on the same KIM API object.
        To avoid such memory leaks, If KIM_API_model_init() has been called,
        then KIM_API_model_destroy() should be called before KIM_API_allocate()
        is called a second time.)

    NOTE: This routine does not set the value of the `numberOfParticles' and
    `numberSpecies' arguments after allocating their memory.  This
    responsibility is left to the Simulator.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int nParticles
              total number of particles.

      int nSpeciess
              number of particles species.

      int *kimerror
              error code: KIM_STATUS_OK    -- successful completion,
                          KIM_STATUS_FAIL  -- unsuccessful

******************************************************************************

void KIM_API_c_free(void *cp);

    This routine is only available in the Forgran 2003 bindings.  It provides
    access to the c "free" memory deallocation routine.  It should be used in
    order to release memory originally allocated by
    KIM_API_get_model_kim_str().

Arguments:

      void *cp
              pointer to memory address to be freed.

******************************************************************************

void KIM_API_free(void *kimmdl, int *kimerror);

    This routine deallocates all memory allocated by KIM_API_allocate and also
    destroys the KIM API object.

    NOTE: Prior to calling this routine, the Simulator is responsible for
          calling the KIM_API_model_destroy() function and deallocating any
          memory associated with arguments in the KIM API object as
          appropriate.

Arguments:

      void *kimmdl
              reference pointer to KIM_API_model object (in C++ style, the
              definition will be (KIM_API_model **)).

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

void KIM_API_print(void *kimmdl, int *kimerror);

    This routine prints to standard output, the KIM API object: structure, data
    and flags.  This is normally used for debugging purposes.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

int KIM_API_model_compute(void *kimmdl);

    This routine executes the `compute' method of the Model by using the
    address of the compute routine stored in KIM API object.  Return value:
    KIM_STATUS_OK on success or KIM_STATUS_MODEL_UNSUPPORTED_CONFIGURATION if
    the Model is unable to perform the computation for the supplied
    configuration (e.g., it doesn't support the particular combination of
    particle species in the configuration) or else KIM_STATUS_FAIL for other
    types of failure.

    NOTES:

    (1) Prior to calling this routine the KIM API object pointed to by `kimmdl'
        must contain the necessary information that the Model requires to run.
        In addition, KIM_API_model_init() must have successfully executed for
        this KIM API object.

    (2) It is important to stress that a Model must not make assumptions about
        the state of the KIM API object in its model_compute() function.  For
        example, the value of `numberOfParticles' could change every time that
        model_compute() is called.  This would also imply that the `coordinates'
        array pointer, and other similar pointers, would change too.  Thus, the
        Model must be careful to accurately determine the validity of any data
        has previously stored in its Model Buffer.  (See details and cautionary
        notes about this in the documentation for KIM_API_set/get_model_buffer
        and also in the standard.kim file.)

    (3) The Model must define a model_compute function (the name of this
           function is not important) with prototype:
           extern "C" { int model_compute(void *kimmdl); }     // in C++
           int model_compute(void *kimmdl);                    /* in C */
           integer(c_int) function model_compute(pkim) bind(c) ! in Fortran 2003
              type(c_ptr), intent(in) :: pkim

        A pointer to the Model's model_compute function must be registered in
        the KIM_API object using one of the "set method" api library routines.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

******************************************************************************

int KIM_API_model_destroy(void *kimmdl);

    This routine executes the `destroy' method of the model by using the
    address of the destroy routine stored in KIM API object.  This routine
    performs any necessary clean-up tasks.  In particular, it must deallocate
    the memory for all Model parameters stored in the KIM API object.  Return
    value is KIM_STATUS_OK on success and KIM_STATUS_FAIL on failure.

    NOTES:

    (1) Prior to calling this routine KIM_API_model_init() must have been
        called for this KIM API object.

    (2) The Model may define a model_destroy function (the name of this
           function is not important) with prototype:
           extern "C" { int model_destroy(void *kimmdl); }     // in C++
           int model_destroy(void *kimmdl);                    /* in C */
           integer(c_int) function model_destroy(pkim) bind(c) ! in Fortran 2003
              type(c_ptr), intent(in) :: pkim

        If a model defines a model_destroy functions, a pointer to this
        function must be registered in the KIM_API object using one of the "set
        method" api library routines.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

******************************************************************************

int KIM_API_get_model_index_shift(void *kimmdl);

    This routine returns an integer that indicates the offset in indices
    between Simulators and Models for array access. The return value can be
    only -1,0 or +1.
    If the Simulator has ZeroBasedLists and the Model has OneBasedLists  the return value is +1
    If the Simulator has OneBasedLists  and the Model has OneBasedLists  the return value is  0
    If the Simulator has ZeroBasedLists and the Model has ZeroBasedLists the return value is  0
    If the Simulator has OneBasedLists  and the Model has ZeroBasedLists the return value is -1

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

******************************************************************************

void KIM_API_set_model_buffer(void *kimmdl, void *ob, int *kimerror);

    This routine allows the Model to store a pointer to a buffer of memory.
    The Model can use this buffer as persistent memory between calls to its
    various functions.

    NOTE: This feature must be used with caution.  There is no mechanism to
          notify the Model when changes are made to the data (controlled by the
          Simulator) in the KIM API object (such as the number of particles, or
          the memory location of the `forces' argument).  In particular, the
          pointer values returned by KIM_API_get_data() are, generally, NOT
          safe to store in the Model Buffer.  An example of a safe quantity to
          store in the Model Buffer is the index for an argument returned by
          the KIM_API_get_index() function.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      void *ob
              pointer to Model Buffer

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

void KIM_API_set_sim_buffer(void *kimmdl, void *ob, int *kimerror);

    This routine allows the Simulator to store a pointer to a buffer of memory.
    The Simulator can use this buffer as persistent memory associated with the
    KIM API object.

    NOTE: This feature must be used with caution.  There is no mechanism to
          notify the Simulator when changes are made to the data (controlled by
          the Model) in the KIM API object (such as the pointer to the Model's
          `compute' function, the pointers to its Parameters or their values).
          In particular, the pointer values returned by KIM_API_get_data() are,
          generally, NOT safe to store in the Simulator Buffer.  An example of
          a safe quantity to store in the Simulator Buffer is the index for an
          argument returned by the KIM_API_get_index() function.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      void *ob
              pointer to Simulator Buffer

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

void *KIM_API_get_model_buffer(void *kimmdl, int *kimerror);

    This routine gets (returns) the pointer to the Model buffer.  See the
    description of KIM_API_get_model_buffer() above.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

void *KIM_API_get_sim_buffer(void *kimmdl, int *kimerror);

    This routine gets (returns) the pointer to the Simulator buffer.  See the
    description of KIM_API_get_sim_buffer() above.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

int KIM_API_is_half_neighbors(void *kimmdl, int *kimerror);

    This routine returns 1 if KIM_API Model object setting is for half
    neighbors or 0 if it is for full neighbors.  The type of neighbor list
    being used (if any) is determined by the "active" NBC method (See
    KIM_API_get_NBC_method() below).  This is a convenience routine which makes
    it easy to quickly determine the type of neighbor list in use.  This routine
    returns 1 for the CLUSTER NBC method even though neighbor lists are not
    used as part of the CLUSTER NBC method.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful


================== ELEMENT ACCESS METHODS ROUTINES BY NAME ====================

int KIM_API_set_data(void *kimmdl, char *nm, intptr_t size, void *dt);
int KIM_API_set_method(void *kimmdl, char *nm, intptr_t size, func_ptr dt);

    These routines search for the string `nm' in the KIM API object
    `kimmdl'. If found, it stores in the KIM API object the value of `dt' which
    points to the location in memory where the data/method associated with `nm'
    is to be stored.  Upon successful completion this routine returns
    KIM_STATUS_OK.  If `nm' is not in the KIM API object this routine returns
    KIM_STATUS_ARG_UNKNOWN.  If an existing pointer in the KIM API object is
    overwritten by this operation, a memory leak may result. (This could
    indicate that storage for the same data has been allocated more than once.)
    Thus, care must be taken if this routine is used in conjunction with
    KIM_API_allocate for array data.  This routine assumes that the shape of
    the associated argument has been fully specified, except possibly for the
    `fast-index' (see discussion of shape entries in standard.kim).  The
    routine computes the product of the shape entries not including the
    fast-index and sets a new shape value for the fast-index by dividing `size'
    by this product.

    NOTE: Prior to calling this routine a valid KIM API object must be obtained
          by calling KIM_API_file_init().

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file

      intptr_t size
              size of the data in terms of underlying elements

      void *dt
              pointer to the data
      func_ptr dt
              pointer to the method

******************************************************************************

void *KIM_API_get_data(void *kimmdl, char *nm, int *kimerror);
func_ptr KIM_API_get_method(void *kimmdl, char *nm, int *kimerror);

    These routines return a pointer from the KIM API object that points to
    memory where data/method associated with the string `nm' is stored.  It
    returns NULL if the string nm is not found in the KIM API object.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

intptr_t KIM_API_get_size(void *kimmdl, char *nm, int *kimerror);

     The functionality of this routine is the same as KIM_API_get_data, except
     it returns the size of the data in terms of underlying elements. (For
     example, if the data is an array of shape [numberOfParticles,3],
     KIM_API_get_size() will return numberOfParticles*3.)  If no data with name
     `nm' is in the KIM API object, a negative value will be returned.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

intptr_t KIM_API_get_rank(void *kimmdl, char *nm, int *kimerror);

     The functionality of this routine is the same as KIM_API_get_data,
     except it returns the rank of the data in terms of underlying
     elements. (For example, if the data is an array of shape
     [numberOfParticles,3], KIM_API_get_rank() will return 2) If no
     data with name `nm' is in the KIM API object, a negative value
     will be returned.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

intptr_t KIM_API_get_shape(void *kimmdl, char *nm, int *shape, int *kimerror);

    This routine returns the rank of `nm' and provides its shape in the argument
    `shape'.  If the name of the argument is not in the KIM API object, a
    negative value will be returned.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file

      int *shape
              An array of integers for the shape of the array data. The routine
              will set values in this array for each dimension of the data
              object (the number of these is equal to the rank value returned
              by this function).  Shape gives the extent of each index for the
              array data. Shape[0] is the slowest changing index.  Shape has to
              be allocated and should have sufficient memory to hold a value
              for each dimension.

      int *kimerror
                error code: KIM_STATUS_OK   -- successful completion,
                            KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

void KIM_API_set_shape(void *kimmdl, char *nm, int *shape, int rank, int *kimerror);

    This routine sets the `shape' of `nm' and checks if the `rank' provided is
    the same as that already stored in the KIM API object.  This will overwrite
    all of the shape data stored in the KIM API object for this argument.  This
    routine should not be used in conjunction with arguments for which
    KIM_API_allocate() has previously allocated memory.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *))

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file

      int *shape
              An array of integers for the shape of the array data.  The
              routine will use the values in this array for each dimension of
              the data object (the number of these must be equal to the rank
              value passed to the function).  Shape gives the range of each
              index for the array data.  Shape[0] is the slowest changing
              index.

      int rank
              Rank of the array and size of shape

      int *kimerror
              error code: KIM_STATUS_OK                -- successful completion,
                          KIM_STATUS_ARG_UNKNOWN       -- name nm is not in KIM
                          KIM_STATUS_ARG_INVALID_RANK  -- rank provided, does
                                                          not match KIM API
                                                          argument rank
                          KIM_STATUS_ARG_INVALID_SHAPE -- negative index in
                                                          shape

******************************************************************************

void KIM_API_set_compute(void *kimmdl, char *nm, int flag, int *kimerror);

    This routine sets the status of the `compute' flag.  If the argument can be
    optionally computed, a Model can check if a Simulator wants the argument to
    be computed.

    NOTES:

    (1) The Simulator is responsible for ensuring that memory has been
        allocated for the argument being requested.

    (2) All arguments that appear in the descriptor (.kim) files of both the
        Simulator and Model are initially set to `compute'.  Therefore, this
        routine would normally only be called if a change to this default
        behavior is desired.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      char *nm
              null terminated string is the name of the argument field, exactly
              as it appears in the .kim descriptor file.

      int flag
              KIM_COMPUTE_FALSE or KIM_COMPUTE_TRUE to turn off compute or turn
              on compute, respectively.

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

int KIM_API_get_compute(void *kimmdl, char *nm, int *kimerror);

    This routine checks the status of the `compute' flag.  If the argument can
    be optionally computed, a Model can check if a Simulator wants the argument
    to be computed.  Returned value: KIM_COMPUTE_FALSE means do not compute,
    KIM_COMPUTE_TRUE means compute.  KIM_STATUS_ARG_UNKNOWN is returned on
    error.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      char *nm
              null terminated string is the name of the argument field, exactly
              as it appears in the .kim descriptor file.

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

int KIM_API_get_index(void *kimmdl, char*nm, int *kimerror);

    This routine returns the index of an argument field in the KIM API object.
    This index serves as an integer offset that allows for efficient access to
    the KIM API object.  (This eliminates the overhead in the element access
    routines associated with using the string `nm' to search for the argument.)
    This index is guaranteed to remain valid for the lifetime of the KIM API
    object.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      char *nm
              null terminated string is the name of the argument field exactly
              as it appears in the .kim descriptor file.

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

int KIM_API_model_init(void *kimmdl);

    This routine will initialize the Model associated with the KIM API object
    by calling the init routine supplied by the Model.  It uses the Model's
    name (which is stored in KIM API object by the KIM_API_file_init routine).
    The return value will be KIM_STATUS_OK in case of success and
    KIM_STATUS_FAIL otherwise.

    NOTES:

    (1) In order to call KIM_API_model_init() it is necessary to have a valid
        KIM API object pointed to by `kimmdl' (see KIM_API_file_init() above).
        The mandatory argument `cutoff' must be registered in this KIM API
        object and it must have memory allocated to it (via either the
        KIM_API_allocate() or KIM_API_set_data() routines).

    (2) The Model's init routine must store its cutoff value in the KIM API
        object and register pointers to its `compute' function (and its
        `reinit' and `destroy' functions, if supported).  If the Model supports
        `flexible' units, it must query the KIM API object (via the
        KIM_API_get_unit_*() functions) and adjust its parameters
        appropriately.  It may also publish its parameters as either fixed or
        free (see the standard.kim file) and perform any other necessary
        initialization steps.  It is important to stress that a Model may not
        store data in static memory since it may be called with different KIM
        API objects.  Any information that should persist between calls must be
        stored in the KIM API object.  Fixed parameters may be used for this
        purpose or the Model Buffer (See details and cautionary notes about
        this in the documentation for KIM_API_set/get_model_buffer and also in
        the standard.kim file.)

    (3) The Model must define a model_init function (the name of this function
        can be any valid function name; this name must be specified in the
        Model's Makefile)
        with prototype:
           extern "C" { int My_Model_Init(void *kimmdl); }     // in C++
           int My_Model_Init(void *kimmdl);                    /* in C */
           integer(c_int) function my_model_init(pkim) bind(c) ! in Fortran 2003
              type(c_ptr), intent(in) :: pkim

    (4) ***Model Drivers*** The KIM_API, as described in this document, has no
        knowledge of the Model Driver concept.  The KIM API build system
        does all the magic to completely hide the distinction between a
        "standard Model" and a "Parameterized Model".  In practice, there is
        only one interface difference between a Model and a Model Driver.  This
        is the model_init function.  The model_init function for a Model Driver
        must accept additional arguments in order for it to have access to the
        parameter files needed to implement a particular "Paramaterized Model".
        The model_init function for a Model Driver (the name of this function
        can be any valid function name; this name must be specified in the
        Model Driver's Makefile) with prototype:
           extern "C"
           { int MD_Init(void *kimmdl, char *paramfile_names,  // in C++
                         int *nmstrlen, int *numparamfiles);
           }
           int MD_Init(void *kimmdl, char *paramfile_names,    /* in C */
                       int *nmstrlen, int *numparamfiles);
           integer(c_int) function md_init(pkim, pparamfile_names, &
                                           nmstrlen, numparamfiles) bind(C)
              type(c_ptr),        intent(in) :: pkim
              type(c_ptr), value, intent(in) :: pparamfile
              integer(c_int),     intent(in) :: nmstrlen
              integer(c_int),     intent(in) :: numparamfiles  ! in Fortran 2003

        The argument `paramfile_names' is a pointer to a 2D character array (in
        C, char paramfile_names[numparamfiles][nmstrlen]).  `nmparamfiles' and
        `nmstrlen' make up the extent of the paramfile_name array.  The i-th
        row of this array will contain a null-terminated string with the
        absolute path to the Model's i-th parameter file, which the Model
        Driver should read from.  The original parameter files are compiled
        into the Model's code which is stored in the corresponding library
        file.  At the time of the KIM_API_model_init() function call, these
        files are copied into temporary files with names obtained from the
        "tmpnam" system call.  These files are available to the Model Driver
        code only during the call to its model_init function.  After this
        function returns the system deletes these file from the system's
        filesystem by invoking the "remove" system call.

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model **)).

******************************************************************************

int KIM_API_model_reinit(void *kimmdl);

    This routine will reinitialize the Model associated with the KIM API object
    by calling the reinit routine supplied by the Model.  The return value will
    be KIM_STATUS_OK in case of success and KIM_STATUS_FAIL otherwise.

    NOTES:

    (1) In order to call KIM_API_model_reinit() it is necessary to have a valid
        KIM API object pointed to by `kimmdl' (see KIM_API_file_init()).
        Additionally, KIM_API_model_init() must have been previously executed
        for this KIM API object.

    (2) This routine must be called if the Simulator has changed one or more of
        the Model's free parameters (see standard.kim for more discussion about
        Model Parameters).

    (3) The Model may define a model_reinit function (the name of this
           function is not important) with prototype:
           extern "C" { int model_reinit(void *kimmdl); }     // in C++
           int model_reinit(void *kimmdl);                    /* in C */
           integer(c_int) function model_reinit(pkim) bind(c) ! in Fortran 2003
              type(c_ptr), intent(in) :: pkim

        If a model defines a model_reinit functions, a pointer to this function
        must be registered in the KIM_API object using one of the "set method"
        api library routines.

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

******************************************************************************

int KIM_API_get_num_model_species(void *kimmdl, int* numberSpecies, int* maxStringLength);

    This routine outputs the number of species supported by the Model and the
    associated maximum length of the particle species name strings.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int* numberSpecies
              the number of particle species supported by the Model

      int* maxStringLength
              the maximum string length found in the list of the Model's
              supported particle species name strings.

******************************************************************************

int KIM_API_get_model_species(void *kimmdl, const int index, const char** const speciesString);

    This routine outputs the requested (index) Model particle species string.
    Each string is a particle species symbol.  The order in which the species
    are indexed is unspecified, but fixed for the lifetime of the kimmdl
    object.  In the case where no particle species are specified by the Model
    or Simulator, the routine returns KIM_STATUS_FAIL for all values of index.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      const int index
              For C/C++ valid values are 0 <= index < numberSpecies.  For
              Fortran, valid values are 0 < index <= numberSpecies.  Here,
              numberSpecies is the value provided by the
              KIM_API_get_num_model_species() routine.

      const char** const speciesString
              The species name string.

******************************************************************************

int KIM_API_get_num_sim_species(void *kimmdl, int* numberSpecies, int* maxStringLength);

    This routine outputs the number of species supported by the Simulator and
    the associated maximum length of the particle species name strings.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int* numberSpecies
              the number of particle species supported by the Simulator

      int* maxStringLength
              the maximum string length found in the list of the Simulator's
              supported particle species name strings.

******************************************************************************

int KIM_API_get_sim_species(void *kimmdl, const int index, const char** const speciesString);

    This routine outputs the requested (index) Simulator particle species
    string.  Each string is a particle species symbol.  The order in which the
    species are indexed is unspecified, but fixed for the lifetime of the
    kimmdl object.  In the case where no particle species are specified by the
    Model or Simulator, the routine returns KIM_STATUS_FAIL for all values of
    index.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      const int index
              For C/C++ valid values are 0 <= index < numberSpecies.  For
              Fortran, valid values are 0 < index <= numberSpecies.  Here,
              numberSpecies is the value provided by the
              KIM_API_get_num_sim_species() routine.

      const char** const speciesString
              The species name string.

******************************************************************************

int KIM_API_get_num_params(void *kimmdl, int* numberParameters, int* maxStringLength);

    This routine outputs the number of parameters supported by the Model and
    the associated maximum length of the parameter name strings.  A Model
    parameter argument is one whose name starts with `PARAM_FREE_' or
    `PARAM_FIXED_'.  Each parameter argument described in the Model's ".kim"
    file will have a place in the KIM API object, but it will not be checked
    against the standard.kim file.  (See the standard.kim file for more
    information on Model parameters.)

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int* numberParameters
              the number of parameters supported by the Model

      int* maxStringLength
              the maximum string length found in the list of the Model's
              supported parameter name strings.

******************************************************************************

int KIM_API_get_parameter(void *kimmdl, const int index, const char** const parameterString);

    This routine outputs the requested (index) Model parameter name string.
    The order in which the parameters are indexed is unspecified, but fixed for
    the lifetime of the kimmdl object.  In the case where no parameters are
    supported the Model, the routine returns KIM_STATUS_FAIL for all values of
    index.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      const int index
              For C/C++ valid values are 0 <= index < numberParameters.  For
              Fortran, valid values are 0 < index <= numberParameters.  Here,
              numberParameters is the value provided by the
              KIM_API_get_num_params() routine.

      const char** const parameterString
              The parameter name string.

******************************************************************************

int KIM_API_get_num_free_params(void *kimmdl, int* numberFreeParameters, int* maxStringLength);

    This routine outputs the number of free parameters supported by the Model
    and the associated maximum length of the parameter name strings.  A Model
    free parameter argument is one whose name starts with `PARAM_FREE_'.  Each
    parameter argument described in the Model's ".kim" file will have a place
    in the KIM API object, but it will not be checked against the standard.kim
    file.  (See the standard.kim file for more information on Model
    parameters.)

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int* numberFreeParameters
              the number of free parameters supported by the Model

      int* maxStringLength
              the maximum string length found in the list of the Model's
              supported free parameter name strings.

******************************************************************************

int KIM_API_get_free_parameter(void *kimmdl, const int index, const char** const freeParameterString);

    This routine outputs the requested (index) Model free parameter name
    string.  The order in which the parameters are indexed is unspecified, but
    fixed for the lifetime of the kimmdl object.  In the case where no free
    parameters are supported the Model, the routine returns KIM_STATUS_FAIL for
    all values of index.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      const int index
              For C/C++ valid values are 0 <= index < numberFreeParameters.
              For Fortran, valid values are 0 < index <= numberFreeParameters.
              Here, numberFreeParameters is the value provided by the
              KIM_API_get_num_free_params() routine.

      const char** const freeParameterString
              The free parameter name string.

******************************************************************************

int KIM_API_get_num_fixed_params(void *kimmdl, int* numberFixedParameters, int* maxStringLength);

    This routine outputs the number of fixed parameters supported by the Model
    and the associated maximum length of the parameter name strings.  A Model
    fixed parameter argument is one whose name starts with `PARAM_FIXED_'.
    Each parameter argument described in the Model's ".kim" file will have a
    place in the KIM API object, but it will not be checked against the
    standard.kim file.  (See the standard.kim file for more information on
    Model parameters.)

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int* numberFixedParameters
              the number of fixed parameters supported by the Model

      int* maxStringLength
              the maximum string length found in the list of the Model's
              supported fixed parameter name strings.

******************************************************************************

int KIM_API_get_fixed_parameter(void *kimmdl, const int index, const char** const fixedParameterString);

    This routine outputs the requested (index) Model fixed parameter name
    string.  The order in which the parameters are indexed is unspecified, but
    fixed for the lifetime of the kimmdl object.  In the case where no fixed
    parameters are supported the Model, the routine returns KIM_STATUS_FAIL for
    all values of index.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      const int index
              For C/C++ valid values are 0 <= index < numberFixedParameters.
              For Fortran, valid values are 0 < index <= numberFixedParameters.
              Here, numberFixedParameters is the value provided by the
              KIM_API_get_num_fixed_params() routine.

      const char** const fixedParameterString
              The fixed parameter name string.

******************************************************************************

int KIM_API_get_NBC_method(void *kimmdl, const char** const NBC_String);

    This routine outputs a string with the NBC name.  The string is the NBC
    (Neighbor list and Boundary Conditions) "active" NBC method in use by the
    KIM_API object `kimmdl'.  (See the standard.kim file for more information
    on NBC methods.)

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      const char** const NBC_String
              The NBC string.

******************************************************************************

int KIM_API_get_species_code(void *kimmdl, char* particle, int *kimerror);

    This routine returns the particle species ID for a given particle symbol,
    as defined by the Model associated with the KIM API object.  The routine
    returns KIM_STATUS_PARTICLE_SPECIES_UNDEFINED if no particle species have
    been provided in the .kim files.  (See the standard.kim file for more
    information on particle species.)  The routine returns
    KIM_STATUS_PARTICLE_INVALID_SPECIES if the supplied symbol, particle, is
    not among the KIM supported particle symbols.  (See standard.kim for the
    list of supported particle species.)

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      char *particle
              particle symbol

      int *kimerror
              error code: KIM_STATUS_OK                       -- successful completion
                          KIM_STATUS_FAIL                     -- unsuccessful
                          KIM_STATUS_PARTICLE_INVALID_SPECIES -- symbol is not among the
                                                                 KIM supported particle symbols
                          KIM_STATUS_PARTICLE_SPECIES_UNDEFINED -- no particle species
                                                                   have been specified by
                                                                   the Simulator or Model.

******************************************************************************

void KIM_API_set_species_code(void *kimmdl, char* particle, int code, int *kimerror);

    This routine sets the particle species ID for a given particle symbol.
    Only those particle species which the Model listed with code `-1' in its
    descriptor file may be changed.  The routine returns
    KIM_STATUS_PARTICLE_SPECIES_UNDEFINED if no particle species have been
    provided in the .kim files.  (See the standard.kim file for more
    information on particle speciess.)  The routine returns
    KIM_STATUS_PARTICLE_INVALID_SPECIES if the supplied symbol, particle, is
    not among the KIM supported particle symbols.  (See standard.kim for the
    list of supported particle species.)

Arguments:
      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      char *particle
              particle symbol

      int code
              integer value used by the Model to represent the specified particle species

      int *kimerror
              error code: KIM_STATUS_OK                       -- successful completion
                          KIM_STATUS_FAIL                     -- unsuccessful
                          KIM_STATUS_PARTICLE_INVALID_SPECIES -- symbol is not among the
                                                                 KIM supported particle symbols
                          KIM_STATUS_PARTICLE_SPECIES_UNDEFINED -- no particle species
                                                                   have been specified by
                                                                   the Simulator or Model.

******************************************************************************

int KIM_API_get_model_kim_str(char *modelname, char** const kimString);

    This routines outputs a pointer to a NULL terminated string containing the
    complete KIM descriptor file for the Model modelname.  The memory pointed
    to by this pointer is allocated by the routine, but should be released by
    the user to avoid a memory leak (Fortran 2003 users should use
    KIM_API_c_free()).  If any errors occur they are fatal and the routine
    prints a message to kim.log and exits.

Return value:
      KIM_STATUS_OK

Arguments:

      char *modelname
              model name in KIM

      char** const kimString
              The Model's ".kim" file string

******************************************************************************

int KIM_API_get_neigh_mode(void *kimmdl, int *kimerror);

    This routine returns a code for the neighbor list mode that should be used
    by the Model and Simulator.  The codes and their corresponding meanings
    are:
         1  -- for Iterator mode
         2  -- for Locator mode
         3  -- for Both (Model needs iterator and locator mode)

    The routine returns a negative value if it encounters an error.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style the definition
              will be (KIM_API_model *)).

      int *kimerror
              error code: KIM_STATUS_OK   -- successful completion,
                          KIM_STATUS_FAIL -- unsuccessful

******************************************************************************

int KIM_API_get_neigh(void *kimmdl, int mode, int request, int *particle,
                      int *numnei, int **nei1particle, double **rij);

    This routine provides standardized access to the neighbor list supplied by
    the Simulator.  The Simulator must have previously registered, in the KIM
    API object, a pointer to its neighbor list access routine with the same
    interface as above (except that `mode' and `request' must be of type `int
    *'). That is,
       extern "C"                                              // in C++
       { int get_neigh(void *kimmdl, int *mode, int* request,
                       int *particle, int *numnei, int **nei1particle,
                       double **rij);
       }
       int get_neigh(void *kimmdl, int *mode, int* request,    /* in C */
                     int *particle, int *numnei, int **nei1particle,
                     double **rij);
       integer(c_int) function get_neigh(pkim, mode, request,& ! in Fortran 2003
                                         part, numnei, pnei1part, &
                                         pRij) bind(c)
          type(c_ptr)),   intent(in)  :: pkim
          integer(c_int), intent(in)  :: mode
          integer(c_int), intent(in)  :: request
          integer(c_int), intent(out) :: part
          integer(c_int), intent(out) :: numnei
          type(c_ptr),    intent(out) :: pnei1part
          type(c_ptr),    intent(out) :: pRij

    Two modes are supported: `Iterator' and `Locator'.  In Iterator mode, the
    Iterator should, first, be reset.  Then, a call to this function will
    return the neighbor list for the "next" particle (the order in which
    particles are returned is immaterial in Iterator mode, and therefore
    undefined).  This process repeats until the neighbor list of every particle
    has been returned and the iterator is incremented past the end of the list.
    In Locator mode, the user explicitly requests the particle for which a
    neighbor list is desired.  This mode must be used when the order in which
    particle neighbor lists are processed is important.

    NOTE: The list of neighbors returned for a given particle should not
          include the particle itself unless it is an image particle with a
          non-zero rij vector entry. (See explanation of rij vectors below.)

    The return value depends on the results of execution:
      KIM_STATUS_NEIGH_ITER_INIT_OK             -- iterator has been
                                                   successfully initialized
      KIM_STATUS_OK                             -- successful operation
      KIM_STATUS_NEIGH_ITER_PAST_END            -- iterator has been
                                                   incremented past end of list
      KIM_STATUS_NEIGH_INVALID_REQUEST          -- invalid particle ID requested
                                                   (request out of range)
      KIM_STATUS_NEIGH_INVALID_MODE             -- invalid mode value
      KIM_STATUS_API_OBJECT_INVALID             -- invalid KIM API object
      KIM_STATUS_NEIGH_TOO_MANY_NEIGHBORS       -- Number of neighbors of a
                                                   particle too big to allocate
                                                   memory for index conversion
      KIM_STATUS_NEIGH_METHOD_NOT_PROVIDED      -- get_neigh method in
                                                   KIM API object is not
                                                   set (NULL value)
Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int mode
              Operate in iterator or locator mode
              mode = 0 : iterator mode
              mode = 1 : locator mode

      int request
              Requested operation
              If mode = 0
                  request = 0 : reset iterator (and return without neighbors)
                  request = 1 : increment iterator
              If mode = 1
                  request = # : number of particle whose neighbor list is
                                requested.  This id should be 0-based if the
                                Model includes ZeroBasedLists in its KIM
                                descriptor file and 1-based if OneBasedLists is
                                included.  (The KIM API will automatically do
                                any necessary conversions.)

      int *particle
              The number of the particle whose neighbor list is returned.  This
              id value will be 0-based if the Model includes ZeroBasedLists in
              its KIM descriptor file and 1-based if OneBasedLists is included.
              (The KIM API will automatically do any necessary conversions.)

      int *numnei
              number of neighbors returned

      int **nei1particle
               pointer argument which will point to the list of neighbors on
               exit.  The neighbor ID values stored in this list will be
               0-based if the Model includes ZeroBasedLists in its KIM
               descriptor file and 1-based if OneBasedLists is included.  (The
               KIM API will automatically do any necessary conversions.)

      double **rij
              pointer argument which will point to the list of relative
              position vectors of the neighbors of a `particle', i.e. if the
              particle index is `i' and its neighbors are indexed by `j', then
              r_ij = x_j - x_i (including boundary conditions if applied). This
              data is only available for NBC method NEIGH_RVEC_F. The returned
              value is NULL for all other NBC methods. (See standard.kim for
              more information on NBC methods.)

******************************************************************************

int KIM_API_process_dEdr(void **km, double *dEdr, double *r, double **dx, &
                          int *i, int *j);

    This routine can be called by a Model to provide the Simulator with a
    contribution, dEdr, to the first derivative of the Model's energy with
    respect to the (scalar) distance r_ij between particle `i' and particle
    `j'.  The Simulator can use this information to compute, via the
    chain-rule, many properties.  Examples include forces, the virial, and
    other thermodynamic tensions.  The KIM API performs automatic index
    conversion (based on ZeroBasedLists and OneBasedLists flag settings) before
    calling the Simulator's supplied process_dEdr function.  If the Simulator
    provides a process_dEdr function, it must register, in the KIM API object,
    a pointer to this function.  The function must conform to the following
    interface:
       extern "C" { int process_dEdr(void *kimmdl,             // in C++
                                     double *dEdr,
                                     double *r, double **dx,
                                     int *i, int *j); }
       int process_dEdr(void *kimmdl, double *dEdr, double *r, /* in C */
                        double **dx, int *i, int *j);
       integer(c_int) function process_dEdr(pkim, dEdr, &      ! in Fortran 2003
                                            r, pdx, i, j) bind(c)
          type(c_ptr),    intent(in) :: pkim
          real(c_double), intent(in) :: dEdr
          real(c_double), intent(in) :: r
          type(c_ptr),    intent(in) :: pdx
          integer(c_int), intent(in) :: i
          integer(c_int), intent(in) :: j

    If the Simulator does not provide its own process_dEdr routine, then the
    KIM API standard process_dEdr routine is used.  If the standard
    process_dEdr routine is used, the KIM API ensures that any appropriate
    memory initializations are performed.  This routine currently supports the
    computation of `virial' and `particleVirial'.  Return value: KIM_STATUS_OK
    if successful and KIM_STATUS_FAIL if unsuccessful.

Arguments:

      void **km
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model **)).

      double *dEdr
              pointer to the contribution to the first derivative of the energy
              with respect to the pair-distance r_ij (dE/dr_ij).

      double *r
              pointer to r_ij -- the distance between particles i and j

      double **dx
              pointer to the relative position vector of particle j
              relative to particle i (i.e., r_ij = x_j - x_i).

      int *i
              pointer to particle index i

      int *j
              pointer to particle index j

******************************************************************************

int KIM_API_process_d2Edr2(void **km, double *d2Edr2, double **r, &
                            double **dx, int **i, int **j);

    This routine can be called by a Model to provide the Simulator with a
    contribution, d2Edr2, to the second derivative of the Model's energy with
    respect to the (scalar) distances r_i[0]j[0] and r_i[1]j[1] between
    particle i[0] and j[0] and between particles i[1] and j[1], respectively.
    The Simulator can use this information (often in conjunction with
    information from process_dEdr) to compute, via the chain-rule, many
    properties.  An example is the hessian.  The KIM API performs automatic
    index conversion (based on ZeroBasedLists and OneBasedLists flag settings)
    before calling the Simulator's supplied process_d2Edr2 function.  If the
    Simulator provides a process_d2Edr2 function, it must register, in the KIM
    API object, a pointer to this function.  The function must conform to the
    following interface:
       extern "C" { int process_d2Edr2(void *kimmdl,           // in C++
                                       double *d2Edr2, double **r,
                                       double **dx, int **i, int **j); }
       int process_d2Edr2(void *kimmdl, double *d2Edr2,        /* in C */
                          double **r, double **dx, int **i, int **j);
       integer function process_d2Edr2(pkim, d2Edr2, &         ! in Fortran 2003
                                       pr, pdx, pi, pj)
          type(c_ptr),    intent(in) :: pkim
          real(c_double), intent(in) :: d2Edr2
          type(c_ptr),    intent(in) :: pr
          type(c_ptr),    intent(in) :: pdx
          type(c_ptr),    intent(in) :: pi
          type(c_ptr),    intent(in) :: pj

    If the Simulator does not provide its own process_d2Edr2 routine, then the
    KIM API standard process_d2Edr2 routine is used.  If the standard
    process_dEdr routine is used, the KIM API ensures that any appropriate
    memory initializations are performed.  This routine and currently supports
    the computation of `hessian' (process_dEdr is also required in order to
    correctly compute the hessian).  Return value: KIM_STATUS_OK if successful
    and KIM_STATUS_FAIL if unsuccessful.

Arguments:

      void **km
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model **)).

      double *d2Edr2
              pointer to contribution to the second derivative of energy with
              respect to the pair-distances r_i[0]j[0] and r_i[1]j[1]
              (d^2E/dr_kl dr_mn).

      double **r
              pointer to array of two doubles -- the distances r[0] and r[1]
              between particles i[0] and j[0] and i[1] and j[1], respectively.

      double **dx
              pointer to the relative position vectors {dx[0], dx[1], dx[2]}
              and {dx[3], dx[4], dx[5]} of particle j[0] relative to i[0] and
              j[1] relative to i[1], respectively.

      int **i
              pointer to particle indices i[0] and i[1]

      int **j
              pointer to particle indices j[0] and j[1]

******************************************************************************

int KIM_API_get_status_msg(int status_code, const char** const status_msg);

    This routine outputs a null terminated character string that describes the
    `status_code'.  `status_code' should contain a `kimerror' code returned by
    a KIM library routine.

Return value:
      KIM_STATUS_OK   -- successful completion
      KIM_STATUS_FAIL -- unsuccessful

Arguments:
      int status_code
              kimerror code for which a description is desired.

      const char** const status_msg
              The message string

******************************************************************************

int KIM_API_report_error(int line, char *file, char *usermsg, int status_code);

    This routine prints the standard KIM error message associated with
    `status_code' as well as the user supplied message `usermsg'.  It returns
    KIM_STATUS_FAIL if status_code is less than KIM_STATUS_OK. Otherwise it
    returns KIM_STATUS_OK.

Arguments:

      int line
              line in the file where the call is made (the preprocessor value
              of __LINE__ may be used here)

      char * file
              name of the file from which the call is made (the preprocessor
              value of __FILE__ may be used here)

      char * usermsg
              user defined error message

      int status_code
              kimerror status code returned by a KIM library routine.

******************************************************************************

double KIM_API_get_scale_conversion(char *u_from, char *u_to, int *kimerror);

    This routine returns the scale conversion factor between one unit and
    another.  For example, KIM_API_get_scale_conversion("cm","m", &kimerror)
    will return the value 0.01.  Both `u_from' and `u_to' must be from the same
    supported base unit (length, energy, charge, temperature, or time).  See
    standard.kim for valid values within each base unit.  The function returns
    a negative value if an error occurs.

Arguments:

      char *u_from
              conversion from unit string

      char *u_to
              conversion to unit string

      int *kimerror
              error status -- a standard KIM_STATUS value

******************************************************************************

int KIM_API_get_unit_handling(void *kimmdl, int *kimerror);

    Returns 1 if Unit_Handling is `flexible', 0 otherwise.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              KIM_STATUS_OK is always returned

******************************************************************************

char *KIM_API_get_unit_length(void *kimmdl, int *kimerror);

    Returns the current setting of the KIM_API_model object for the base unit
    of length.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              KIM_STATUS_OK is always returned

******************************************************************************

char *KIM_API_get_unit_energy(void *kimmdl, int *kimerror);

    Returns the current setting of the KIM_API_model object for the base unit
    of energy.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              KIM_STATUS_OK is always returned

******************************************************************************

char *KIM_API_get_unit_charge(void *kimmdl, int *kimerror);

    Returns the current setting of the KIM_API_model object for the base unit
    of charge.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              KIM_STATUS_OK is always returned

******************************************************************************

char *KIM_API_get_unit_temperature(void *kimmdl, int *kimerror);

    Returns the current setting of the KIM_API_model object for the base unit
    of temperature.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              KIM_STATUS_OK is always returned

******************************************************************************

char *KIM_API_get_unit_time(void *kimmdl, int *kimerror);

    Returns the current setting of the KIM_API_model object for the base unit
    of time.

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      int *kimerror
              KIM_STATUS_OK is always returned

******************************************************************************

double KIM_API_convert_to_act_unit(void *kimmdl, char *length, char *energy,
                                   char *charge, char *temperature, char *time,
                                   double length_exponent,
                                   double energy_exponent,
                                   double charge_exponent,
                                   double temperature_exponent,
                                   double time_exponent,
                                   int *kimerror);

    This function returns scale conversion factor for a derived unit from the
    supplied base units to the "active" set of base units associated with the
    KIM API object kimmdl.  The derived unit is defined by the supplied
    exponents for each of the base units.  If the supplied base units are not
    among the standard supported base units (see standard.kim), an appropriate
    KIM status code is returned.  For example, consider the conversion of the
    quantity `10 N/s' to the equivalent active unit.  C code for this would be:

      double forcePerTime = 10.0; /* N/s */
      forcePerTime *= KIM_API_convert_to_act_unit(kimmdl,
                                                   "m",  "J", "C", "K",  "s",
                                                  -1.0,  1.0, 0.0, 0.0, -1.0,
                                                  kimerror);

Arguments:

      void *kimmdl
              pointer to KIM_API_model object (in C++ style, the definition
              will be (KIM_API_model *)).

      char *length
              base unit of length string

      char *energy
              base unit of energy string

      char *charge
              base unit of charge string

      char *temperature
              base unit of temperature string

      char *time
              base unit of time string

      double length_exponent
              exponent for length contribution to derived unit

      double energy_exponent
              exponent for energy contribution to derived unit

      double charge_exponent
              exponent for charge contribution to derived unit

      double temperature_exponent
              exponent for temperature contribution to derived unit

      double time_exponent
              exponent for time contribution to derived unit

      int *kimerror
              KIM_STATUS_OK (if successful completion)

******************************************************************************



==================ELEMENT ACCESS METHODS ROUTINES BY INDEX====================

The "by index" routines have the same functionality as "by name" and the same
arguments except "char *nm" is replaced by "int I".  The index of each argument
in the KIM API object is obtained by the KIM_API_get_index() routine described
above.

The prototypes of the supported "by index" routines are:

int KIM_API_set_data_by_index(void *kimmdl, int I, intptr_t size, void *dt);
int KIM_API_set_method_by_index(void *kimmdl, int I, intptr_t size, func_ptr dt);

void *KIM_API_get_data_by_index(void *kimmdl, int I, int *kimerror);
func_ptr KIM_API_get_method_by_index(void *kimmdl, int I, int *kimerror);

intptr_t KIM_API_get_size_by_index(void *kimmdl, int I, int *kimerror);

intptr_t KIM_API_get_rank_by_index(void *kimmdl, int I, int *kimerror);

intptr_t KIM_API_get_shape_by_index(void *kimmdl, int I, int *shape, int *kimerror);

void KIM_API_set_compute_by_index(void *kimmdl, int I, int flag, int *kimerror);

int KIM_API_get_compute_by_index(void *kimmdl, int I, int *kimerror);



******************************************************************************

                          MULTIPLE ACCESS ROUTINES

******************************************************************************

In order to simplify access to KIM API object, MULTIPLE ACCESS ROUTINES are
included among the KIM library methods.  There are 13 of these routines:

c-style:
      1) KIM_API_getm_compute
      2) KIM_API_setm_compute
      3) KIM_API_getm_compute_by_index
      4) KIM_API_setm_compute_by_index
      5) KIM_API_getm_data
      6) KIM_API_getm_method
      7) KIM_API_setm_data
      8) KIM_API_setm_method
      9) KIM_API_getm_data_by_index
     10) KIM_API_getm_method_by_index
     11) KIM_API_setm_data_by_index
     12) KIM_API_setm_method_by_index
     13) KIM_API_getm_index

     Each of these routines provides access to multiple KIM API object
     arguments in one function call.  These routines have a uniform
     interface:

     void KIM_API_*m_*(void *kimmdl, int *kimerror, int numargs, ...);

     A code line that calls these routine will look like:

     KIM_API_*m_*(kimmdl, &kimerror, numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

     numargs -- must be the number of all arguments that follows it.

     There can be up to 15 VARIABLE_GROUPs in one call.  Each
     VARIABLE_GROUP has either 3 or 4 function arguments.  Therefore
     numargs must be divisible by either 3 or 4 (depending on which
     MULTIPLE ACCESS function is being called).  VARIABLE_GROUPS have
     different types of function arguments depending on the context.  The
     last variable in the group is always an integer flag (gkey) which can
     be 1 or 0.  If gkey = 1 the routine will perform the requested
     operation for the associated VARIABLE_GROUP, if gkey=0 the
     VARIABLE_GROUP will be skipped.

     The VARIABLE_GROUP definitions are:

      1.  void KIM_API_getm_compute(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: char *name, int *compute, int gkey

      2.  void KIM_API_setm_compute(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: char *name, int compute, int gkey

      3.  void KIM_API_getm_compute_by_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: int index, int *compute, int gkey

      4.  void KIM_API_setm_compute_by_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: int index, int compute, int gkey

      5.  void KIM_API_getm_data(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: char *name, void **data, int gkey

      6.  void KIM_API_getm_method(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: char *name, func_ptr *method, int gkey

      7.  void KIM_API_setm_data(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 4 variables: char *name, intptr_t size, void *data, int gkey

      8.  void KIM_API_setm_method(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 4 variables: char *name, intptr_t size, func_ptr data, int gkey

      9.  void KIM_API_getm_data_by_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: int index, void **data, int gkey

     10.  void KIM_API_getm_method_by_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 3 variables: int index, func_ptr *method, int gkey

     11.  void KIM_API_setm_data_by_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 4 variables: int index, intptr_t size, void *data, int gkey

     12.  void KIM_API_setm_method_by_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...]);

          Here VARIABLE_GROUP has 4 variables: int index, intptr_t size, func_ptr method, int gkey

     13.  void KIM_API_getm_index(void *kimmdl, int *kimerror, int numargs, VARIABLE_GROUP1, [VARIABLE_GROUP2, ...] );

          Here VARIABLE_GROUP has 3 variables: char *name, int *index, int gkey

    `kimerror' in these routines will be KIM_STATUS_OK if the routine is successful,
    otherwise KIM_STATUS_FAIL (or other error codes < KIM_STATUS_OK).

Fortran Style:

    The interface here is exactly as it is for the c-style, except that the
    `numargs' argument is not required.


    As an example, in C, suppose a Model wants to determine if the Simulator
    has requested that the `energy', `virial', and/or the `hessian' should be
    computed.  Then, for each requested argument the Model needs to get a
    memory pointer to know where to store the results of the computations.  The
    corresponding code looks like:

      int     comp_energy,  comp_virial,  comp_hessian;
      double *energy_data, *virial_data, *hessian_data;
      KIM_API_getm_compute(kimmdl, &kimerror, 3*3,
                           "energy",  &comp_energy,  1,
                           "virial",  &comp_virial,  1,
                           "hessian", &comp_hessian, 1);
      KIM_API_getm_data(kimmdl, &kimerror, 3*3,
                        "energy",   &energy_data,  (comp_energy  == 1),
                        "virial",   &virial_data,  (comp_virial  == 1),
                        "hessian",  &hessian_data, (comp_hessian == 1));

      If the Simulator has not requested computation of the `virial', for
      example, then the `comp_virial' variable will be set to zero by the call
      to KIM_API_getm_compute().  Then, in the KIM_API_getm_data() call the
      logical statement (comp_virial == 1) will evaluate to false (0) and the
      value of the `virial_data' will not be retrieved.

******************************************************************************

*** END of KIM_API_Description.txt file ***
