kim-api  2.0.2+v2.0.2.GNU An Application Programming Interface (API) for the Knowledgebase of Interatomic Models (KIM).
Implementation

Previous Section: Theory.

In code, a model (or model driver) consists of up to eight routines which perform specific tasks:

1. The ModelCreate (or ModelDriverCreate ) routine (required), which performs initialization tasks for the model object.
2. The ModelComputeArgumentsCreate routine (required), which performs initialization tasks for a compute-arguments object.
3. The ModelCompute routine (required), which uses the configuration information stored in a compute-arguments object to perform the model's core computational tasks.
4. The ModelExtension routine (optional), which provides a mechanism for creating and using non-standard extensions to the KIM API.
5. The ModelRefresh routine (required if parameter pointers are set, otherwise should not be provided), which performs updates after a simulator makes changes to the model's parameters (if this is supported).
6. The ModelWriteParameterizedModel (optional) routine, which can be used to write the parameter files and CMake file necessary to create a new parameterized model from the current set of in-memory parameters.
7. The ModelComputeArgumentsDestroy routine (required), which performs finalization tasks for a compute-arguments object.
8. The ModelDestroy routine (required), which performs finalization tasks for the model object.

These are summarized in the following table.

Model Routine Required / Optional
KIM::MODEL_ROUTINE_NAME::Create required
KIM::MODEL_ROUTINE_NAME::ComputeArgumentsCreate required
KIM::MODEL_ROUTINE_NAME::Compute required
KIM::MODEL_ROUTINE_NAME::Extension optional
KIM::MODEL_ROUTINE_NAME::Refresh required if one or more parameter pointers set, otherwise should not be provided
KIM::MODEL_ROUTINE_NAME::WriteParameterizedModel optional
KIM::MODEL_ROUTINE_NAME::ComputeArgumentsDestroy required
KIM::MODEL_ROUTINE_NAME::Destroy required

The above table indicates which routines must be provided by a model. For optional routines, each model must indicate that the routine is required or optional for use by the simulator, as described below.

The interaction between the simulator and a model involves the following steps:

• A simulator creates a model object, by calling KIM::Model::Create, that will be used to exchange pointers to data and functions related to the model between the simulator and model. Creating this object includes the specification of how the simulator will number particles (zero-based or one-based), determination of the physical base units that the model will use, and execution of the model's ModelCreate routine.

When calling KIM::Model::Create to create a model object, the simulator provides a set of "requested" base units that it would prefer to use. The KIM API gives the model final authority to decide on the base units it will use. Best practice for models is to respect the request of the simulator and to use the requested base units by converting its parameters appropriately. The requestedUnitsAccepted output argument of the KIM::Model::Create routine is a convenience that allows the simulator a short-cut to determine if its request for base units was accepted. (The alternative is for the simulator to call to KIM::Model::GetUnits and compare the results to the requested units.)

If a base unit is not relevant to the simulator (e.g., a unit of time is not necessary for static equilibrium computations), then the simulator should specify that the corresponding requested base unit(s) is/are "unused". Similarly, if a base unit is irrelevant to the model (e.g., many models only require units of length and energy; Thus, units of charge, temperature, and time are irrelevant), then the model should specify that the corresponding base unit(s) is/are "unused" (regardless of the simulator's requested values) when calling KIM::ModelCreate::SetUnits within its ModelCreate routine. Additionally, the model should select its preferred (non-"unused") base unit value when the simulator provides a request of "unused" for a relevant base unit.

• Once a model object is obtained, the simulator should use KIM::Model::IsRoutinePresent to determine which routines the model has provided and if they are required or optional. From this information the simulator should determine if it can proceed to work with the model, or if the model requires the use of routines that are not supported by the simulator it should exit.
• Next, the simulator creates a compute-arguments object, by calling KIM::Model::ComputeArgumentsCreate, that will be used to exchange pointers to data and functions related to the atomic configuration and values being computed for it. Creating this object includes execution of the model's ModelComputeArgumentsCreate routine.
• Then, to perform a computation, the simulator provides a compute-arguments object to the KIM::Model::Compute routine (which, in part, executes the model's ModelCompute function).
• There are input compute-arguments that include the various components that make up a configuration (number of particles, particle position vectors, etc.).
• There are output compute-arguments that include the quantities (like partial energy and partial forces), defined in Section Theory, associated with the configuration.
• There are also compute-callback functions (such as a function to get a particle's neighbor list) that the simulator provides for use by the model.
• When a simulator is finished working with a model, it needs to clean up by calling KIM::Model::ComputeArgumentsDestroy (which, in part, executes the model's ModelComputeArgumentsDestroy routine) to delete each of the compute-arguments objects that were created, and finally calling KIM::Model::Destroy (which, in part, executes the model's ModelDestroy routine) to delete the model object.

The KIM API provides a list of all compute-arguments and compute-callbacks defined as part of the official API. Each argument and callback has a "Support Status" that can be one of four values: requiredByAPI, notSupported, required, or optional. A model specifies a support status value, as part of its ModelComputeArgumentsCreate routine, for every compute-argument and compute-callback defined by the KIM API. It is the responsibility of the simulator to use the compute-arguments object interface to determine the support status of each compute-argument and compute-callback and to use this information to determine if the model is capable of performing the desired computation.

Below, lists of each input compute-argument, output compute-argument, and compute-callback are provided. To be explicit, zero-based particle numbering is used where necessary.

Input compute-argument table:

Compute Argument Name Unit Data Type Extent Memory Layout Valid Support Statuses (bold – default)
numberOfParticles N/A integer 1 requiredByAPI
particleSpeciesCodes N/A integer numberOfParticles $$sc^{(0)}, sc^{(1)}, \dots$$ requiredByAPI
particleContributing N/A integer numberOfParticles $$c^{(0)}, c^{(1)}, \dots$$ requiredByAPI
coordinates length double numberOfParticles * 3 $$r^{(0)}_1, r^{(0)}_2, r^{(0)}_3, r^{(1)}_1, r^{(1)}_2, \dots$$ requiredByAPI
• numberOfParticles is the number of particles (contributing and non-contributing) in the configuration.
• particleSpeciesCodes contains integer codes (as defined by the model) specifying the species of each particle. For example, if the model defines the mapping Cu $$\leftrightarrow 1$$, Al $$\leftrightarrow 2$$, and Ni $$\leftrightarrow 3$$, then $$sc^{(0)} = 3, sc^{(1)} = 1, sc^{(2)} = 2, \dots$$ means that particle 0 is a nickel atom, particle 1 is a copper atom, particle 2 is an aluminum atom.
• particleContributing contains the contributing/non-contributing status of each particle. Particle $$i$$ is contributing if $$c^{(i)} = 1$$ and non-contributing if $$c^{(i)} = 0$$.
• coordinates contains the Cartesian components of the particles' position vectors, $$\mathbf{r}^{(i)} = r^{(i)}_1 \mathbf{e}_1 + r^{(i)}_2 \mathbf{e}_2 + r^{(i)}_3 \mathbf{e}_3$$.

Output compute-argument table:

Compute Argument Name Unit Data Type Extent Memory Layout Valid Support Statuses (bold – default)
partialEnergy energy double 1 required, optional, notSupported
partialForces force double numberOfParticles * 3 $$f^{\mathcal{C}(0)}_1, f^{\mathcal{C}(0)}_2, f^{\mathcal{C}(0)}_3, f^{\mathcal{C}(1)}_1, f^{\mathcal{C}(1)}_2\dots$$ required, optional, notSupported
partialParticleEnergy energy double numberOfParticles $$E^{\mathcal{C}}_0, E^{\mathcal{C}}_1, E^{\mathcal{C}}_2, \dots$$ required, optional, notSupported
partialVirial energy double 6 $$V^{\mathcal{C}}_{11}, V^{\mathcal{C}}_{22}, V^{\mathcal{C}}_{33}, V^{\mathcal{C}}_{23}, V^{\mathcal{C}}_{31}, V^{\mathcal{C}}_{12}$$ required, optional, notSupported
partialParticleVirial energy double numberOfParticles * 6 $$\mathbf{V}^{\mathcal{C}(0)}, \mathbf{V}^{\mathcal{C}(1)}, \mathbf{V}^{\mathcal{C}(2)}, \dots$$ required, optional, notSupported
• partialEnergy is the configuration's partial energy $$E^{\mathcal{C}}$$.
• partialForces contains the partial force vector for each particle, $$\mathbf{f}^{\mathcal{C}(i)} = f^{\mathcal{C}(i)}_1 \mathbf{e}_1 + f^{\mathcal{C}(i)}_2 \mathbf{e}_2 + f^{\mathcal{C}(i)}_3 \mathbf{e}_3$$.
• partialParticleEnergy contains the partial particle energy for each particle, $$E^{\mathcal{C}}_i$$.
• partialVirial is the configuration's partial virial tensor, $$\mathbf{V}^{\mathcal{C}}$$.
• partialParticleVirial contains the partial particle virial tensor for each particle, $$\mathbf{V}^{\mathcal{C}(i)}$$.

Compute-callback table:

Compute Callback Name Valid Support Statuses (bold – default)
GetNeighborList requiredByAPI
ProcessDEDrTerm required, optional, notSupported
ProcessD2EDr2Term required, optional, notSupported
• GetNeighborList is a callback function that allows a model to obtain the list of neighbors of a particle. The model may request any number ( $$\ge1$$) of neighbor lists with different (or equal) cutoff distances. The GetNeighborList callback function must support the return of the appropriate list of neighbors. The returned list of neighbors consists of a contiguous-in-memory list of integers corresponding to an unordered full list of a particle's neighbors (not including itself). Each such neighbor list must contain at least all particles within the corresponding cutoff distance of the specified particle. (However, the returned list may contain particles beyond the cutoff distance.) Neighbor lists provided by the simulator must be consistent with the configuration coordinates and the model's cutoff values. In particular, the model must, in principle, be able to independently construct its own equivalent neighbor list using just the particle coordinates. Further, the GetNeighborList callback routine must check to ensure that the neighbor list data (provided, via the simulator, by the compute-arguments object) is consistent with the model's cutoff values.

CAUTION - SIMULATOR DEVELOPERS: In general, it is important that neighbor lists provided by a simulator are "efficient" in the sense that the list contains only a small number of particles that are located outside the cutoff distance. If the lists are not efficient, then the model computational time may be severely impacted. This is especially true for models that request multiple neighbor lists with a wide range of cutoff distances.

Neighbor List Hint: The above describes the default behavior and all models must work correctly when provided with neighbor lists of this type. However, based on the neighbor list hint provided by the model a simulator may provide the model with a modified neighbor list that is more efficient. If the model sets its "modelWillNotRequestNeighborsOfNoncontributingParticles" value to 1 (true), it is guaranteeing that it will not request the neighbors of non-contributing particles. In this case, the simulator does not need to generate a neighbor list for such particles. The model has no way of knowing if the simulator is taking advantage of its hint, so it must work correctly for all types of neighbor lists consistent with its provided hint.

• ProcessDEDrTerm is a callback function that allows for access to the derivatives of the configuration's partial energy, $$E^{\mathcal{C}}$$, with respect to all pair-distances, $$r^{(i,j)}, i,j \in C_{p}$$. That is, it allows the model to communicate the values of $$\frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}}$$ to the simulator. Recall that $$r^{(i,j)}$$ and $$r^{(j,i)}$$ are just two different notations for the same quantity. Thus, there are only $$\frac{\text{numberOfParticles} \cdot (\text{numberOfParticles} + 1)}{2}$$ quantities (as opposed to $$(\text{numberOfParticles})^2$$) referred to by the notation $$\frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}}$$.

These quantities can be used to compute many quantities of interest associated with the configuration. For example, it is possible to independently compute the partial virial from this information using the formula

$\mathbf{V}^{\mathcal{C}} = \sum_{i \in C_p} \sum_{j \in \mathcal{N}^{(i)}_{r_{\text{infl}}}} \;\; \sum_{k \not= j; \; k \in \bar{\mathcal{N}}^{(i)}_{r_{\text{infl}}}} \left(\frac{1}{2 r^{(j,k)}} \frac{\partial \tilde{E}_i}{\partial r^{(j,k)}} \right) \mathbf{r}^{(j,k)} \otimes \mathbf{r}^{(j,k)}.$

• ProcessD2EDr2Term is a callback function that allows for access to the second derivatives of the configuration's partial energy, $$E^{\mathcal{C}}$$, with respect to all pair-distances, $$r^{(i,j)}, i,j \in C_{p}$$. That is, it allows the model to communicate the values of $$\frac{\partial^2 E^{\mathcal{C}}}{\partial r^{(i,j)} \partial r^{(m,n)}}$$ to the simulator.

Next Section: Summary of Differences Between kim-api-v1 and kim-api-v2.