KIM API V2
|
Previous Section: Theory.
In code, a model (or model driver) consists of six routines which perform specific tasks. The first is the ModelCreate (or ModelDriverCreate) routine, which performs initialization tasks for the model object. The second is the ModelComputeArgumentsCreate routine, which performs initialization tasks for a compute-arguments object. The third is the ModelComputeArgumentsDestroy routine, which performs finalization tasks for a compute-arguments object. The fourth is the ModelCompute routine, which uses the configuration information stored in a compute-arguments object to perform the model's core computational tasks. The fifth is the ModelRefresh routine, which performs updates after a simulator makes changes to the model's parameters (if this is supported). The sixth is the ModelDestroy routine, which performs finalization tasks for the model object.
To interact with a model, a simulator creates a model object (which, in part, includes execution of the model's ModelCreate routine). Using this object, the simulator creates a compute-arguments object (which, in part, includes execution of the model's ModelComputeArgumentsCreate routine). Then, the simulator provides a compute-arguments object to 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.). And, 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.
The KIM API provides a list of all compute-arguments and compute-callbacks defined as part of the official API. Each such argument and callback has a "Support Status" which 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.
Next, lists of each input compute-argument, output compute-argument, and compute-callback are provided. To be explicit, below 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 |
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}}_{32}, V^{\mathcal{C}}_{13}\) | 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 |
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. 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 Hints 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 hints provided by the model a simulator may provide the model with a modified neighbor list that is more efficient. If the model sets its "paddingNeighborHint" to 1 (true), it is guaranteeing that it will not need access to the neighbors of non-contributing (padding) particles. So, the simulator does not need to generate a neighbor list for such particles. If the model sets its "halfListHint" to 1 (true), it is guaranteeing that it will only use neighbors \(j\) of particle \(i\) if \(i < j\). So, the simulator can construct a "half list" of neighbors where each pair of neighbors is listed only once in such a way that the list of neighbors for particle \(i\) contains only particles \(j\) numbered greater than \(i\). The model has no way of known if the simulator is taking advantage of its hints, so it must work correctly for all types of neighbor lists consistent with its provided hints.
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} \mathbf{V}^{\mathcal{C}(i)} = \sum_{i \in C_p} \sum_{j \in \mathcal{N}^{(i)}_{r_{\text{infl}}}} \frac{\bar{E}_i}{\partial \mathbf{r}^{(j)}} \otimes \mathbf{r}^{(j)} = \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}}}} \frac{\partial \tilde{E}_i}{\partial r^{(j,k)}} \frac{\partial r^{(j,k)}}{\partial \mathbf{r}^{(j)}} \otimes \mathbf{r}^{(j)}. \]
Next Section: Summary of Differences Between kim-api-v1 and kim-api-v2.