kim-api  2.0.3-git+v2.0.2-git-14-gf1578e2f.GNU
An Application Programming Interface (API) for the Knowledgebase of Interatomic Models (KIM).

Previous Section: Features of the KIM API package.

The KIM API is concerned with "simulators" and "models". Conceptually, a KIM Model is a subprogram that defines an energy-per-particle function, \(E_i\), and an "influence distance", \(r_{\text{infl}}\), that identifies the particle separation range over which \(E_i\) depends on the position of its neighboring particles. (Note, this is not necessarily equal to the neighbor list cutoff radius used by a model.) A KIM Model is defined for a specific material system (a specific set of particle species: e.g., Al, Ni, and Cu) and contains all parameter values necessary for evaluating \(E_i\) for any configuration containing particles of the supported species. A KIM Model will, typically, also have the ability to compute other quantities related to the energy-per-particle, such as the force on a particle or the particle's virial.

Conceptually, a KIM-compliant simulator is a computer program that is compatible with the KIM API and performs a numerical simulation based on the energy, forces, etc. of a set of particles. This could be a molecular dynamics simulation, a Monte Carlo simulation, or other similar simulation technique. Such a simulator treats a KIM Model as a black box. It constructs an atomistic "Configuration" of interest and passes this configuration to a KIM Model along with a list of quantities (energy, force, virial, etc.) to be computed. The model then performs the requested computation and passes the results back to the simulator. Once the simulator has received the model's results it may use these values to advance its simulation and update the atomistic configuration. Typically, this sequence of events is repeated in an iterative process until the simulator determines it has reached convergence or some other stopping condition is achieved.

The purpose of the KIM API is to coordinate the information exchange between KIM-compliant simulators and KIM Models. It does this through the definition of various concepts and quantities, and by providing a set of subroutines that facilitate the necessary communication between simulators and models. A simulator supporting the KIM API can work with all KIM Models (as long as they can agree on units and the necessary species are supported by the model) and vice versa.

Of central importance to the information exchange process is the definition of an atomistic "Configuration", \(\mathcal{C}\). Abstractly, a configuration consists of a set of particles \(C_p\) and their associated data. For each particle \(i \in C_p\), the following additional data must be defined.

  1. The particle's species (H, He, Li, etc.).
  2. The particle's position vector \(\mathbf{r}^{(i)} = r^{(i)}_j \mathbf{e}_j = r^{(i)}_1 \mathbf{e}_1 + r^{(i)}_2 \mathbf{e}_2 + r^{(i)}_3 \mathbf{e}_3,\) where \(\mathbf{e}_j, \; j=1,2,3\) are unit vectors along the global fixed Cartesian coordinate system \(x\), \(y\), and \(z\) directions, respectively.
  3. The particle's "Contributing Status", which is either "contributing" or "non-contributing". Non-contributing particles exist as part of the configuration only to provide the proper environment for the contributing particles. Thus, non-contributing particles (sometimes called "ghost" or "padding" particles) can be thought of as providing the appropriate boundary conditions for the configuration.

Before proceeding further, we introduce the notation \(\mathbf{r}^{(i,j)} \equiv \mathbf{r}^{(j)} - \mathbf{r}^{(i)}\) for the relative position vector from particle \(i\) to particle \(j\), and the notation \(r^{(i,j)}\) for the magnitude of the vector \(\mathbf{r}^{(i,j)}\). Note that \(r^{(j,i)} = r^{(i,j)}\) and these are simply two different notations for the same quantity.

Returning to the definition and description of a configuration, a configuration's set of particles may be partitioned into two disjoint sets: The set of contributing particles \(C_{cp}\), and the set of non-contributing particles \(C_{ncp}\). So that

\[ C_{p} = C_{cp} \cup C_{ncp} \quad \text{and} \quad C_{cp} \cap C_{ncp} = \emptyset. \]

For a particle \(i \in C_p\), define the particle's ("punctured") influence neighborhood, \(\mathcal{N}^{(i)}_{r_\text{infl}}\), as the subset of particles (not including the particle, itself) in the configuration that are located no more than \(r_{\text{infl}}\) away from particle \(i\). That is,

\[ \mathcal{N}^{(i)}_{r_\text{infl}} \equiv \{ j \in C_p \;|\; 0 < r^{(i,j)} \le r_{\text{infl}} \}. \]

Finally, define the closure of the particle's influence neighborhood, \(\bar{\mathcal{N}}^{(i)}_{r_{\text{infl}}}\):

\[ \bar{\mathcal{N}}^{(i)}_{r_{\text{infl}}} \equiv \mathcal{N}^{(i)}_{r_{\text{infl}}} \cup \{i\}. \]

With the above definitions, it is possible to more specifically identify the functional dependence for a KIM Model's energy-per-particle function, \(E_i\):

\[ E_i = \bar{E}_i(\mathbf{r}^{(j)} \;|\; j \in \bar{\mathcal{N}}^{(i)}_{r_{\text{infl}}}). \]

In fact, due to the principle of material frame indifference, this function can only be a function of the distances between these particles:

\[ E_i = \tilde{E}_i( r^{(j,k)} \;|\; j,k \in \bar{\mathcal{N}}^{(i)}_{r_{\text{infl}}}) . \]

It is usually most convenient to work with the function of position vectors, \(\bar{E}_i(\mathbf{r}^{(j)})\). However, in some cases it is advantageous to work with the function of distances, \(\tilde{E}_i(r^{(j,k)})\). When the distinction is unimportant the unaccented notation, \(E_i\), will be used.

Now a configuration's "Partial Energy" may be defined as the sum of its contributing particles' energies:

\[ E^\mathcal{C} = \sum_{i \in C_{cp}} E_i. \]

From this definition of the configuration's partial energy, a set of additional quantities may be derived that are often of interest in simulations.

First, define formally, the configuration's "Partial Particle Energy" for particle \(i\), \(E^{\mathcal{C}}_i\), as simply the model's energy-per-particle value for contributing particles and zero for non-contributing particles,

\[ E^{\mathcal{C}}_i \equiv \begin{cases} E_i, & i \in C_{cp},\\ 0, & i \in C_{ncp}. \end{cases} \]

Second, the configuration's "Partial Force" on particle \(j\), \(\mathbf{f}^{\mathcal{C}(j)}\), is defined as the negative of the derivative of the configuration's partial energy with respect to the particle's position vector:

\[ \mathbf{f}^{\mathcal{C}(j)} \equiv - \frac{\partial E^{\mathcal{C}}}{\partial \mathbf{r}^{(j)}}, \quad j \in C_{p}. \]

Note that, in general, every particle (both contributing and non-contributing) has a partial force.

Third, the configuration's "Partial Virial" tensor, \(\mathbf{V}^{\mathcal{C}}\), is defined in terms of the partial forces:

\[ \mathbf{V}^{\mathcal{C}} \equiv - \sum_{i \in C_{p}} \mathbf{f}^{\mathcal{C}(i)} \otimes \mathbf{r}^{(i)} = \sum_{i \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial \mathbf{r}^{(i)}} \otimes \mathbf{r}^{(i)}, \]

where \(\otimes\) is the tensor product operation.

Although the partial virial tensor is given in terms of the absolute particle positions, \(\mathbf{r}^{(i)}\), it can be shown to be independent of the coordinate origin. Indeed,

\begin{align*} \mathbf{V}^{\mathcal{C}} = \sum_{i \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial \mathbf{r}^{(i)}} \otimes \mathbf{r}^{(i)} &= \frac{1}{2} \left[ \sum_{i \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial \mathbf{r}^{(i)}} \otimes \mathbf{r}^{(i)} + \sum_{j \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial \mathbf{r}^{(j)}} \otimes \mathbf{r}^{(j)} \right] \\ &= \frac{1}{2} \left[ \sum_{i \in C_{p}} \sum_{j \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \frac{\partial r^{(i,j)}}{\partial \mathbf{r}^{(i)}} \otimes \mathbf{r}^{(i)} + \sum_{j \in C_{p}} \sum_{i \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial {r}^{(i,j)}} \frac{\partial r^{(i,j)}}{\partial \mathbf{r}^{(j)}} \otimes \mathbf{r}^{(j)} \right] \\ &= \frac{1}{2} \left[ \sum_{i \in C_{p}} \sum_{j \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \frac{\mathbf{r}^{(i,j)}}{r^{(i,j)}} \otimes \mathbf{r}^{(i)} + \sum_{j \in C_{p}} \sum_{i \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial {r}^{(i,j)}} \frac{\mathbf{r}^{(j,i)}}{r^{(i,j)}} \otimes \mathbf{r}^{(j)} \right] \\ &= \frac{1}{2} \left[ \sum_{i \in C_{p}} \sum_{j \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \frac{\mathbf{r}^{(i,j)}}{r^{(i,j)}} \otimes \mathbf{r}^{(i)} + \sum_{j \in C_{p}} \sum_{i \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial {r}^{(i,j)}} \left(-\frac{\mathbf{r}^{(i,j)}}{r^{(i,j)}}\right) \otimes \mathbf{r}^{(j)} \right] \\ &= \frac{1}{2} \left[ \sum_{i \in C_{p}} \sum_{j \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \frac{\mathbf{r}^{(i,j)}}{r^{(i,j)}} \otimes \left(\mathbf{r}^{(i)} - \mathbf{r}^{(j)}\right) \right] \\ &= \frac{1}{2} \left[ \sum_{i \in C_{p}} \sum_{j \in C_{p}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \frac{\mathbf{r}^{(i,j)}}{r^{(i,j)}} \otimes \mathbf{r}^{(i,j)} \right]. \end{align*}

So, an equivalent definition for the virial tensor is

\[ \mathbf{V}^{\mathcal{C}} \equiv \sum_{i, j \in C_{p}} \left( \frac{1}{2 r^{(i,j)}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \right) \mathbf{r}^{(i,j)} \otimes \mathbf{r}^{(i,j)}. \]

It is common to partition the partial virial into particle contributions, the "Partial Particle Virial" tensors \(\mathbf{V}^{\mathcal{C}(i)}\) such that

\[ \mathbf{V}^{\mathcal{C}} = \sum_{i \in C_{p}} \mathbf{V}^{\mathcal{C}(i)}. \]

However, this decomposition is not unique, and different definitions of the particle virial tensor are found in the literature. For example, here are two common definitions:

\begin{gather*} \mathbf{V}^{\mathcal{C}(i)} \equiv \sum_{j \in C_{p}} \left( \frac{1}{2 r^{(i,j)}} \frac{\partial E^{\mathcal{C}}}{\partial r^{(i,j)}} \right) \mathbf{r}^{(i,j)} \otimes \mathbf{r}^{(i,j)}; && \mathbf{V}^{\mathcal{C}(i)} \equiv \sum_{j, k \in C_{p}} \left( \frac{1}{2 r^{(j,k)}} \frac{\partial E^{\mathcal{C}}_i}{\partial r^{(j,k)}} \right) \mathbf{r}^{(j,k)} \otimes \mathbf{r}^{(j,k)}. \end{gather*}

Notice, in the first definition the configuration's partial energy \(E^{\mathcal{C}}\) is used, whereas in the second definition the partial particle energy \(E^{\mathcal{C}}_i\) of particle \(i\) is used. Further, it is obvious by inspection that with these definitions the sum of partial particle virial tensors equals the partial virial tensor.

Thus, the KIM API does not impose a specific definition for a model's partial particle virial tensor. It simply requires that the model's definition satisfies the summation formula \(\mathbf{V}^{\mathcal{C}} = \sum_{i \in C_{p}} \mathbf{V}^{\mathcal{C}(i)}\).

Domain Decomposition

The definitions of a configuration's partial energy, forces, and virial are designed to allow for easy (and low communication) parallel computation via domain decomposition. This section presents a simple example that illustrates how this works.

Start with a configuration of particles corresponding to a finite strip of a centered square lattice.


The total energy of the system, particle energy, the total force on each particle, the total virial tensor, and the particle virial tensors can be computed using a single configuration. In this case, the configuration is \(\mathcal{T}\), the set of particles is \(T_p\), the set of contributing particles is \(T_{cp} = T_p\), and the set of non-contributing particles is \(T_{ncp}=\emptyset\). Then, the total energy is \(E=E^\mathcal{T}\), the particle energy is \(E_i=E^{\mathcal{T}}_i\), the total force is \(\mathbf{f}^{(i)}=\mathbf{f}^{\mathcal{T}(i)}\), the total virial tensor is \(\mathbf{V} = \mathbf{V}^{\mathcal{T}}\), and the particle virial tensor \(\mathbf{V}^{(i)} = \mathbf{V}^{\mathcal{T}(i)}\). Next, it is shown how to compute \(E\), \(E_i\), \(\mathbf{f}^{(i)}\), \(\mathbf{V}\), and \(\mathbf{V}^{(i)}\) using a decomposition into two domains.

Partition \(T_p\) into two disjoint subsets, \(A_p\) and \(B_p\). That is, \(A_p \cap B_p = \emptyset\) and \(A_p \cup B_p = T_p\).


Next, define configuration \(\mathcal{C}\) to have particles \(C_p=T_p\) with \(C_{cp}=A_p\) and \(C_{ncp}=B_p\), and configuration \(\mathcal{D}\) to have particles \(D_p=T_p\) with \(D_{cp}=B_p\) and \(D_{ncp}=A_p\). (In practice, one can get away with including only those non-contributing particles that fall within the "influence distance" of at least one contributing particle.) Then, we can add up (or "assemble") the values using the contributions from each domain

\begin{align*} E &= E^\mathcal{C} + E^\mathcal{D},\\ \mathbf{f}^{(i)} &= \mathbf{f}^{\mathcal{C}(i)} + \mathbf{f}^{\mathcal{D}(i)},\\ \mathbf{V} &= \mathbf{V}^{\mathcal{C}} + \mathbf{V}^{\mathcal{D}}, \\ \mathbf{V}^{(i)} &= \mathbf{V}^{\mathcal{C}(i)} + \mathbf{V}^{\mathcal{D}(i)}. \end{align*}

Here it becomes clear why the KIM API prepends the term "Partial" to all of its standard quantity names. In general, the quantities computed by a model are only one "partial" contribution to a total. For example, here we can say that the force on particle \(i\), \(\mathbf{f}^{(i)}\), is the sum of \(\mathcal{C}\)'s partial force \(\mathbf{f}^{\mathcal{C}(i)}\) and \(\mathcal{D}\)'s partial force \(\mathbf{f}^{\mathcal{D}(i)}\).

For the particle energies, we can just take the value from the (only) domain where the particle is contributing

\[ E_i = \begin{cases} E^{\mathcal{C}}_i & \text{if $i \in C_{cp}$},\\ E^{\mathcal{D}}_i & \text{if $i \in D_{cp}$}. \end{cases} \]

Next Section: Implementation.