<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Materials on Hunter Heidenreich | Senior AI Research Scientist</title><link>https://hunterheidenreich.com/tags/materials/</link><description>Recent content in Materials on Hunter Heidenreich | Senior AI Research Scientist</description><image><title>Hunter Heidenreich | Senior AI Research Scientist</title><url>https://hunterheidenreich.com/img/avatar.webp</url><link>https://hunterheidenreich.com/img/avatar.webp</link></image><generator>Hugo -- 0.163.3</generator><language>en-US</language><copyright>2026 Hunter Heidenreich</copyright><lastBuildDate>Tue, 04 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://hunterheidenreich.com/tags/materials/index.xml" rel="self" type="application/rss+xml"/><item><title>Atom-Density Representations for Machine Learning</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/atom-density-representations-ml/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/atom-density-representations-ml/</guid><description>A unified bra-ket framework connecting SOAP, Behler-Parrinello, and other atom-density representations for ML on molecules and materials.</description><content:encoded><![CDATA[<h2 id="a-unified-theory-of-atom-density-representations">A Unified Theory of Atom-Density Representations</h2>
<p>This is a <strong>Theory</strong> paper that provides a formal, basis-independent framework for constructing structural representations of atomic systems for machine learning. Rather than proposing a new representation, Willatt, Musil, and Ceriotti show that many popular approaches (SOAP power spectra, Behler-Parrinello symmetry functions, $n$-body kernels, and tensorial SOAP) are special cases of a single abstract construction based on smoothed atom densities and <a href="https://en.wikipedia.org/wiki/Haar_measure">Haar integration</a> over symmetry groups.</p>
<h2 id="the-challenge-of-representing-atomic-structures">The Challenge of Representing Atomic Structures</h2>
<p>Machine learning models for predicting molecular and materials properties require input representations that are (1) complete enough to distinguish structurally distinct configurations and (2) invariant to physical symmetries (translations, rotations, and permutations of identical atoms). This has led to a large and growing set of competing approaches: <a href="/posts/molecular-descriptor-coulomb-matrix/">Coulomb matrices</a>, symmetry functions, <a href="https://en.wikipedia.org/wiki/Radial_distribution_function">radial distribution functions</a>, wavelets, invariant polynomials, and many more.</p>
<p>The proliferation of representations makes it difficult to compare them on equal footing or to identify which design choices are fundamental and which are incidental. Internal-coordinate approaches (e.g., Coulomb matrices) are automatically translation- and rotation-invariant but require additional symmetrization over permutations, which can introduce derivative discontinuities when done via sorting. Density-based approaches such as radial distribution functions and SOAP avoid these discontinuities by working with smooth density fields, but their theoretical connections to one another have not been made explicit.</p>
<h2 id="dirac-notation-for-atomic-environments">Dirac Notation for Atomic Environments</h2>
<p>The core innovation is to describe an atomic configuration $\mathcal{A}$ as a ket $|\mathcal{A}\rangle$ in a Hilbert space, formed by placing smooth functions $g(\mathbf{r})$ (typically Gaussians) on each atom and decorating them with orthonormal element kets $|\alpha\rangle$:</p>
<p>$$
\langle \mathbf{r} | \mathcal{A} \rangle = \sum_{i} g(\mathbf{r} - \mathbf{r}_{i}) | \alpha_{i} \rangle
$$</p>
<p>This ket is basis-independent, which is the reason for adopting the Dirac notation. The same abstract object can be projected onto position space, reciprocal space, or a basis of radial functions and spherical harmonics, yielding different concrete representations that all encode the same structural information.</p>
<h3 id="symmetrization-via-haar-integration">Symmetrization via Haar Integration</h3>
<p>To impose translational invariance, the ket is averaged over the translation group. Averaging the raw density $|\mathcal{A}\rangle$ directly (first order, $\nu = 1$) discards all geometric information and retains only atom counts per element. The solution is to first take tensor products and then average:</p>
<p>$$
\left| \mathcal{A}^{(\nu)} \right\rangle_{\hat{t}} = \int \mathrm{d}\hat{t} \underbrace{\hat{t}|\mathcal{A}\rangle \otimes \hat{t}|\mathcal{A}\rangle \cdots \hat{t}|\mathcal{A}\rangle}_{\nu}
$$</p>
<p>For $\nu = 2$, this yields a translationally-invariant ket that encodes pairwise distance information between atoms, and naturally decomposes into atom-centered contributions:</p>
<p>$$
\left| \mathcal{A}^{(2)} \right\rangle_{\hat{t}} = \sum_{j} |\alpha_{j}\rangle |\mathcal{X}_{j}\rangle
$$</p>
<p>where $|\mathcal{X}_{j}\rangle$ is the environment ket centered on atom $j$, defined with a smooth cutoff function $f_{c}(r_{ij})$ that restricts each environment to a spherical neighborhood (justified by the nearsightedness principle of electronic matter). This decomposition is what justifies the widely used additive kernel between structures (a sum of kernels between environments).</p>
<h3 id="rotational-invariance-and-body-order-correlations">Rotational Invariance and Body-Order Correlations</h3>
<p>The same Haar integration procedure over the $SO(3)$ rotation group produces rotationally invariant representations:</p>
<p>$$
\left| \mathcal{X}^{(\nu)} \right\rangle_{\hat{R}} = \int \mathrm{d}\hat{R} \prod_{\aleph}^{\nu} \otimes \hat{R}\hat{U}_{\aleph}|\mathcal{X}_{j}^{\aleph}\rangle
$$</p>
<p>The order $\nu$ of the tensor product before symmetrization determines the body-order of correlations captured: $\nu$ corresponds to $(\nu + 1)$-body correlations. The $\nu = 1$ invariant ket retains only radial (distance) information (two-body). The $\nu = 2$ ket encodes three-body correlations (two distances and an angle), and is argued to be sufficient for unique reconstruction of a configuration (up to inversion symmetry), based on extensive numerical experiments. Using nonlinear kernels (tensor products of the symmetrized ket, parameterized by $\zeta$) allows the model to incorporate higher body-order correlations beyond those explicitly in the feature vector.</p>
<h2 id="recovering-soap-symmetry-functions-and-tensorial-extensions">Recovering SOAP, Symmetry Functions, and Tensorial Extensions</h2>
<p>By projecting the abstract invariant kets onto specific basis sets, the authors recover several well-known frameworks as special cases.</p>
<h3 id="behler-parrinello-symmetry-functions">Behler-Parrinello Symmetry Functions</h3>
<p>In the $\delta$-function limit of the atomic density, the $\nu = 1$ and $\nu = 2$ invariant kets in real space directly correspond to the 2-body and 3-body correlation functions. Behler-Parrinello symmetry functions are projections of these correlation functions onto suitable test functions $G$:</p>
<p>$$
\langle \alpha \beta G_{2} | \mathcal{X}_{j} \rangle = \langle \alpha | \alpha_{j} \rangle \int \mathrm{d}r, G_{2}(r), r \left\langle \beta r | \mathcal{X}_{j}^{(1)} \right\rangle_{\hat{R},, h \to \delta}
$$</p>
<p>where the $h \to \delta$ subscript indicates the Dirac delta limit of the atomic density.</p>
<h3 id="soap-power-spectrum">SOAP Power Spectrum</h3>
<p>Expanding the environmental ket in a basis of radial functions $R_{n}(r)$ and <a href="https://en.wikipedia.org/wiki/Spherical_harmonics">spherical harmonics</a> $Y_{m}^{l}(\hat{\mathbf{r}})$, the $\nu = 2$ invariant ket is the SOAP power spectrum:</p>
<p>$$
\left\langle \alpha n \alpha&rsquo; n&rsquo; l \left| \mathcal{X}_{j}^{(2)} \right\rangle_{\hat{R}} \propto \frac{1}{\sqrt{2l+1}} \sum_{m} \langle \alpha n l m | \mathcal{X}_{j} \rangle^{\star} \langle \alpha&rsquo; n&rsquo; l m | \mathcal{X}_{j} \rangle \right.
$$</p>
<p>This identity shows that the SOAP kernel, which can be expressed as a scalar product between truncated power spectrum vectors, is a natural consequence of the inner product between invariant kets. The $\nu = 3$ case yields the <a href="https://en.wikipedia.org/wiki/Bispectrum">bispectrum</a>, used as a four-body feature vector in both SOAP and Spectral Neighbor Analysis Potentials (SNAP), where its high resolution enables accurate interatomic potentials through linear regression:</p>
<p>$$
\langle \alpha_{1} n_{1} l_{1}, \alpha_{2} n_{2} l_{2}, \alpha n l | \mathcal{X}_{j}^{(3)} \rangle_{\hat{R}} \propto \frac{1}{\sqrt{2l+1}} \sum_{m, m_{1}, m_{2}} \langle \mathcal{X}_{j} | \alpha n l m \rangle \langle \alpha_{1} n_{1} l_{1} m_{1} | \mathcal{X}_{j} \rangle \langle \alpha_{2} n_{2} l_{2} m_{2} | \mathcal{X}_{j} \rangle \langle l_{1} m_{1} l_{2} m_{2} | l m \rangle
$$</p>
<p>where $\langle l_{1} m_{1} l_{2} m_{2} | l m \rangle$ is a <a href="https://en.wikipedia.org/wiki/Clebsch%E2%80%93Gordan_coefficients">Clebsch-Gordan coefficient</a>.</p>
<h3 id="tensorial-soap-lambda-soap">Tensorial SOAP ($\lambda$-SOAP)</h3>
<p>The tensorial extension of SOAP incorporates an angular momentum ket $|\lambda \mu\rangle$ into the tensor product before symmetrization:</p>
<p>$$
\left| \mathcal{X}^{(\nu)} \lambda \mu \right\rangle_{\hat{R}} = \int \mathrm{d}\hat{R}, \hat{R}|\lambda \mu\rangle \prod_{\aleph=1}^{\nu} \otimes \hat{R}|\mathcal{X}_{j}\rangle
$$</p>
<p>This construction is rotationally invariant in the full product space but covariant in the subspace of atomic environments, enabling models for tensorial properties (e.g., polarizability tensors, chemical shielding).</p>
<h3 id="distributions-vs-sorted-vectors">Distributions vs. Sorted Vectors</h3>
<p>The paper also connects density-based and sorted-vector approaches. Given a set of structural descriptors ${a_{i}}$, the sorted vector is equivalent to the inverse cumulative distribution function of the histogram of values. The Euclidean distance between sorted vectors is the $\mathcal{L}^{2}$ norm of the difference between the inverse CDFs, and the $\mathcal{L}^{1}$ norm corresponds to the <a href="https://en.wikipedia.org/wiki/Earth_mover%27s_distance">earth mover&rsquo;s distance</a>. This highlights that different symmetrization strategies encode essentially the same structural information.</p>
<h2 id="generalized-operators-for-tuning-representations">Generalized Operators for Tuning Representations</h2>
<p>The framework becomes especially powerful through the introduction of a linear Hermitian operator $\hat{U}$ that transforms the density ket before symmetrization. This operator must commute with rotations:</p>
<p>$$
\langle \alpha n l m | \hat{U} | \alpha&rsquo; n&rsquo; l&rsquo; m&rsquo; \rangle = \delta_{ll&rsquo;} \delta_{mm&rsquo;} \langle \alpha n l | \hat{U} | \alpha&rsquo; n&rsquo; l&rsquo; \rangle
$$</p>
<p>Several practical modifications to standard representations can be understood as choices of $\hat{U}$:</p>
<h3 id="dimensionality-reduction">Dimensionality Reduction</h3>
<p>A low-rank expansion of $\hat{U}$ via PCA on the spherical-harmonic covariance matrix of environments identifies linearly independent components, enabling compression of the feature vector. For a given $l$, the covariance matrix between spherical expansion coefficients is:</p>
<p>$$
C_{\alpha n \alpha&rsquo; n&rsquo;}^{(l)} = \frac{1}{N} \sum_{j} \sum_{m} \langle \alpha n l m | \mathcal{X}_{j} \rangle^{\star} \langle \mathcal{X}_{j} | \alpha&rsquo; n&rsquo; l m \rangle = \frac{\sqrt{2l+1}}{N} \sum_{j} \left\langle \alpha n, \alpha&rsquo; n&rsquo; l \left| \mathcal{X}_{j}^{(2)} \right\rangle_{\hat{R}} \right.
$$</p>
<p>The eigenvectors of $\mathbf{C}^{(l)}$ provide the mixing coefficients for a compressed representation, retaining only components with significant eigenvalues.</p>
<h3 id="radial-scaling">Radial Scaling</h3>
<p>In systems with relatively uniform atom density, the overlap kernel is dominated by the region farthest from the center. A radial scaling operator $u(r)$ (diagonal in position space) downweights distant contributions:</p>
<p>$$
\langle \alpha \mathbf{r} | \hat{U} | \mathcal{X}_{j} \rangle = u(r), \psi_{\mathcal{X}_{j}}^{\alpha}(\mathbf{r})
$$</p>
<p>This recovers the multi-scale kernels that are known to improve predictions in practice, and connects to the two-body features of Faber et al.</p>
<h3 id="alchemical-kernels">Alchemical Kernels</h3>
<p>An operator that acts only in chemical-element space introduces correlations between different elements. The &ldquo;alchemical&rdquo; projection:</p>
<p>$$
\langle J \mathbf{r} | \mathcal{X}_{j} \rangle = \sum_{\alpha} u_{J\alpha}, \psi_{\mathcal{X}_{j}}^{\alpha}(\mathbf{r})
$$</p>
<p>reduces the dimensionality from $O(n_{\mathrm{sp}}^{2})$ to $O(d_{J}^{2})$ and has been shown to produce a low-dimensional representation of elemental space that shares similarities with periodic-table groupings.</p>
<h3 id="non-factorizable-operators">Non-Factorizable Operators</h3>
<p>For more complex modifications (e.g., distance- and angle-dependent scaling of three-body correlations), the operator must act on the full product space rather than factoring into independent components. The authors show that the three-body scaling function of Faber et al. corresponds to a diagonal non-factorizable operator in the real-space representation.</p>
<h2 id="implications-and-future-directions">Implications and Future Directions</h2>
<p>The main conclusions are:</p>
<ol>
<li>
<p><strong>Unification</strong>: SOAP, Behler-Parrinello symmetry functions, $\lambda$-SOAP, bispectrum descriptors, and sorted-vector approaches all emerge from the same abstract construction, differing only in the choice of basis set, body order $\nu$, and kernel power $\zeta$.</p>
</li>
<li>
<p><strong>Systematic improvability</strong>: The $\hat{U}$ operator framework provides a principled way to tune representations, from simple radial scaling to full alchemical and non-factorizable couplings, with clear connections to existing heuristic modifications.</p>
</li>
<li>
<p><strong>Completeness hierarchy</strong>: The body-order parameter $\nu$ and kernel power $\zeta$ together control the trade-off between completeness and computational cost. The $\nu = 2$ (three-body) representation appears to be sufficient for unique structural identification, while higher orders can be recovered through nonlinear kernels.</p>
</li>
</ol>
<p><strong>Limitations</strong>: The paper is primarily theoretical and does not include extensive numerical benchmarks comparing the different instantiations of the framework. Optimization of the $\hat{U}$ operator (especially in its general form) carries a risk of overfitting that the authors acknowledge but do not resolve. The connection to neural network-based representations (message-passing networks, equivariant architectures) is not explored.</p>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<p>This is a theoretical paper that does not introduce new benchmark results. No training or test datasets are used. The ethanol molecule in Figure 2 serves as a visualization example for three-body correlation functions.</p>
<h3 id="algorithms">Algorithms</h3>
<p>The paper defines abstract constructions (Haar integration, tensor products, operator transformations) and shows how they reduce to concrete algorithms:</p>
<ul>
<li><strong>SOAP power spectrum</strong>: Expand atom density in radial functions and spherical harmonics, compute $\nu = 2$ invariant ket (Eq. 33).</li>
<li><strong>Alchemical projection</strong>: Contract element channels via learned or PCA-derived mixing coefficients (Eq. 53-55).</li>
<li><strong>Dimensionality reduction</strong>: PCA on the covariance matrix $C_{\alpha n \alpha&rsquo; n&rsquo;}^{(l)}$ of spherical expansion coefficients (Eq. 45).</li>
</ul>
<h3 id="models">Models</h3>
<p>No trained models are presented. The framework applies to kernel ridge regression / Gaussian process regression models that use these representations as inputs.</p>
<h3 id="evaluation">Evaluation</h3>
<p>No quantitative benchmarks are reported. The contribution is the theoretical framework itself, connecting and generalizing existing representations.</p>
<h3 id="hardware">Hardware</h3>
<p>Not applicable (theoretical work).</p>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Willatt, M. J., Musil, F., &amp; Ceriotti, M. (2019). Atom-density representations for machine learning. <em>The Journal of Chemical Physics</em>, 150(15), 154110. <a href="https://doi.org/10.1063/1.5090481">https://doi.org/10.1063/1.5090481</a></p>
<p><strong>Publication</strong>: The Journal of Chemical Physics, 2019</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{willatt2019atom,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Atom-density representations for machine learning}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Willatt, Michael J. and Musil, F{\&#39;e}lix and Ceriotti, Michele}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{The Journal of Chemical Physics}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{150}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span>=<span style="color:#e6db74">{15}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{154110}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2019}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.1063/1.5090481}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">eprint</span>=<span style="color:#e6db74">{1807.00408}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">archiveprefix</span>=<span style="color:#e6db74">{arXiv}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">primaryclass</span>=<span style="color:#e6db74">{physics.chem-ph}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>Ewald Message Passing for Molecular Graphs</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/ewald-message-passing-molecular-graphs/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/ewald-message-passing-molecular-graphs/</guid><description>Ewald message passing augments GNNs with Fourier-space long-range interactions, improving energy predictions by 10-16% on OC20 and OE62 benchmarks.</description><content:encoded><![CDATA[<h2 id="a-fourier-space-long-range-correction-for-molecular-gnns">A Fourier-Space Long-Range Correction for Molecular GNNs</h2>
<p>This is a <strong>Method</strong> paper that introduces Ewald message passing (Ewald MP), a general framework for incorporating long-range interactions into message passing neural networks (MPNNs) for molecular <a href="/notes/chemistry/molecular-simulation/ml-potentials/learning-smooth-interatomic-potentials/">potential energy surface</a> prediction. The key contribution is a nonlocal Fourier-space message passing scheme, grounded in the classical <a href="https://en.wikipedia.org/wiki/Ewald_summation">Ewald summation</a> technique from computational physics, that complements the short-range message passing of existing GNN architectures.</p>
<h2 id="the-long-range-interaction-problem-in-molecular-gnns">The Long-Range Interaction Problem in Molecular GNNs</h2>
<p>Standard MPNNs for molecular property prediction rely on a spatial distance cutoff to define atomic neighborhoods. While this locality assumption enables favorable scaling with system size and provides a useful inductive bias, it fundamentally limits the model&rsquo;s ability to capture long-range interactions such as electrostatic forces and van der Waals (<a href="https://en.wikipedia.org/wiki/London_dispersion_force">London dispersion</a>) interactions. These interactions decay slowly with distance (e.g., electrostatic energy follows a $1/r$ power law), and truncating them with a distance cutoff can introduce severe artifacts in thermochemical predictions.</p>
<p>This problem is well-known in molecular dynamics, where empirical force fields explicitly separate bonded (short-range) and non-bonded (long-range) energy terms. The Ewald summation technique addresses this by decomposing interactions into a short-range part that converges quickly with a distance cutoff and a long-range part whose Fourier transform converges quickly with a frequency cutoff. The authors propose bringing this same strategy into the GNN paradigm.</p>
<h2 id="from-ewald-summation-to-learnable-fourier-space-messages">From Ewald Summation to Learnable Fourier-Space Messages</h2>
<p>The core insight is a formal analogy between the continuous-filter convolution used in MPNNs and the electrostatic potential computation in Ewald summation. In a standard continuous-filter convolution, the message sum for atom $i$ is:</p>
<p>$$
M_i^{(l+1)} = \sum_{j \in \mathcal{N}(i)} h_j^{(l)} \cdot \Phi^{(l)}(| \mathbf{x}_i - \mathbf{x}_j |)
$$</p>
<p>where $h_j^{(l)}$ are atom embeddings and $\Phi^{(l)}$ is a learned radial filter. Comparing this to the electrostatic potential $V_i^{\text{es}}(\mathbf{x}_i) = \sum_{j \neq i} q_j \cdot \Phi^{\text{es}}(| \mathbf{x}_i - \mathbf{x}_j |)$ reveals a direct correspondence: atom embeddings play the role of partial charges, and learned filters replace the $1/r$ kernel.</p>
<p>Ewald MP decomposes the learned filter into short-range and long-range components. The short-range part is handled by any existing GNN architecture with a distance cutoff. The long-range part is computed as a sum over Fourier frequencies:</p>
<p>$$
M^{\text{lr}}(\mathbf{x}_i) = \sum_{\mathbf{k}} \exp(i \mathbf{k}^T \mathbf{x}_i) \cdot s_{\mathbf{k}} \cdot \hat{\Phi}^{\text{lr}}(| \mathbf{k} |)
$$</p>
<p>where $s_{\mathbf{k}}$ are <strong><a href="https://en.wikipedia.org/wiki/Structure_factor">structure factor</a> embeddings</strong>, computed as:</p>
<p>$$
s_{\mathbf{k}} = \sum_{j \in \mathcal{S}} h_j \exp(-i \mathbf{k}^T \mathbf{x}_j)
$$</p>
<p>These structure factor embeddings are a Fourier-space representation of the atom embedding distribution, and truncating to low frequencies effectively coarse-grains the hidden model state while preserving long-range information. The frequency filters $\hat{\Phi}^{\text{lr}}$ are learned, making the entire scheme data-driven rather than tied to a fixed physical functional form.</p>
<p>The method handles both <strong>periodic</strong> systems (where the <a href="https://en.wikipedia.org/wiki/Reciprocal_lattice">reciprocal lattice</a> provides a natural frequency discretization) and <strong>aperiodic</strong> systems (where the Fourier domain is discretized using a cubic voxel grid with SVD-based rotation alignment to preserve rotation invariance). The combined embedding update becomes:</p>
<p>$$
h_i^{(l+1)} = \frac{1}{\sqrt{3}} \left[ h_i^{(l)} + f_{\text{upd}}^{\text{sr}}(M_i^{\text{sr}}) + f_{\text{upd}}^{\text{lr}}(M_i^{\text{lr}}) \right]
$$</p>
<p>The computational complexity is $\mathcal{O}(N_{\text{at}} N_{\text{k}})$, and by fixing the number of frequency vectors $N_{\text{k}}$, linear scaling $\mathcal{O}(N_{\text{at}})$ is achievable.</p>
<h2 id="experiments-across-four-gnn-architectures-and-two-datasets">Experiments Across Four GNN Architectures and Two Datasets</h2>
<p>The authors test Ewald MP as an augmentation on four baseline architectures: <a href="/notes/chemistry/datasets/marcel/">SchNet, PaiNN, DimeNet++, and GemNet-T</a>. Two datasets are used:</p>
<ul>
<li><strong>OC20</strong> (Chanussot et al., 2021): ~265M periodic structures of adsorbate-catalyst systems with DFT-computed energies and forces. The OC20-2M subsplit is used for training.</li>
<li><strong>OE62</strong> (Stuke et al., 2020): ~62,000 large aperiodic organic molecules with DFT-computed energies that include a DFT-D3 dispersion correction for London dispersion interactions.</li>
</ul>
<p>All baselines use a 6 Å distance cutoff and 50 maximum neighbors. The Ewald modification is minimal: the long-range message sum is added as an additional skip connection term in each interaction block. Comparison studies include: (1) increasing the distance cutoff to match the computational cost of Ewald MP, (2) replacing the Ewald block with a SchNet interaction block at increased cutoff, and (3) increasing atom embedding dimensions to match Ewald MP&rsquo;s parameter count.</p>
<h3 id="key-energy-mae-results-on-oe62">Key Energy MAE Results on OE62</h3>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Baseline (meV)</th>
					<th>Ewald MP (meV)</th>
					<th>Improvement</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>SchNet</td>
					<td>133.5</td>
					<td>79.2</td>
					<td>40.7%</td>
			</tr>
			<tr>
					<td>PaiNN</td>
					<td>61.4</td>
					<td>57.9</td>
					<td>5.7%</td>
			</tr>
			<tr>
					<td>DimeNet++</td>
					<td>51.2</td>
					<td>46.5</td>
					<td>9.2%</td>
			</tr>
			<tr>
					<td>GemNet-T</td>
					<td>51.5</td>
					<td>47.4</td>
					<td>8.0%</td>
			</tr>
	</tbody>
</table>
<h3 id="key-energy-mae-results-on-oc20-averaged-across-test-splits">Key Energy MAE Results on OC20 (Averaged Across Test Splits)</h3>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Baseline (meV)</th>
					<th>Ewald MP (meV)</th>
					<th>Improvement</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>SchNet</td>
					<td>895</td>
					<td>830</td>
					<td>7.3%</td>
			</tr>
			<tr>
					<td>PaiNN</td>
					<td>448</td>
					<td>393</td>
					<td>12.3%</td>
			</tr>
			<tr>
					<td>DimeNet++</td>
					<td>496</td>
					<td>445</td>
					<td>10.4%</td>
			</tr>
			<tr>
					<td>GemNet-T</td>
					<td>346</td>
					<td>307</td>
					<td>11.3%</td>
			</tr>
	</tbody>
</table>
<h2 id="robust-long-range-improvements-and-dispersion-recovery">Robust Long-Range Improvements and Dispersion Recovery</h2>
<p>Ewald MP achieves consistent improvements across all models and both datasets, averaging 16.1% on OE62 and 10.3% on OC20. Several findings stand out:</p>
<ol>
<li>
<p><strong>Robustness</strong>: Unlike the increased-cutoff and SchNet-LR alternatives, Ewald MP never produces detrimental effects in any tested configuration. The increased cutoff setting hurts SchNet and PaiNN on OE62, and the SchNet-LR block fails to improve DimeNet++ and GemNet-T.</p>
</li>
<li>
<p><strong>Long-range specificity</strong>: A binning analysis on OE62 groups molecules by the magnitude of their DFT-D3 dispersion correction. Ewald MP shows an outsize improvement for structures with large long-range energy contributions. It recovers or surpasses a &ldquo;cheating&rdquo; baseline that receives the exact DFT-D3 ground truth as an additional input.</p>
</li>
<li>
<p><strong>Efficiency on periodic systems</strong>: Ewald MP achieves similar relative improvements on OC20 at roughly half the relative computational cost compared to OE62, suggesting periodic structures as a particularly attractive application domain.</p>
</li>
<li>
<p><strong>Force predictions</strong>: Improvements in <a href="/notes/chemistry/molecular-simulation/ml-potentials/dark-side-of-forces/">force MAEs</a> are consistent but small, which is expected since the frequency truncation removes high-frequency contributions to the potential energy surface.</p>
</li>
<li>
<p><strong>Ablation studies</strong>: Results are robust across different frequency cutoffs, voxel resolutions, and filtering strategies, with the non-radial periodic filtering scheme outperforming radial alternatives on out-of-distribution generalization.</p>
</li>
</ol>
<p>Limitations include the current focus on scalar (invariant) embeddings only (PaiNN&rsquo;s equivariant vector embeddings are not augmented), and the potential for a &ldquo;gap&rdquo; of medium-range interactions when $N_{\text{k}}$ is fixed for linear scaling. The authors suggest adapting more efficient Ewald summation variants (e.g., particle mesh Ewald with $\mathcal{O}(N \log N)$ scaling) as future work.</p>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<table>
	<thead>
			<tr>
					<th>Purpose</th>
					<th>Dataset</th>
					<th>Size</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Training (periodic)</td>
					<td>OC20-2M</td>
					<td>~2M structures</td>
					<td>Subsplit of OC20; PBC; DFT energies and forces</td>
			</tr>
			<tr>
					<td>Training (aperiodic)</td>
					<td>OE62</td>
					<td>~62,000 molecules</td>
					<td>Large organic molecules; DFT energies with D3 correction</td>
			</tr>
			<tr>
					<td>Evaluation</td>
					<td>OC20-test (4 splits: ID, OOD-ads, OOD-cat, OOD-both)</td>
					<td>Varies</td>
					<td>Evaluated via submission to OC20 evaluation server</td>
			</tr>
			<tr>
					<td>Evaluation</td>
					<td>OE62-val, OE62-test</td>
					<td>~6,000 each</td>
					<td>Direct evaluation</td>
			</tr>
	</tbody>
</table>
<h3 id="algorithms">Algorithms</h3>
<ul>
<li>Ewald message passing is integrated as an additional skip connection term in each interaction block</li>
<li>For periodic systems: non-radial filtering with fixed reciprocal lattice positions ($N_x, N_y, N_z$ hyperparameters)</li>
<li>For aperiodic systems: radial Gaussian basis function filtering with frequency cutoff $c_k$ and voxel resolution $\Delta = 0.2$ Å$^{-1}$</li>
<li>SVD-based coordinate alignment for rotation invariance in the aperiodic case</li>
<li>Bottleneck dimension $N_\downarrow = 16$ (GemNet-T) or $N_\downarrow = 8$ (others)</li>
<li>Update function: dense layer + $N_{\text{hidden}}$ residual layers ($N_{\text{hidden}} = 3$, except PaiNN with $N_{\text{hidden}} = 0$)</li>
</ul>
<h3 id="models">Models</h3>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Embedding Size (OE62)</th>
					<th>Interaction Blocks</th>
					<th>Ewald Params (OE62)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>SchNet</td>
					<td>512</td>
					<td>4</td>
					<td>12.2M total</td>
			</tr>
			<tr>
					<td>PaiNN</td>
					<td>512</td>
					<td>4</td>
					<td>15.7M total</td>
			</tr>
			<tr>
					<td>DimeNet++</td>
					<td>256</td>
					<td>3</td>
					<td>4.8M total</td>
			</tr>
			<tr>
					<td>GemNet-T</td>
					<td>256</td>
					<td>3</td>
					<td>16.1M total</td>
			</tr>
	</tbody>
</table>
<h3 id="evaluation">Evaluation</h3>
<ul>
<li>Primary metric: Energy mean absolute error (EMAE) in meV</li>
<li>Secondary metric: Force MAE in meV/Å (OC20 only)</li>
<li>Loss: Linear combination of energy and force MAEs (Eq. 15) with model-specific force multipliers</li>
<li>Optimizer: Adam with weight decay ($\lambda = 0.01$)</li>
</ul>
<h3 id="hardware">Hardware</h3>
<ul>
<li>All runtime measurements on NVIDIA A100 GPUs</li>
<li>Runtimes measured after 50 warmup batches, averaged over 500 batches, minimum of 3 repetitions</li>
<li>Code: <a href="https://github.com/arthurkosmala/EwaldMP">EwaldMP</a> (Hippocratic License 3.0)</li>
</ul>
<h3 id="artifacts">Artifacts</h3>
<table>
	<thead>
			<tr>
					<th>Artifact</th>
					<th>Type</th>
					<th>License</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><a href="https://github.com/arthurkosmala/EwaldMP">EwaldMP</a></td>
					<td>Code</td>
					<td>Hippocratic License 3.0 (new files) / MIT (OC20 base)</td>
					<td>Official implementation built on the Open Catalyst Project codebase</td>
			</tr>
			<tr>
					<td><a href="https://github.com/facebookresearch/fairchem/blob/main/docs/catalysts/datasets/oc20.md">OC20</a></td>
					<td>Dataset</td>
					<td>CC-BY-4.0</td>
					<td>~265M periodic adsorbate-catalyst structures with DFT energies and forces</td>
			</tr>
			<tr>
					<td><a href="https://doi.org/10.1038/s41597-020-0385-y">OE62</a></td>
					<td>Dataset</td>
					<td>CC-BY-4.0</td>
					<td>~62,000 large organic molecules with DFT energies including D3 correction</td>
			</tr>
	</tbody>
</table>
<p><strong>Reproducibility status</strong>: Highly Reproducible. Source code, both datasets, and detailed hyperparameters (including per-model learning rates, batch sizes, and Ewald-specific settings) are all publicly available. Pre-trained model weights are not provided.</p>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Kosmala, A., Gasteiger, J., Gao, N., &amp; Günnemann, S. (2023). Ewald-based Long-Range Message Passing for Molecular Graphs. In <em>Proceedings of the 40th International Conference on Machine Learning (ICML 2023)</em>.</p>
<p><strong>Publication</strong>: ICML 2023</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@inproceedings</span>{kosmala2023ewald,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Ewald-based Long-Range Message Passing for Molecular Graphs}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Kosmala, Arthur and Gasteiger, Johannes and Gao, Nicholas and G{\&#34;u}nnemann, Stephan}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">booktitle</span>=<span style="color:#e6db74">{Proceedings of the 40th International Conference on Machine Learning}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2023}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">series</span>=<span style="color:#e6db74">{PMLR}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{202}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>Materials Representations for ML Review</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-representations/notations/materials-representations-ml-review/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-representations/notations/materials-representations-ml-review/</guid><description>Review of representation strategies for encoding solid-state materials as ML inputs, covering structural descriptors, crystal graphs, and generative models.</description><content:encoded><![CDATA[<h2 id="a-systematization-of-material-representations">A Systematization of Material Representations</h2>
<p>This paper is a <strong>Systematization</strong> that organizes and categorizes the strategies researchers use to convert solid-state materials into numerical representations suitable for machine learning models. Rather than proposing a new method, the review provides a structured taxonomy of existing approaches, connecting each to the practical constraints of data availability, computational cost, and prediction targets. It covers structural descriptors, graph-based learned representations, compositional features, transfer learning, and generative models for inverse design.</p>
<h2 id="why-material-representations-matter">Why Material Representations Matter</h2>
<p>Machine learning has enabled rapid property prediction for materials, but every ML pipeline depends on how the material is encoded as a numerical input. The authors identify three guiding principles for effective representations:</p>
<ol>
<li><strong>Similarity preservation</strong>: Similar materials should have similar representations, and dissimilar materials should diverge in representation space.</li>
<li><strong>Domain coverage</strong>: The representation should be constructable for every material in the target domain.</li>
<li><strong>Cost efficiency</strong>: Computing the representation should be cheaper than computing the target property directly (e.g., via <a href="https://en.wikipedia.org/wiki/Density_functional_theory">DFT</a>).</li>
</ol>
<p>In practice, materials scientists face several barriers. Atomistic structures span diverse space groups, supercell sizes, and disorder parameters. Real material performance depends on defects, microstructure, and interfaces. Structural information often requires expensive experimental or computational effort to obtain. Datasets in materials science tend to be small, sparse, and biased toward well-studied systems.</p>
<h2 id="structural-descriptors-local-global-and-topological">Structural Descriptors: Local, Global, and Topological</h2>
<p>The review covers three families of hand-crafted structural descriptors that encode atomic positions and types.</p>
<h3 id="local-descriptors">Local Descriptors</h3>
<p>Local descriptors characterize the environment around each atom. Atom-centered symmetry functions (ACSF), introduced by Behler and Parrinello, define radial and angular functions:</p>
<p>$$
G_{i}^{1} = \sum_{j \neq i}^{\text{neighbors}} e^{-\eta(R_{ij} - R_{s})^{2}} f_{c}(R_{ij})
$$</p>
<p>$$
G_{i}^{2} = 2^{1-\zeta} \sum_{j,k \neq i}^{\text{neighbors}} (1 + \lambda \cos \theta_{ijk})^{\zeta} e^{-\eta(R_{ij}^{2} + R_{ik}^{2} + R_{jk}^{2})} f_{c}(R_{ij}) f_{c}(R_{ik}) f_{c}(R_{jk})
$$</p>
<p>The Smooth Overlap of Atomic Positions (SOAP), proposed by Bartók et al., defines atomic neighborhood density as a sum of Gaussians and computes a rotationally invariant kernel through expansion in radial functions and <a href="https://en.wikipedia.org/wiki/Spherical_harmonics">spherical harmonics</a>:</p>
<p>$$
\rho_{i}(\mathbf{r}) = \sum_{j} \exp\left(-\frac{|\mathbf{r} - \mathbf{r}_{ij}|^{2}}{2\sigma^{2}}\right) = \sum_{nlm} c_{nlm} g_{n}(\mathbf{r}) Y_{lm}(\hat{\mathbf{r}})
$$</p>
<p>The power spectrum $\mathbf{p}(\mathbf{r}) \equiv \sum_{m} c_{nlm}(c_{n&rsquo;lm})^{*}$ serves as a vector descriptor of the local environment. SOAP has seen wide adoption both as a similarity metric and as input to ML models.</p>
<p><a href="https://en.wikipedia.org/wiki/Voronoi_diagram">Voronoi tessellation</a> provides another local approach, segmenting space into cells and extracting features like effective coordination numbers, cell volumes, and neighbor properties.</p>
<h3 id="global-descriptors">Global Descriptors</h3>
<p>Global descriptors encode the full structure. The Coulomb matrix models electrostatic interactions between atoms:</p>
<p>$$
M_{i,j} = \begin{cases} Z_{i}^{2.4} &amp; \text{for } i = j \\ \frac{Z_{i}Z_{j}}{|r_{i} - r_{j}|} &amp; \text{for } i \neq j \end{cases}
$$</p>
<p>Other global methods include partial radial distribution functions (PRDF), the many-body tensor representation (MBTR), and cluster expansions. The Atomic Cluster Expansion (ACE) framework generalizes cluster expansions to continuous environments and has become a foundation for modern deep learning potentials.</p>
<h3 id="topological-descriptors">Topological Descriptors</h3>
<p><a href="https://en.wikipedia.org/wiki/Persistent_homology">Persistent homology</a> from topological data analysis (TDA) identifies geometric features at multiple length scales. Topological descriptors capture pore geometries in porous materials and have outperformed traditional structural descriptors for predicting CO$_{2}$ adsorption in metal-organic frameworks and methane storage in <a href="https://en.wikipedia.org/wiki/Zeolite">zeolites</a>. A caveat is the $O(N^{3})$ worst-case computational cost per filtration.</p>
<h2 id="crystal-graph-neural-networks">Crystal Graph Neural Networks</h2>
<p>Graph neural networks bypass manual feature engineering by learning representations directly from structural data. Materials are converted to graphs $G(V, E)$ where nodes represent atoms and edges connect neighbors within a cutoff radius, with periodic boundary conditions.</p>
<p>Key architectures discussed include:</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Key Innovation</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>CGCNN</td>
					<td>Crystal graph convolutions for broad property prediction</td>
			</tr>
			<tr>
					<td>MEGNet</td>
					<td>Materials graph networks with global state attributes</td>
			</tr>
			<tr>
					<td>ALIGNN</td>
					<td>Line graph neural networks incorporating three-body angular features</td>
			</tr>
			<tr>
					<td>Equivariant GNNs</td>
					<td>E(3)-equivariant message passing for tensorial properties</td>
			</tr>
	</tbody>
</table>
<p>The review identifies several limitations. Graph convolutions based on local neighborhoods can fail to capture long-range interactions or periodicity-dependent properties (e.g., lattice parameters, phonon spectra). Strategies to address this include concatenation with hand-tuned descriptors, plane-wave periodic basis modulation, and reciprocal-space features.</p>
<p>A major practical restriction is the requirement for relaxed atomic positions. Graphs built from unrelaxed crystal prototypes lose information about geometric distortions, degrading accuracy. Approaches to mitigate this include data augmentation with perturbed structures, Bayesian optimization of prototypes, and surrogate force-field relaxation.</p>
<p>Equivariant models that introduce higher-order tensors to node and edge features, constrained to transform correctly under E(3) operations, achieve state-of-the-art accuracy and can match structural descriptor performance even in low-data (~100 datapoints) regimes.</p>
<h2 id="compositional-descriptors-without-structure">Compositional Descriptors Without Structure</h2>
<p>When crystal structures are unavailable, representations can be built purely from stoichiometry and tabulated atomic properties (radii, electronegativity, valence electrons). Despite their simplicity, these methods have distinct advantages: zero computational overhead, accessibility to non-experts, and robustness for high-throughput screening.</p>
<p>Key methods include:</p>
<ul>
<li><strong>MagPie</strong>: 145 input features derived from elemental properties</li>
<li><strong>SISSO</strong>: Compressive sensing over algebraic combinations of atomic properties, capable of discovering interpretable descriptors (e.g., a new tolerance factor $\tau$ for perovskite stability)</li>
<li><strong>ElemNet</strong>: Deep neural network using only fractional stoichiometry as input, outperforming MagPie with &gt;3,000 training points</li>
<li><strong>ROOST</strong>: Fully-connected compositional graph with attention-based message passing, achieving strong performance with only hundreds of examples</li>
<li><strong>CrabNet</strong>: Self-attention on element embeddings with fractional encoding, handling dopant-level concentrations via log-scale inputs</li>
</ul>
<p>Compositional models cannot distinguish polymorphs and generally underperform structural approaches. They are most valuable when atomistic resolution is unavailable.</p>
<h2 id="defects-surfaces-and-grain-boundaries">Defects, Surfaces, and Grain Boundaries</h2>
<p>The review extends beyond idealized unit cells to practical materials challenges:</p>
<p><strong>Point defects</strong>: Representations of the pristine bulk can predict vacancy formation energies through linear relationships with band structure descriptors. Frey et al. proposed using relative differences between defect and parent structure properties, requiring no DFT on the defect itself.</p>
<p><strong>Surfaces and catalysis</strong>: Binding energy prediction for catalysis requires representations beyond the bulk unit cell. The d-band center for metals and oxygen 2p-band center for metal oxides serve as simple electronic descriptors, following the <a href="https://en.wikipedia.org/wiki/Sabatier_principle">Sabatier principle</a> that optimal catalytic activity requires intermediate binding strength. Graph neural networks trained on the Open Catalyst 2020 dataset (&gt;1 million DFT energies) have enabled broader screening, though errors remain high for certain adsorbates and non-metallic surfaces.</p>
<p><strong>Grain boundaries</strong>: SOAP descriptors computed for atoms near grain boundaries and clustered into local environment classes can predict grain boundary energy, mobility, and shear coupling. This approach provides interpretable structure-property relationships.</p>
<h2 id="transfer-learning-across-representations">Transfer Learning Across Representations</h2>
<p>When target datasets are small, transfer learning leverages representations learned from large, related datasets. The standard procedure involves: (1) pretraining on a large dataset (e.g., all Materials Project formation energies), (2) freezing parameters up to a chosen depth, and (3) either fine-tuning remaining layers or extracting features for a separate model.</p>
<p>Key findings from the review:</p>
<ul>
<li>Transfer learning is most effective when the source dataset is orders of magnitude larger than the target</li>
<li>Physically related tasks transfer better (e.g., Open Catalyst absorption energies transfer well to new adsorbates, less so to unrelated small molecules)</li>
<li>Earlier neural network layers learn more general representations and transfer better across properties</li>
<li>Multi-depth feature extraction, combining activations from multiple layers, can improve transfer</li>
<li>Predictions from surrogate models can serve as additional descriptors, expanding screening domains by orders of magnitude</li>
</ul>
<h2 id="generative-models-for-crystal-inverse-design">Generative Models for Crystal Inverse Design</h2>
<p>Generative models for solid-state materials face challenges beyond molecular generation: more diverse atomic species, the need to specify both positions and lattice parameters, non-unique definitions (rotations, translations, supercell scaling), and large unit cells (&gt;100 atoms for zeolites and MOFs).</p>
<p>The review traces the progression of approaches:</p>
<ol>
<li><strong>Voxel representations</strong>: Discretize unit cells into volume elements. Early work (iMatGen, Court et al.) demonstrated feasibility but was restricted to specific chemistries or cubic systems.</li>
<li><strong>Continuous coordinate models</strong>: Point cloud and invertible representations allowed broader chemical spaces but lacked symmetry invariances.</li>
<li><strong>Symmetry-aware models</strong>: Crystal Diffusion <a href="/notes/machine-learning/generative-models/autoencoding-variational-bayes/">VAE</a> (CDVAE) uses periodic graphs and SE(3)-equivariant message passing for translationally and rotationally invariant generation, establishing benchmark tasks for the field.</li>
<li><strong>Constrained models for porous materials</strong>: Approaches like SmVAE represent MOFs through their topological building blocks (RFcodes), ensuring all generated structures are physically valid.</li>
</ol>
<h2 id="open-problems-and-future-directions">Open Problems and Future Directions</h2>
<p>The review highlights four high-impact open questions:</p>
<ol>
<li><strong>Local vs. global descriptor trade-offs</strong>: Local descriptors (SOAP) excel for short-range interactions but struggle with long-range physics. Global descriptors model periodicity but lack generality across space groups. Combining local and long-range features could provide more universal models.</li>
<li><strong>Prediction from unrelaxed prototypes</strong>: ML force fields can relax structures at a fraction of DFT cost, potentially expanding screening domains. Key questions remain about required training data scale and generalizability.</li>
<li><strong>Applicability of compositional descriptors</strong>: The performance gap between compositional and structural models may be property-dependent, being smaller for properties like band gap that depend on global features rather than local site energies.</li>
<li><strong>Extensions of generative models</strong>: Diffusion-based architectures have improved on voxel approaches for small unit cells, but extending to microstructure, dimensionality, and surface generation remains open.</li>
</ol>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<p>This paper is a review and does not present new experimental results or release any novel code, data, or models. The paper is open-access (hybrid OA at Annual Reviews) and the arXiv preprint is freely available. The following artifacts table covers key publicly available resources discussed in the review.</p>
<h3 id="artifacts">Artifacts</h3>
<table>
	<thead>
			<tr>
					<th>Artifact</th>
					<th>Type</th>
					<th>License</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><a href="https://arxiv.org/abs/2301.08813">arXiv preprint (2301.08813)</a></td>
					<td>Other</td>
					<td>arXiv (open access)</td>
					<td>Free preprint version</td>
			</tr>
			<tr>
					<td><a href="https://next-gen.materialsproject.org">Materials Project</a></td>
					<td>Dataset</td>
					<td>CC-BY-4.0</td>
					<td>DFT energies, band gaps, structures for &gt;100,000 compounds</td>
			</tr>
			<tr>
					<td><a href="https://oqmd.org">OQMD</a></td>
					<td>Dataset</td>
					<td>CC-BY-4.0</td>
					<td>Open Quantum Materials Database, &gt;600,000 DFT entries</td>
			</tr>
			<tr>
					<td><a href="https://github.com/facebookresearch/fairchem">Open Catalyst 2020 (OC20)</a></td>
					<td>Dataset</td>
					<td>CC-BY-4.0</td>
					<td>&gt;1,000,000 DFT surface adsorption energies</td>
			</tr>
			<tr>
					<td><a href="https://aflowlib.org">AFLOW</a></td>
					<td>Dataset</td>
					<td>Public</td>
					<td>High-throughput ab initio library, &gt;3,000,000 entries</td>
			</tr>
			<tr>
					<td><a href="https://github.com/hackingmaterials/matminer">Matminer</a></td>
					<td>Code</td>
					<td>BSD</td>
					<td>Open-source toolkit for materials data mining and featurization</td>
			</tr>
	</tbody>
</table>
<h3 id="algorithms">Algorithms</h3>
<p>The review covers: ACSF, SOAP, Voronoi tessellation, Coulomb matrices, PRDF, MBTR, cluster expansions, ACE, persistent homology, CGCNN, MEGNet, ALIGNN, E(3)-equivariant GNNs, MagPie, SISSO, ElemNet, ROOST, CrabNet, VAE, GAN, and diffusion-based crystal generators.</p>
<h3 id="hardware">Hardware</h3>
<p>No new experiments are conducted. Hardware requirements vary by the referenced methods (DFT calculations require HPC; GNN training typically requires 1-8 GPUs).</p>
<h3 id="reproducibility-status">Reproducibility Status</h3>
<p><strong>Partially Reproducible</strong>: The review paper itself is open-access. All major datasets discussed (Materials Project, OQMD, OC20, AFLOW) are publicly available under permissive licenses. Most referenced model implementations (CGCNN, MEGNet, ALIGNN, ROOST, CDVAE) have open-source code. No novel artifacts are released by the authors.</p>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Damewood, J., Karaguesian, J., Lunger, J. R., Tan, A. R., Xie, M., Peng, J., &amp; Gómez-Bombarelli, R. (2023). Representations of Materials for Machine Learning. <em>Annual Review of Materials Research</em>, 53. <a href="https://doi.org/10.1146/annurev-matsci-080921-085947">https://doi.org/10.1146/annurev-matsci-080921-085947</a></p>
<p><strong>Publication</strong>: Annual Review of Materials Research, 2023</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{damewood2023representations,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Representations of Materials for Machine Learning}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Damewood, James and Karaguesian, Jessica and Lunger, Jaclyn R. and Tan, Aik Rui and Xie, Mingrou and Peng, Jiayu and G{\&#39;o}mez-Bombarelli, Rafael}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{Annual Review of Materials Research}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{53}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2023}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.1146/annurev-matsci-080921-085947}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>LLM-Prop: Predicting Crystal Properties from Text</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-design/property-prediction/llm-prop-crystal-property-prediction/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-design/property-prediction/llm-prop-crystal-property-prediction/</guid><description>LLM-Prop fine-tunes the T5 encoder on crystal text descriptions to predict band gap, volume, and other properties, outperforming GNN baselines.</description><content:encoded><![CDATA[<h2 id="text-based-crystal-property-prediction-with-llms">Text-Based Crystal Property Prediction with LLMs</h2>
<p>LLM-Prop is a <strong>Method</strong> paper that proposes using the encoder portion of <a href="https://en.wikipedia.org/wiki/T5_(language_model)">T5</a> (a general-purpose language model) fine-tuned on crystal text descriptions to predict physical and electronic properties of crystalline materials. The primary contribution is demonstrating that text-based representations of crystals, generated by Robocrystallographer, can serve as effective inputs for <a href="/notes/chemistry/molecular-design/property-prediction/">property prediction</a>, outperforming graph neural network (GNN) baselines on several tasks despite using a non-domain-specific pre-trained model with fewer parameters.</p>
<h2 id="why-text-instead-of-crystal-graphs">Why Text Instead of Crystal Graphs?</h2>
<p>Graph neural networks have been the dominant approach for crystal property prediction. Models like CGCNN, MEGNet, and ALIGNN represent crystals as graphs where atoms are nodes and bonds are edges. However, GNNs face several fundamental challenges for crystals:</p>
<ol>
<li><strong>Periodicity encoding</strong>: Crystals have repetitive unit cell arrangements that are distinct from standard molecular graphs, and GNNs struggle to encode this periodicity efficiently.</li>
<li><strong>Information incorporation</strong>: Critical structural information like bond angles, <a href="https://en.wikipedia.org/wiki/Space_group">space group</a> symmetry, and <a href="https://en.wikipedia.org/wiki/Wyckoff_positions">Wyckoff sites</a> is difficult to incorporate into graph representations.</li>
<li><strong>Expressiveness</strong>: Graphs may lack the expressiveness needed to convey complex crystal information relevant to property prediction.</li>
</ol>
<p>Meanwhile, textual descriptions of crystals (generated by tools like Robocrystallographer) naturally encode space group information, bond geometries, coordination environments, and symmetry details in human-readable form. Despite this richness, text-based approaches for crystal property prediction had been largely unexplored.</p>
<h2 id="core-innovation-t5-encoder-with-careful-fine-tuning">Core Innovation: T5 Encoder with Careful Fine-Tuning</h2>
<p>The key insight of LLM-Prop is to take a pre-trained encoder-decoder model (<a href="/notes/natural-language-processing/language-models/t5-text-to-text-transfer-transformer/">T5</a>-small) and discard the decoder entirely, using only the encoder with a linear prediction head. This design has several advantages:</p>
<ul>
<li>Cutting the network in half (from ~60M to ~37M parameters) allows processing of longer input sequences</li>
<li>Longer sequences mean more crystal information can be included</li>
<li>The encoder-only approach avoids T5&rsquo;s known weakness at regression in text-to-text format</li>
</ul>
<p>The framework applies several preprocessing strategies to the crystal text descriptions:</p>
<ol>
<li><strong>Stopword removal</strong>: Standard English stopwords are removed, except digits and symbols carrying chemical information</li>
<li><strong>Numerical token replacement</strong>: Bond distances are replaced with a <code>[NUM]</code> token and bond angles with <code>[ANG]</code>, reducing sequence length while preserving structural cues</li>
<li><strong>[CLS] token prepending</strong>: A classification token is added at the start, and its learned embedding is used as input to the prediction layer</li>
<li><strong>Label scaling</strong>: For regression tasks, targets are normalized using z-score, min-max, or log normalization</li>
</ol>
<p>The normalization schemes are defined as:</p>
<p>$$
\hat{Y}_{i}(\text{z-score}) = \frac{Y_{i} - \mu}{\sigma}
$$</p>
<p>$$
\hat{Y}_{i}(\text{min-max}) = \frac{Y_{i} - Y_{\min}}{Y_{\max} - Y_{\min}}
$$</p>
<p>$$
\hat{Y}_{i}(\text{log-norm}) = \log(Y_{i} + 1)
$$</p>
<p>The tokenizer is also retrained on the crystal text corpus with a vocabulary size of 32k, and the special tokens <code>[NUM]</code>, <code>[ANG]</code>, and <code>[CLS]</code> are added to the vocabulary.</p>
<h2 id="experimental-setup-and-baselines">Experimental Setup and Baselines</h2>
<h3 id="dataset-textedge">Dataset: TextEdge</h3>
<p>The authors collected data from the <a href="https://en.wikipedia.org/wiki/Materials_Project">Materials Project</a> database (as of November 2022), yielding 144,931 crystal structure-description pairs split into 125,098 training, 9,945 validation, and 9,888 test samples. Crystal text descriptions were generated using Robocrystallographer. The dataset covers six prediction tasks:</p>
<table>
	<thead>
			<tr>
					<th>Task</th>
					<th>Type</th>
					<th>Metric</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Band gap (eV)</td>
					<td>Regression</td>
					<td>MAE (lower is better)</td>
			</tr>
			<tr>
					<td>Unit cell volume (A^3/cell)</td>
					<td>Regression</td>
					<td>MAE (lower is better)</td>
			</tr>
			<tr>
					<td>Formation energy per atom (eV/atom)</td>
					<td>Regression</td>
					<td>MAE (lower is better)</td>
			</tr>
			<tr>
					<td>Energy per atom (eV/atom)</td>
					<td>Regression</td>
					<td>MAE (lower is better)</td>
			</tr>
			<tr>
					<td>Energy above hull (eV/atom)</td>
					<td>Regression</td>
					<td>MAE (lower is better)</td>
			</tr>
			<tr>
					<td>Is-gap-direct</td>
					<td>Classification</td>
					<td>AUC (higher is better)</td>
			</tr>
	</tbody>
</table>
<h3 id="baselines">Baselines</h3>
<p>Seven baselines were compared:</p>
<ul>
<li><strong>GNN-based</strong>: CGCNN, MEGNet, ALIGNN, DeeperGATGNN</li>
<li><strong>Classic ML</strong>: XGBoost, Random Forest (on Robocrystallographer features)</li>
<li><strong>Text-based</strong>: MatBERT (domain-specific pre-trained BERT, ~110M parameters)</li>
</ul>
<p>All models were trained and evaluated on the same dataset splits for fair comparison. GNN models were retrained on the new data rather than using results from older, smaller Materials Project versions.</p>
<h3 id="main-results-llm-prop-vs-gnn-baselines">Main Results: LLM-Prop vs. GNN Baselines</h3>
<p>When using crystal text descriptions as input, LLM-Prop achieved:</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Band gap (eV)</th>
					<th>Volume (A^3/cell)</th>
					<th>FEPA (eV/atom)</th>
					<th>EPA (eV/atom)</th>
					<th>Ehull (eV/atom)</th>
					<th>Is-gap-direct (AUC)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>CGCNN</td>
					<td>0.293</td>
					<td>188.834</td>
					<td>0.046</td>
					<td>0.082</td>
					<td>0.040</td>
					<td>0.830</td>
			</tr>
			<tr>
					<td>MEGNet</td>
					<td>0.304</td>
					<td>297.948</td>
					<td>0.077</td>
					<td>0.056</td>
					<td>0.051</td>
					<td>N/A</td>
			</tr>
			<tr>
					<td>ALIGNN</td>
					<td>0.250</td>
					<td>129.580</td>
					<td>0.027</td>
					<td>0.059</td>
					<td>0.028</td>
					<td>0.678</td>
			</tr>
			<tr>
					<td>DeeperGATGNN</td>
					<td>0.291</td>
					<td>111.857</td>
					<td>0.081</td>
					<td>0.116</td>
					<td>0.045</td>
					<td>N/A</td>
			</tr>
			<tr>
					<td>LLM-Prop (Descr.)</td>
					<td><strong>0.231</strong></td>
					<td><strong>39.252</strong></td>
					<td>0.056</td>
					<td>0.067</td>
					<td>0.047</td>
					<td><strong>0.857</strong></td>
			</tr>
	</tbody>
</table>
<p>LLM-Prop outperformed the best GNN baseline (ALIGNN) by approximately 8% on <a href="https://en.wikipedia.org/wiki/Band_gap">band gap</a> prediction, 65% on volume prediction, and 3% on band gap classification (Is-gap-direct). For formation energy per atom, energy per atom, and energy above hull, ALIGNN retained an advantage.</p>
<h3 id="llm-prop-vs-matbert">LLM-Prop vs. MatBERT</h3>
<p>LLM-Prop also outperformed MatBERT (a domain-specific pre-trained BERT) across all tasks despite having roughly 3x fewer parameters. The table below shows the best result for each model across the three input preprocessing strategies (w/ Numbers, w/o Numbers, w/ [NUM]&amp;[ANG]):</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Band gap (eV)</th>
					<th>Volume (A^3/cell)</th>
					<th>FEPA (eV/atom)</th>
					<th>EPA (eV/atom)</th>
					<th>Ehull (eV/atom)</th>
					<th>Is-gap-direct (AUC)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>MatBERT (best)</td>
					<td>0.258</td>
					<td>54.969</td>
					<td>0.071</td>
					<td>0.098</td>
					<td>0.050</td>
					<td>0.722</td>
			</tr>
			<tr>
					<td>LLM-Prop (best)</td>
					<td><strong>0.231</strong></td>
					<td><strong>39.138</strong></td>
					<td><strong>0.056</strong></td>
					<td><strong>0.067</strong></td>
					<td><strong>0.047</strong></td>
					<td><strong>0.857</strong></td>
			</tr>
	</tbody>
</table>
<p>Note: LLM-Prop&rsquo;s best band gap (0.231) comes from the &ldquo;w/o Numbers&rdquo; configuration, while the best volume (39.138) comes from &ldquo;w/ Numbers&rdquo;. The best Is-gap-direct AUC (0.857) uses the &ldquo;[NUM]&amp;[ANG]&rdquo; configuration.</p>
<h3 id="ablation-studies">Ablation Studies</h3>
<p>The contribution of each preprocessing strategy was evaluated:</p>
<table>
	<thead>
			<tr>
					<th>Configuration</th>
					<th>Band gap</th>
					<th>Volume</th>
					<th>Is-gap-direct (AUC)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>LLM-Prop (baseline)</td>
					<td>0.256</td>
					<td>69.352</td>
					<td>0.796</td>
			</tr>
			<tr>
					<td>+ modified tokenizer</td>
					<td>0.247</td>
					<td>78.632</td>
					<td>0.785</td>
			</tr>
			<tr>
					<td>+ label scaling</td>
					<td>0.242</td>
					<td>44.515</td>
					<td>N/A</td>
			</tr>
			<tr>
					<td>+ [CLS] token</td>
					<td>0.231</td>
					<td>39.520</td>
					<td>0.842</td>
			</tr>
			<tr>
					<td>+ [NUM] token</td>
					<td>0.251</td>
					<td>86.090</td>
					<td>0.793</td>
			</tr>
			<tr>
					<td>+ [ANG] token</td>
					<td>0.242</td>
					<td>64.965</td>
					<td>0.810</td>
			</tr>
			<tr>
					<td>- stopwords</td>
					<td>0.252</td>
					<td>56.593</td>
					<td>0.779</td>
			</tr>
			<tr>
					<td>LLM-Prop+all (no space group)</td>
					<td>0.235</td>
					<td>97.457</td>
					<td>0.705</td>
			</tr>
			<tr>
					<td>LLM-Prop+all</td>
					<td><strong>0.229</strong></td>
					<td>42.259</td>
					<td><strong>0.857</strong></td>
			</tr>
	</tbody>
</table>
<p>The [CLS] token provided the single largest improvement across all tasks. Label scaling was critical for volume prediction (reducing MAE from 69.352 to 44.515). Removing space group information from descriptions degraded volume prediction dramatically (from 42.259 to 97.457), confirming that space group symmetry is a key factor.</p>
<h3 id="data-efficiency-and-transfer-learning">Data Efficiency and Transfer Learning</h3>
<p>LLM-Prop achieved SOTA results on band gap and volume prediction with only about 90k training samples (35k fewer than baselines). For volume prediction specifically, LLM-Prop outperformed all GNN baselines with just 30k training samples.</p>
<p>Transfer learning experiments showed that LLM-Prop transferred well between band gap and volume prediction tasks:</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Volume-to-Band gap (Test)</th>
					<th>Band gap-to-Volume (Test)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>CGCNN-transfer</td>
					<td>0.295</td>
					<td>182.997</td>
			</tr>
			<tr>
					<td>ALIGNN-transfer</td>
					<td>0.322</td>
					<td>136.164</td>
			</tr>
			<tr>
					<td>MatBERT-transfer</td>
					<td>0.266</td>
					<td>54.289</td>
			</tr>
			<tr>
					<td>LLM-Prop-transfer</td>
					<td><strong>0.244</strong></td>
					<td><strong>50.753</strong></td>
			</tr>
	</tbody>
</table>
<h2 id="key-findings-limitations-and-future-directions">Key Findings, Limitations, and Future Directions</h2>
<p><strong>Key findings</strong>:</p>
<ul>
<li>Text descriptions of crystals carry rich structural information (space groups, Wyckoff sites, coordination geometries) that is difficult to encode in graphs but naturally expressed in text</li>
<li>A carefully fine-tuned general-purpose LLM encoder can outperform domain-specific pre-trained models, challenging the assumption that in-domain pre-training is always necessary</li>
<li>Removing numerical information (bond distances and angles) from descriptions often improves performance, because current LLMs treat numbers as regular tokens without understanding their quantitative meaning</li>
<li>Longer input sequences correlate with better performance, with 888 tokens as the default maximum on the hardware used</li>
</ul>
<p><strong>Limitations acknowledged by the authors</strong>:</p>
<ul>
<li>The origin of LLM-Prop&rsquo;s performance advantage over GNNs is not fully understood. It remains unclear whether the boost comes from additional structured information in text or from the different data modality itself</li>
<li>LLM-Prop cannot perform zero-shot predictions since T5 was not pre-trained on materials science data</li>
<li>The approach depends on Robocrystallographer to generate text descriptions, adding a preprocessing dependency</li>
<li>Current LLMs&rsquo; inability to reason about numerical values limits the use of quantitative information in descriptions</li>
</ul>
<p><strong>Future directions</strong> suggested by the authors include investigating techniques to use <a href="/notes/chemistry/molecular-design/generation/autoregressive/3d-chemical-language-models-xyz-cif-pdb/">CIF files</a> directly as LLM inputs, developing new GNN architectures that incorporate space group and Wyckoff site information, and further exploring which information in crystal descriptions contributes most to each property prediction task.</p>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<table>
	<thead>
			<tr>
					<th>Purpose</th>
					<th>Dataset</th>
					<th>Size</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Training/Eval</td>
					<td>TextEdge</td>
					<td>144,931 crystals</td>
					<td>From Materials Project (Nov 2022), text generated by Robocrystallographer</td>
			</tr>
			<tr>
					<td>Training split</td>
					<td>TextEdge</td>
					<td>125,098</td>
					<td>Random split</td>
			</tr>
			<tr>
					<td>Validation split</td>
					<td>TextEdge</td>
					<td>9,945</td>
					<td>Random split</td>
			</tr>
			<tr>
					<td>Test split</td>
					<td>TextEdge</td>
					<td>9,888</td>
					<td>Random split</td>
			</tr>
	</tbody>
</table>
<h3 id="algorithms">Algorithms</h3>
<ul>
<li><strong>Optimizer</strong>: Adam with one-cycle learning rate scheduler</li>
<li><strong>Learning rate</strong>: 1e-3 for LLM-Prop, 5e-5 for MatBERT</li>
<li><strong>Dropout</strong>: 0.2 for LLM-Prop, 0.5 for MatBERT</li>
<li><strong>Batch size</strong>: 64 (888 tokens) or 16 (2000 tokens) for LLM-Prop</li>
<li><strong>Epochs</strong>: 200-300 depending on task</li>
<li><strong>Loss</strong>: MAE for regression, BCE for classification</li>
<li><strong>Evaluation</strong>: MAE for regression, AUC for classification</li>
<li><strong>Each model run 5 times on test set</strong>, averaged MAE reported</li>
</ul>
<h3 id="models">Models</h3>
<ul>
<li><strong>Base model</strong>: T5-small encoder (~60M parameters total, ~37M after discarding decoder and adding prediction head)</li>
<li><strong>Vocabulary size</strong>: 32k (retrained tokenizer)</li>
<li><strong>Max input tokens</strong>: 888 (default) or 2000</li>
<li><strong>Special tokens</strong>: [CLS], [NUM], [ANG]</li>
</ul>
<h3 id="artifacts">Artifacts</h3>
<table>
	<thead>
			<tr>
					<th>Artifact</th>
					<th>Type</th>
					<th>License</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><a href="https://github.com/vertaix/LLM-Prop">LLM-Prop</a></td>
					<td>Code</td>
					<td>MIT</td>
					<td>Official implementation</td>
			</tr>
			<tr>
					<td><a href="https://drive.google.com/drive/folders/1YCDBzwjwNRIc1FRkB662G3Y5AOWaokUG">TextEdge + Checkpoints</a></td>
					<td>Dataset + Model</td>
					<td>Not specified</td>
					<td>Benchmark dataset and trained model checkpoints</td>
			</tr>
	</tbody>
</table>
<h3 id="hardware">Hardware</h3>
<ul>
<li><strong>GPUs</strong>: NVIDIA RTX A6000</li>
<li><strong>Training time</strong>: ~40 minutes per epoch for LLM-Prop</li>
<li><strong>Inference</strong>: ~1 minute for 10,000 materials on one GPU</li>
</ul>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Rubungo, A. N., Arnold, C. B., Rand, B. P., &amp; Dieng, A. B. (2025). LLM-Prop: predicting the properties of crystalline materials using large language models. <em>npj Computational Materials</em>, 11, 186. <a href="https://doi.org/10.1038/s41524-025-01536-2">https://doi.org/10.1038/s41524-025-01536-2</a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{rubungo2025llmprop,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{LLM-Prop: predicting the properties of crystalline materials using large language models}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Rubungo, Andre Niyongabo and Arnold, Craig B. and Rand, Barry P. and Dieng, Adji Bousso}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{npj Computational Materials}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{11}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span>=<span style="color:#e6db74">{1}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{186}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2025}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{Nature Publishing Group}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.1038/s41524-025-01536-2}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>MOFFlow: Flow Matching for MOF Structure Prediction</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/mofflow/</link><pubDate>Sat, 20 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/mofflow/</guid><description>A Riemannian flow matching framework for generating Metal-Organic Framework structures by treating building blocks as rigid bodies.</description><content:encoded><![CDATA[<h2 id="methodological-contribution-mofflow-architecture">Methodological Contribution: MOFFlow Architecture</h2>
<p>This is a <strong>Methodological Paper</strong> ($\Psi_{\text{Method}}$).</p>
<p>It introduces <strong>MOFFlow</strong>, a generative architecture and training framework designed specifically for the structure prediction of Metal-Organic Frameworks (MOFs). The paper focuses on the algorithmic innovation of decomposing the problem into rigid-body assembly on a Riemannian manifold, validates this through comparison against existing baselines, and performs ablation studies to justify architectural choices. While it leverages the theory of flow matching, its primary contribution is the application-specific architecture and the handling of modular constraints.</p>
<h2 id="motivation-scaling-limits-of-atom-level-generation">Motivation: Scaling Limits of Atom-Level Generation</h2>
<p>The primary motivation is to overcome the scalability and accuracy limitations of existing methods for MOF structure prediction.</p>
<ul>
<li><strong>Computational Cost of DFT:</strong> Conventional approaches rely on <em>ab initio</em> calculations (DFT) combined with random search, which are computationally prohibitive for large, complex systems like MOFs.</li>
<li><strong>Failure of General CSP:</strong> Existing deep generative models for general Crystal Structure Prediction (CSP) operate on an atom-by-atom basis. They fail to scale to MOFs, which often contain hundreds or thousands of atoms per unit cell, and do not exploit the inherent modular nature (building blocks) of MOFs.</li>
<li><strong>Tunability:</strong> MOFs have applications in carbon capture and drug delivery due to their tunable porosity, making automated design tools valuable.</li>
</ul>
<h2 id="core-innovation-rigid-body-flow-matching-on-se3">Core Innovation: Rigid-Body Flow Matching on SE(3)</h2>
<p>MOFFlow introduces a <strong>hierarchical, rigid-body flow matching framework</strong> tailored for MOFs.</p>
<ul>
<li><strong>Rigid Body Decomposition:</strong> MOFFlow treats metal nodes and organic linkers as rigid bodies, reducing the search space from $3N$ (atoms) to $6M$ (roto-translation of $M$ blocks) compared to atom-based methods.</li>
<li><strong>Riemannian Flow Matching on $SE(3)$:</strong> It is the first end-to-end model to jointly generate block-level rotations ($SO(3)$), translations ($\mathbb{R}^3$), and lattice parameters using <a href="/notes/machine-learning/generative-models/flow-matching-for-generative-modeling/">Riemannian flow matching</a>.</li>
<li><strong>MOFAttention:</strong> A custom attention module designed to encode the geometric relationships between building blocks, lattice parameters, and rotational constraints.</li>
<li><strong>Constraint Handling:</strong> It incorporates domain knowledge by operating on a mean-free system for translation invariance and using canonicalized coordinates for rotation invariance.</li>
</ul>
<h2 id="experimental-setup-and-baselines">Experimental Setup and Baselines</h2>
<p>The authors evaluated MOFFlow on structure prediction accuracy, physical property preservation, and scalability.</p>
<ul>
<li><strong>Dataset:</strong> The <strong>Boyd et al. (2019)</strong> dataset consisting of 324,426 hypothetical MOF structures, decomposed into building blocks using the <strong>MOFid</strong> algorithm. Filtered to structures with &lt;200 blocks, yielding 308,829 structures (247,066 train / 30,883 val / 30,880 test). Structures contain up to approximately 2,400 atoms per unit cell.</li>
<li><strong>Baselines:</strong>
<ul>
<li><em>Optimization-based:</em> Random Search (RS) and Evolutionary Algorithm (EA) using CrySPY and CHGNet.</li>
<li><em>Deep Learning:</em> DiffCSP (deep generative model for general crystals).</li>
<li><em>Self-Assembly:</em> A heuristic algorithm used in MOFDiff (adapted for comparison).</li>
</ul>
</li>
<li><strong>Metrics:</strong>
<ul>
<li><strong>Match Rate (MR):</strong> Percentage of generated structures matching ground truth within tolerance.</li>
<li><strong>RMSE:</strong> Root mean squared displacement normalized by average free length per atom.</li>
<li><strong>Structural Properties:</strong> Volumetric/Gravimetric Surface Area (VSA/GSA), Pore Limiting Diameter (PLD), Void Fraction, etc., calculated via Zeo++.</li>
<li><strong>Scalability:</strong> Performance vs. number of atoms and building blocks.</li>
</ul>
</li>
</ul>
<h2 id="results-and-generative-performance">Results and Generative Performance</h2>
<p>MOFFlow outperformed all baselines in accuracy and efficiency, particularly for large structures.</p>
<ul>
<li><strong>Accuracy:</strong> With a single sample, MOFFlow achieved a <strong>31.69% match rate</strong> (stol=0.5) and <strong>87.46%</strong> (stol=1.0) on the full test set (30,880 structures). With 5 samples, these rose to <strong>44.75%</strong> (stol=0.5) and <strong>100.0%</strong> (stol=1.0). RS and EA (tested on 100 and 15 samples respectively due to computational cost, generating 20 candidates each) achieved 0.00% MR at both tolerance levels. DiffCSP reached 0.09% (stol=0.5) and 23.12% (stol=1.0) with 1 sample.</li>
<li><strong>Speed:</strong> Inference took <strong>1.94 seconds</strong> per structure, compared to 5.37s for DiffCSP, 332s for RS, and 1,959s for EA.</li>
<li><strong>Scalability:</strong> MOFFlow preserved high match rates across all system sizes, while DiffCSP&rsquo;s match rate dropped sharply beyond 200 atoms.</li>
<li><strong>Property Preservation:</strong> The distributions of physical properties (e.g., surface area, void fraction) for MOFFlow-generated structures closely matched the ground truth. DiffCSP frequently reduced volumetric surface area and void fraction to zero.</li>
<li><strong>Self-Assembly Comparison:</strong> In a controlled comparison where the self-assembly (SA) algorithm received MOFFlow&rsquo;s predicted translations and lattice, MOFFlow (MR=31.69%, RMSE=0.2820) outperformed SA (MR=30.04%, RMSE=0.3084), confirming the value of the learned rotational vector fields. In an extended scalability comparison, SA scaled better for structures with many building blocks, but MOFFlow achieved higher overall match rate (31.69% vs. 27.14%).</li>
<li><strong>Batch Implementation:</strong> A refactored Batch version achieves improved results: <strong>32.73% MR</strong> (stol=0.5), RMSE of 0.2743, inference in <strong>0.19s</strong> per structure (10x faster), and training in roughly 1/3 the GPU hours.</li>
</ul>
<h3 id="limitations">Limitations</h3>
<p>The paper identifies three key limitations:</p>
<ol>
<li><strong>Hypothetical-only evaluation:</strong> All experiments use the Boyd et al. hypothetical database. Evaluation on more challenging real-world datasets remains needed.</li>
<li><strong>Rigid-body assumption:</strong> The model assumes that local building block structures are known, which may be impractical for rare building blocks whose structural information is missing from existing libraries or is inaccurate.</li>
<li><strong>Periodic invariance:</strong> The model is not invariant to periodic transformations of the input. Explicitly modeling periodic invariance could further improve performance.</li>
</ol>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<ul>
<li><strong>Source:</strong> MOF dataset by Boyd et al. (2019).</li>
<li><strong>Preprocessing:</strong> Structures were decomposed using the metal-oxo decomposition algorithm from <strong>MOFid</strong>.</li>
<li><strong>Filtering:</strong> Structures with fewer than 200 building blocks were used, yielding 308,829 structures.</li>
<li><strong>Splits:</strong> Train/Validation/Test ratio of 8:1:1 (247,066 / 30,883 / 30,880).</li>
<li><strong>Availability:</strong> Pre-processed dataset is available on <a href="https://zenodo.org/records/15187230">Zenodo</a>.</li>
<li><strong>Representations:</strong>
<ul>
<li><em>Atom-level:</em> Tuple $(X, a, l)$ (coordinates, types, lattice).</li>
<li><em>Block-level:</em> Tuple $(\mathcal{B}, q, \tau, l)$ (blocks, rotations, translations, lattice).</li>
</ul>
</li>
</ul>
<h3 id="algorithms">Algorithms</h3>
<ul>
<li><strong>Framework:</strong> Riemannian Flow Matching.</li>
<li><strong>Objective:</strong> Conditional Flow Matching (CFM) loss regressing to clean data $q_1, \tau_1, l_1$.
$$
\begin{aligned}
\mathcal{L}(\theta) = \mathbb{E}_{t, \mathcal{S}^{(1)}} \left[ \frac{1}{(1-t)^2} \left( \lambda_1 |\log_{q_t}(\hat{q}_1) - \log_{q_t}(q_1)|^2 + \dots \right) \right]
\end{aligned}
$$</li>
<li><strong>Priors:</strong>
<ul>
<li>Rotations ($q$): Uniform on $SO(3)$.</li>
<li>Translations ($\tau$): Standard normal on $\mathbb{R}^3$.</li>
<li>Lattice ($l$): Log-normal for lengths, Uniform(60, 120) for angles (Niggli reduced).</li>
</ul>
</li>
<li><strong>Inference:</strong> ODE solver with <strong>50 integration steps</strong>.</li>
<li><strong>Local Coordinates:</strong> Defined using PCA axes, corrected for symmetry to ensure consistency.</li>
</ul>
<h3 id="models">Models</h3>
<ul>
<li><strong>Architecture:</strong> Hierarchical structure with two key modules.
<ul>
<li><strong>Atom-level Update Layers:</strong> 4-layer EGNN-like structure to encode building block features $h_m$ from atomic graphs (cutoff 5Å).</li>
<li><strong>Block-level Update Layers:</strong> 6 layers that iteratively update $q, \tau, l$ using the <strong>MOFAttention</strong> module.</li>
</ul>
</li>
<li><strong>MOFAttention:</strong> Modified Invariant Point Attention (IPA) that incorporates lattice parameters as offsets to the attention matrix.</li>
<li><strong>Hyperparameters:</strong>
<ul>
<li>Node dimension: 256 (block-level), 64 (atom-level).</li>
<li>Attention heads: 24.</li>
<li>Loss coefficients: $\lambda_1=1.0$ (rot), $\lambda_2=2.0$ (trans), $\lambda_3=0.1$ (lattice).</li>
</ul>
</li>
<li><strong>Checkpoints:</strong> Pre-trained weights and models are openly provided on <a href="https://zenodo.org/records/15187230">Zenodo</a>.</li>
</ul>
<h3 id="evaluation">Evaluation</h3>
<ul>
<li><strong>Metrics:</strong>
<ul>
<li><strong>Match Rate:</strong> Using <code>StructureMatcher</code> from <code>pymatgen</code>. Tolerances: <code>stol=0.5/1.0</code>, <code>ltol=0.3</code>, <code>angle_tol=10.0</code>.</li>
<li><strong>RMSE:</strong> Normalized by average free length per atom.</li>
</ul>
</li>
<li><strong>Tools:</strong> <strong>Zeo++</strong> for structural property calculations (Surface Area, Pore Diameter, etc.).</li>
</ul>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Metric</th>
					<th style="text-align: left">MOFFlow</th>
					<th style="text-align: left">DiffCSP</th>
					<th style="text-align: left">RS (20 cands)</th>
					<th style="text-align: left">EA (20 cands)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">MR (stol=0.5, k=1)</td>
					<td style="text-align: left"><strong>31.69%</strong></td>
					<td style="text-align: left">0.09%</td>
					<td style="text-align: left">0.00%</td>
					<td style="text-align: left">0.00%</td>
			</tr>
			<tr>
					<td style="text-align: left">MR (stol=1.0, k=1)</td>
					<td style="text-align: left"><strong>87.46%</strong></td>
					<td style="text-align: left">23.12%</td>
					<td style="text-align: left">0.00%</td>
					<td style="text-align: left">0.00%</td>
			</tr>
			<tr>
					<td style="text-align: left">MR (stol=0.5, k=5)</td>
					<td style="text-align: left"><strong>44.75%</strong></td>
					<td style="text-align: left">0.34%</td>
					<td style="text-align: left">-</td>
					<td style="text-align: left">-</td>
			</tr>
			<tr>
					<td style="text-align: left">MR (stol=1.0, k=5)</td>
					<td style="text-align: left"><strong>100.0%</strong></td>
					<td style="text-align: left">38.94%</td>
					<td style="text-align: left">-</td>
					<td style="text-align: left">-</td>
			</tr>
			<tr>
					<td style="text-align: left">RMSE (stol=0.5, k=1)</td>
					<td style="text-align: left"><strong>0.2820</strong></td>
					<td style="text-align: left">0.3961</td>
					<td style="text-align: left">-</td>
					<td style="text-align: left">-</td>
			</tr>
			<tr>
					<td style="text-align: left">Avg. time per structure</td>
					<td style="text-align: left"><strong>1.94s</strong></td>
					<td style="text-align: left">5.37s</td>
					<td style="text-align: left">332s</td>
					<td style="text-align: left">1,959s</td>
			</tr>
	</tbody>
</table>
<h3 id="hardware">Hardware</h3>
<ul>
<li><strong>Training Hardware:</strong> 8 $\times$ NVIDIA RTX 3090 (24GB VRAM).</li>
<li><strong>Training Time:</strong>
<ul>
<li><em>TimestepBatch version (main paper):</em> ~5 days 15 hours.</li>
<li><em>Batch version:</em> ~1 day 17 hours (332.74 GPU hours). The authors also release this refactored implementation, which achieves comparable performance with faster convergence.</li>
</ul>
</li>
<li><strong>Batch Size:</strong> 160 (capped by $N^2$ where $N$ is the number of atoms, for memory management).</li>
</ul>
<h3 id="artifacts">Artifacts</h3>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Artifact</th>
					<th style="text-align: left">Type</th>
					<th style="text-align: left">License</th>
					<th style="text-align: left">Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><a href="https://github.com/nayoung10/MOFFlow">MOFFlow (GitHub)</a></td>
					<td style="text-align: left">Code</td>
					<td style="text-align: left">MIT</td>
					<td style="text-align: left">Official implementation built on DiffDock, EGNN, MOFDiff, and protein-frame-flow</td>
			</tr>
			<tr>
					<td style="text-align: left"><a href="https://zenodo.org/records/15187230">Pre-processed dataset and checkpoints (Zenodo)</a></td>
					<td style="text-align: left">Dataset / Model</td>
					<td style="text-align: left">Unknown</td>
					<td style="text-align: left">Includes pre-processed MOF structures and trained model weights</td>
			</tr>
	</tbody>
</table>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Kim, N., Kim, S., Kim, M., Park, J., &amp; Ahn, S. (2025). MOFFlow: Flow Matching for Structure Prediction of Metal-Organic Frameworks. <em>International Conference on Learning Representations (ICLR)</em>.</p>
<p><strong>Publication</strong>: ICLR 2025</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@inproceedings</span>{kimMOFFlowFlowMatching2025,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{MOFFlow: Flow Matching for Structure Prediction of Metal-Organic Frameworks}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Kim, Nayoung and Kim, Seongsu and Kim, Minsu and Park, Jinkyoo and Ahn, Sungsoo}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">booktitle</span>=<span style="color:#e6db74">{The Thirteenth International Conference on Learning Representations}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2025}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">url</span>=<span style="color:#e6db74">{https://openreview.net/forum?id=dNT3abOsLo}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Additional Resources</strong>:</p>
<ul>
<li><a href="https://openreview.net/forum?id=dNT3abOsLo">OpenReview Discussion</a></li>
<li><a href="https://github.com/nayoung10/MOFFlow">Official Code Repository</a></li>
</ul>
]]></content:encoded></item><item><title>Stillinger-Weber Potential for Silicon Simulation</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/stillinger-weber-1985/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/stillinger-weber-1985/</guid><description>The 1985 paper introducing the Stillinger-Weber potential, a 3-body interaction model for molecular dynamics of tetrahedral semiconductors.</description><content:encoded><![CDATA[<h2 id="core-methodological-contribution">Core Methodological Contribution</h2>
<p>This is a <strong>Method</strong> paper.</p>
<p>Its primary contribution is the formulation of the <strong>Stillinger-Weber potential</strong>, a non-additive potential energy function designed to model tetrahedral semiconductors. The paper also uses molecular dynamics simulation to explore physical properties of silicon in both crystalline and liquid phases, but the methodological contribution (the potential architecture) is what enabled subsequent research on covalent materials.</p>
<h2 id="the-failure-of-pair-potentials-in-silicon">The Failure of Pair Potentials in Silicon</h2>
<p>The authors aimed to simulate the melting and liquid properties of tetrahedral semiconductors (Silicon and Germanium).</p>
<ul>
<li><strong>The Problem:</strong> Standard pair potentials (like Lennard-Jones) favor close-packed structures (12 nearest neighbors) and cannot stabilize the open diamond structure (4 nearest neighbors) of Silicon.</li>
<li><strong>The Gap:</strong> Earlier classical potentials lacked the flexibility to describe the profound structural change where Silicon shrinks upon melting (coordination number increases from 4 to &gt;6) while remaining conductive.</li>
<li><strong>The Goal:</strong> To construct a potential that spans the entire configuration space, describing both the rigid crystal and the diffusive liquid, without requiring quantum mechanical calculations.</li>
</ul>
<h2 id="the-three-body-interaction-novelty">The Three-Body Interaction Novelty</h2>
<p>The core novelty is the introduction of a stabilizing <strong>three-body interaction term</strong> ($v_3$) to the potential energy function.</p>
<ul>
<li><strong>3-Body Term:</strong> Explicitly penalizes deviations from the ideal tetrahedral angle ($\cos \theta_t = -1/3$).</li>
<li><strong>Unified Model:</strong> This potential handles bond breaking and reforming, allowing for the simulation of melting and liquid diffusion. Previous &ldquo;Keating&rdquo; potentials model only small elastic deformations.</li>
<li><strong>Mapping Technique:</strong> The application of &ldquo;steepest-descent mapping&rdquo; to quench dynamical configurations into their underlying &ldquo;inherent structures&rdquo; (local minima), revealing the fundamental topology of the liquid energy landscape.</li>
</ul>
<h2 id="molecular-dynamics-validation">Molecular Dynamics Validation</h2>
<p>The authors performed Molecular Dynamics (MD) simulations using the proposed potential.</p>
<ul>
<li><strong>System:</strong> 216 Silicon atoms in a cubic cell with periodic boundary conditions.</li>
<li><strong>State Points:</strong> Fixed density $\rho = 2.53 \text{ g/cm}^3$ (matching experimental liquid density at melting).</li>
<li><strong>Process:</strong>
<ol>
<li>Start with diamond crystal at low temperature.</li>
<li>Systematically heat to induce spontaneous nucleation and melting.</li>
<li>Equilibrate the liquid.</li>
<li>Periodically map configurations to potential minima (inherent structures) using steepest descent.</li>
</ol>
</li>
</ul>
<h2 id="phase-topology-and-inverse-lindemann-criterion">Phase Topology and Inverse Lindemann Criterion</h2>
<ul>
<li><strong>Validation:</strong> The potential successfully stabilizes the diamond structure as the global minimum at zero pressure.</li>
<li><strong>Liquid Structure:</strong> The simulated liquid pair-correlation function $g(r)$ and structure factor $S(k)$ qualitatively match experimental diffraction data, including the characteristic shoulder on the structure factor peak.</li>
<li><strong>Inherent Structure:</strong> The liquid possesses a temperature-independent inherent structure (amorphous network) hidden beneath thermal vibrations.</li>
<li><strong>Melting/Freezing Criteria:</strong> The study proposes an &ldquo;Inverse Lindemann Criterion&rdquo;: while crystals melt when vibration amplitude exceeds ~0.19 lattice spacings, liquids freeze when atom displacements from their inherent minima drop below ~0.30 neighbor spacings.</li>
</ul>
<h2 id="limitations-and-energy-scale-problem">Limitations and Energy Scale Problem</h2>
<p>The authors acknowledge a quantitative energy scale discrepancy. To match the observed melting temperature of Si ($1410°$C), $\epsilon$ would need to be approximately 42 kcal/mol, considerably less than the 50 kcal/mol required to reproduce the correct cohesive energy of the crystal. The authors suggest this could be resolved either by further optimization of $v_2$ and $v_3$, or by adding position-independent single-particle terms $v_1 \approx -16$ kcal/mol arising from the electronic structure. Adding $v_1$ terms only affects the temperature scale and has no influence on local structure at a given reduced temperature.</p>
<p>The simulated liquid coordination number (8.07) is also higher than the experimentally reported value of approximately 6.4, though the authors note that the experimental definition of &ldquo;nearest neighbors&rdquo; was not precisely stated.</p>
<h2 id="bonding-statistics-in-inherent-structures">Bonding Statistics in Inherent Structures</h2>
<p>Analysis of potential-energy minima (inherent structures) using a bond cutoff of $r/\sigma = 1.40$ reveals the coordination distribution in the liquid:</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Coordination Number</th>
					<th style="text-align: left">Fraction of Atoms</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">4</td>
					<td style="text-align: left">0.201</td>
			</tr>
			<tr>
					<td style="text-align: left">5</td>
					<td style="text-align: left">0.568</td>
			</tr>
			<tr>
					<td style="text-align: left">6</td>
					<td style="text-align: left">0.205</td>
			</tr>
			<tr>
					<td style="text-align: left">7</td>
					<td style="text-align: left">0.024</td>
			</tr>
	</tbody>
</table>
<p>Five-coordinate atoms dominate the liquid&rsquo;s inherent structure, with four- and six-coordinate atoms each accounting for about 20% of the population. The three-body interactions prevent any occurrence of coordination numbers near 12 that would indicate local close packing.</p>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="algorithms">Algorithms</h3>
<ul>
<li><strong>Integration:</strong> Equations of motion integrated using a <strong>fifth-order Gear algorithm</strong>.</li>
<li><strong>Time Step:</strong> $\Delta t = 5 \times 10^{-3} \tau$ (approx $3.83 \times 10^{-16}$ s), where $\tau = \sigma(m/\epsilon)^{1/2} = 7.6634 \times 10^{-14}$ s.</li>
<li><strong>Minimization:</strong> Steepest-descent mapping utilized <strong>Newton&rsquo;s method</strong> to find limiting solutions ($\nabla \Phi = 0$).</li>
</ul>
<h3 id="models">Models</h3>
<p>To reproduce this work, one must implement the potential $\Phi = \sum v_2 + \sum v_3$ with the exact functional forms and parameters provided.</p>















<figure class="post-figure center ">
    <img src="/img/notes/chemistry/stillinger-weber-potential.webp"
         alt="Stillinger-Weber potential visualization"
         title="Stillinger-Weber potential visualization"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Left: Two-body radial potential $v_2(r)$ showing the characteristic well at $r_{min} \approx 1.12\sigma$. Right: Three-body angular penalty $h(r_{min}, r_{min}, \theta)$ demonstrating the minimum at the tetrahedral angle (109.5°), which enforces the diamond crystal structure.</figcaption>
    
</figure>

<h4 id="reduced-units">Reduced Units</h4>
<ul>
<li>$\sigma = 0.20951 \text{ nm}$</li>
<li>$\epsilon = 50 \text{ kcal/mol} = 3.4723 \times 10^{-12} \text{ erg}$</li>
</ul>
<h4 id="two-body-term-v_2">Two-Body Term ($v_2$)</h4>
<p>$$
v_2(r_{ij}) = \epsilon A (B r_{ij}^{-p} - r_{ij}^{-q}) \exp[(r_{ij} - a)^{-1}] \quad \text{for } r_{ij} &lt; a
$$</p>
<p><em>(Vanishes for $r \geq a$)</em></p>
<h4 id="three-body-term-v_3">Three-Body Term ($v_3$)</h4>
<p>$$
v_3(r_i, r_j, r_k) = \epsilon [h(r_{ij}, r_{ik}, \theta_{jik}) + h(r_{ji}, r_{jk}, \theta_{ijk}) + h(r_{ki}, r_{kj}, \theta_{ikj})]
$$</p>
<p>where:</p>
<p>$$
h(r_{ij}, r_{ik}, \theta_{jik}) = \lambda \exp[\gamma(r_{ij}-a)^{-1} + \gamma(r_{ik}-a)^{-1}] (\cos\theta_{jik} + \frac{1}{3})^2
$$</p>
<p><em>(Vanishes if distances $\geq a$)</em></p>
<h4 id="parameters">Parameters</h4>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Parameter</th>
					<th style="text-align: left">Value</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left">$A$</td>
					<td style="text-align: left">$7.049556277$</td>
			</tr>
			<tr>
					<td style="text-align: left">$B$</td>
					<td style="text-align: left">$0.6022245584$</td>
			</tr>
			<tr>
					<td style="text-align: left">$p$</td>
					<td style="text-align: left">$4$</td>
			</tr>
			<tr>
					<td style="text-align: left">$q$</td>
					<td style="text-align: left">$0$</td>
			</tr>
			<tr>
					<td style="text-align: left">$a$</td>
					<td style="text-align: left">$1.80$</td>
			</tr>
			<tr>
					<td style="text-align: left">$\lambda$</td>
					<td style="text-align: left">$21.0$</td>
			</tr>
			<tr>
					<td style="text-align: left">$\gamma$</td>
					<td style="text-align: left">$1.20$</td>
			</tr>
	</tbody>
</table>
<h3 id="evaluation">Evaluation</h3>
<p>The paper evaluates the model against experimental diffraction data.</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Metric</th>
					<th style="text-align: left">Simulated Value</th>
					<th style="text-align: left">Experimental Value</th>
					<th style="text-align: left">Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><strong>Melting Point ($T_m^*$)</strong></td>
					<td style="text-align: left">$\approx 0.080$</td>
					<td style="text-align: left">N/A</td>
					<td style="text-align: left">Reduced units. Requires $\epsilon \approx 42$ kcal/mol to match real $T_m = 1410°$C, vs 50 kcal/mol for correct cohesive energy.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Coordination (Liquid)</strong></td>
					<td style="text-align: left">$8.07$</td>
					<td style="text-align: left">$\approx 6.4$</td>
					<td style="text-align: left">Evaluated at first $g(r)$ minimum ($r/\sigma = 1.625$). Simulated value is higher than experiment.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>$S(k)$ First Peak</strong></td>
					<td style="text-align: left">$2.53$ $\AA^{-1}$</td>
					<td style="text-align: left">$2.80$ $\AA^{-1}$</td>
					<td style="text-align: left">From Table I.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>$S(k)$ Shoulder</strong></td>
					<td style="text-align: left">$3.25$ $\AA^{-1}$</td>
					<td style="text-align: left">$3.25$ $\AA^{-1}$</td>
					<td style="text-align: left">From Table I. Exact match with experiment.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>$S(k)$ Second Peak</strong></td>
					<td style="text-align: left">$5.35$ $\AA^{-1}$</td>
					<td style="text-align: left">$5.75$ $\AA^{-1}$</td>
					<td style="text-align: left">From Table I.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>$S(k)$ Third Peak</strong></td>
					<td style="text-align: left">$8.16$ $\AA^{-1}$</td>
					<td style="text-align: left">$8.50$ $\AA^{-1}$</td>
					<td style="text-align: left">From Table I.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>$S(k)$ Fourth Peak</strong></td>
					<td style="text-align: left">$10.60$ $\AA^{-1}$</td>
					<td style="text-align: left">$11.20$ $\AA^{-1}$</td>
					<td style="text-align: left">From Table I.</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Entropy of Melting ($\Delta S / N k_B$)</strong></td>
					<td style="text-align: left">$\approx 3.7$</td>
					<td style="text-align: left">$3.25$</td>
					<td style="text-align: left">Simulated at constant volume; experimental at constant pressure (1 atm).</td>
			</tr>
	</tbody>
</table>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Stillinger, F. H., &amp; Weber, T. A. (1985). Computer simulation of local order in condensed phases of silicon. <em>Physical Review B</em>, 31(8), 5262-5271. <a href="https://doi.org/10.1103/PhysRevB.31.5262">https://doi.org/10.1103/PhysRevB.31.5262</a></p>
<p><strong>Publication</strong>: Physical Review B, 1985</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{stillingerComputerSimulationLocal1985,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span> = <span style="color:#e6db74">{Computer Simulation of Local Order in Condensed Phases of Silicon}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span> = <span style="color:#e6db74">{Stillinger, Frank H. and Weber, Thomas A.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span> = <span style="color:#ae81ff">1985</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">month</span> = apr,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span> = <span style="color:#e6db74">{Physical Review B}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span> = <span style="color:#e6db74">{31}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span> = <span style="color:#e6db74">{8}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span> = <span style="color:#e6db74">{5262--5271}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span> = <span style="color:#e6db74">{American Physical Society}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span> = <span style="color:#e6db74">{10.1103/PhysRevB.31.5262}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>MD Simulation of Self-Diffusion on Metal Surfaces (1994)</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/surface-science/self-diffusion-metal-surfaces-1994/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/surface-science/self-diffusion-metal-surfaces-1994/</guid><description>Molecular dynamics simulation of Iridium surface diffusion confirming atomic exchange mechanisms using EAM and many-body potentials.</description><content:encoded><![CDATA[<h2 id="scientific-typology-computational-discovery">Scientific Typology: Computational Discovery</h2>
<p>This is primarily a <strong>Discovery</strong> ($\Psi_{\text{Discovery}}$) paper, with strong supporting contributions as a <strong>Method</strong> ($\Psi_{\text{Method}}$) evaluation. The primary contribution is the validation and mechanistic visualization of the &ldquo;exchange mechanism&rdquo; for surface diffusion using computational methods (Molecular Dynamics with many-body potentials). This physical phenomenon was previously observed in Field Ion Microscope (FIM) experiments but difficult to characterize dynamically. The paper focuses on determining <em>how</em> atoms move, specifically distinguishing between hopping and exchange mechanisms.</p>
<h2 id="the-field-ion-microscope-fim-observation-gap">The Field Ion Microscope (FIM) Observation Gap</h2>
<p>Surface diffusion is critical for understanding phenomena like crystal growth, epitaxy, and catalysis. Experimental evidence from FIM on fcc(001) surfaces (specifically Pt and Ir) suggested an &ldquo;exchange mechanism&rdquo; where an adatom replaces a substrate atom, challenging the conventional wisdom that adatoms migrate by hopping over potential barriers (bridge sites) between binding sites. The authors sought to:</p>
<ol>
<li>Investigate whether this exchange mechanism could be reproduced dynamically in simulation.</li>
<li>Determine which interatomic potentials (EAM, Sutton-Chen, R-G-L) accurately describe these surface behaviors compared to bulk properties.</li>
</ol>
<h2 id="dynamic-visualization-of-atomic-exchange">Dynamic Visualization of Atomic Exchange</h2>
<p>The study provides a direct dynamic visualization of the &ldquo;concerted motion&rdquo; involved in exchange diffusion events, which happens on timescales too fast for experimental imaging. By comparing three different many-body potentials, the authors demonstrate that the choice of potential is critical for capturing surface phenomena; specifically, identifying that &ldquo;bulk&rdquo; derived potentials (like Sutton-Chen) may fail to capture specific surface exchange events that EAM and R-G-L potentials successfully model.</p>
<h2 id="simulation-protocol--evaluated-potentials">Simulation Protocol &amp; Evaluated Potentials</h2>
<p>The authors performed Molecular Dynamics (MD) simulations on Iridium (Ir) surfaces:</p>
<ul>
<li><strong>Surfaces</strong>: Channeled (110), densely packed (111), and loosely packed (001).</li>
<li><strong>Potentials</strong>: Three many-body models were tested: Embedded Atom Method (EAM), Sutton-Chen (S-C), and Rosato-Guillope-Legrand (R-G-L).</li>
<li><strong>Conditions</strong>: Simulations were primarily run at $T=800$ K to ensure sufficient sampling of diffusion events.</li>
<li><strong>Cross-Validation</strong>: The study extended the analysis to Cu, Rh, and Pt systems to verify the universality of the exchange mechanism against experimental data.</li>
</ul>
<h2 id="confirmation-of-concerted-motion-mechanisms">Confirmation of Concerted Motion Mechanisms</h2>
<ul>
<li><strong>Mechanism Confirmation</strong>: The study confirmed that diffusion on Ir(001) proceeds via an atomic exchange mechanism (concerted motion). The activation energy for exchange ($0.77$ eV) was found to be significantly lower than for hopping over bridge sites ($1.57$ eV).</li>
<li><strong>Surface Structure Dependence</strong>:
<ul>
<li><strong>Ir(111)</strong>: Diffusion is rapid (activation energy $V_a = 0.17$ eV from R-G-L Arrhenius plot) and occurs exclusively via hopping; no exchange events were observed due to the close-packed nature of the surface.</li>
<li><strong>Ir(110)</strong>: Diffusion is anisotropic; atoms hop <em>along</em> channels but use the exchange mechanism to move <em>across</em> channels.</li>
</ul>
</li>
<li><strong>Potential Validity</strong>: The R-G-L and EAM potentials successfully reproduced experimental exchange behaviors, whereas the Sutton-Chen potential failed to predict exchange on Ir(001). The authors attribute the S-C failure primarily to the use of &ldquo;bulk&rdquo; potential parameters to describe interactions at the surface.</li>
<li><strong>Cross-System Comparison</strong>: The study extended the analysis to Cu, Rh, and Pt systems. Both S-C and R-G-L potentials correctly predicted the absence of exchange on all three Rh surfaces and on (111) surfaces of Cu and Pt. Exchange events were correctly predicted on Cu(001), Cu(110), Pt(001), and Pt(110) by both potentials. The sole discrepancy was S-C failing to predict exchange on Ir(001), where R-G-L and EAM succeeded in agreement with experiment.</li>
</ul>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="algorithms">Algorithms</h3>
<ul>
<li><strong>Integration</strong>: &ldquo;Velocity&rdquo; form of the Verlet algorithm.</li>
<li><strong>Time Step</strong>: $\Delta t = 0.01$ ps ($10^{-14}$ s).</li>
<li><strong>Simulation Protocol</strong>:
<ol>
<li><strong>Quenching</strong>: System relaxed to 0 K by zeroing velocities when $v \cdot F &lt; 0$.</li>
<li><strong>Equilibration</strong>: 5 ps constant-temperature run (renormalizing velocities every step).</li>
<li><strong>Production</strong>: 15 ps constant-energy (microcanonical) run where trajectories are collected.</li>
</ol>
</li>
</ul>
<h3 id="models">Models</h3>
<p>The study relies on three specific many-body potential formulations:</p>
<ol>
<li><strong>Embedded Atom Method (EAM)</strong>:
<ul>
<li>Total energy:
$$U_{tot} = \sum_i F_i(\rho_i) + \frac{1}{2} \sum_{j \neq i} \phi_{ij}(r_{ij})$$</li>
</ul>
</li>
<li><strong>Sutton-Chen (S-C)</strong>:
<ul>
<li>Uses a square root density dependence and power-law pair repulsion $(a/r)^{n}$:
$$F(\rho) \propto \rho^{1/2}$$</li>
</ul>
</li>
<li><strong>Rosato-Guillope-Legrand (R-G-L)</strong>:
<ul>
<li>Born-Mayer type repulsion:
$$\phi_{ij}(r) = A \exp[-p(r/r_0 - 1)]$$</li>
<li>Attractive band energy:
$$F_i(\rho) = -\left(\sum \xi^2 \exp[-2q(r/r_0 - 1)]\right)^{1/2}$$</li>
</ul>
</li>
</ol>
<h3 id="data">Data</h3>
<ul>
<li><strong>System Size</strong>: 648 classical atoms.</li>
<li><strong>Geometry</strong>:
<ul>
<li>Cubic box with fixed volume.</li>
<li>Periodic boundary conditions in $x$ and $y$ (parallel to surface), free motion in $z$.</li>
<li>Substrate depth: 8, 12, or 9 atomic layers depending on orientation [(001), (110), (111)].</li>
</ul>
</li>
<li><strong>Cutoff Radius</strong>: 14 bohr ($\sim 7.4$ Å).</li>
<li><strong>Initial Conditions</strong>: Velocities initialized from a Maxwellian distribution.</li>
</ul>
<h3 id="evaluation">Evaluation</h3>
<ul>
<li><strong>Diffusion Constant ($D$)</strong>: Calculated using the Einstein relation via Mean Square Displacement (MSD):
$$D = \lim_{t \to \infty} \frac{\langle \Delta r^2(t) \rangle}{2td}$$
where $d=2$ for surface diffusion.</li>
<li><strong>Activation Energy ($V_a$)</strong>: Extracted from the slope of Arrhenius plots ($\ln D$ vs $1/T$).</li>
<li><strong>Attempt Frequency ($\nu$)</strong>: Estimated via harmonic approximation: $\nu = \frac{1}{2\pi}\sqrt{c/M}$.</li>
</ul>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Shiang, K.-D., Wei, C. M., &amp; Tsong, T. T. (1994). A molecular dynamics study of self-diffusion on metal surfaces. <em>Surface Science</em>, 301(1-3), 136-150. <a href="https://doi.org/10.1016/0039-6028(94)91295-5">https://doi.org/10.1016/0039-6028(94)91295-5</a></p>
<p><strong>Publication</strong>: Surface Science 1994</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{shiang1994molecular,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{A molecular dynamics study of self-diffusion on metal surfaces}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Shiang, Keh-Dong and Wei, C.M. and Tsong, Tien T.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{Surface Science}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{301}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span>=<span style="color:#e6db74">{1-3}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{136--150}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{1994}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{Elsevier}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.1016/0039-6028(94)91295-5}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>In Situ XRD of Oxidation-Reduction Oscillations on Pt/SiO2</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/surface-science/oxidation-reduction-oscillations-pt-sio2-1994/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/surface-science/oxidation-reduction-oscillations-pt-sio2-1994/</guid><description>In situ XRD validation of the oxide model driving kinetic rate oscillations in high-pressure CO oxidation on supported platinum.</description><content:encoded><![CDATA[<h2 id="experimental-validation-of-the-oxide-model">Experimental Validation of the Oxide Model</h2>
<p>This is a <strong>Discovery (Translational/Application)</strong> paper.</p>
<p>It is classified as such because the primary contribution is the experimental resolution of a long-standing scientific debate regarding the physical driving force of kinetic oscillations. The authors use established techniques (in situ X-ray diffraction and Debye Function Analysis) to falsify existing hypotheses (reconstruction model, carbon model) and validate a specific physical mechanism (the oxide model).</p>
<h2 id="the-missing-driving-force-in-high-pressure-co-oxidation">The Missing Driving Force in High-Pressure CO Oxidation</h2>
<p>The study addresses the debate surrounding the driving force of kinetic oscillations in CO oxidation on platinum catalysts at high pressures ($p &gt; 10^{-3}$ mbar). While low-pressure oscillations on single crystals were known to be caused by surface reconstruction, the mechanism for high-pressure oscillations on supported catalysts was unresolved. Three main models existed:</p>
<ul>
<li><strong>Reconstruction model</strong>: Structural changes of the substrate</li>
<li><strong>Carbon model</strong>: Periodic deactivation by carbon</li>
<li><strong>Oxide model</strong>: Periodic formation and reduction of surface oxides</li>
</ul>
<p>Prior to this work, there was no conclusive experimental proof demonstrating the periodic oxidation and reduction required by the oxide model.</p>
<h2 id="direct-in-situ-xrd-proof">Direct In Situ XRD Proof</h2>
<p>The core novelty is the <strong>first direct experimental evidence</strong> connecting periodic structural changes in the catalyst to rate oscillations. Using in situ X-ray diffraction (XRD), the authors demonstrated that the intensity of the Pt(111) Bragg peak oscillates in sync with the reaction rate.</p>
<p>By applying Debye Function Analysis (DFA) to the diffraction profiles, they quantitatively showed that the catalyst transitions between a metallic Pt state and a partially oxidized state (containing $\text{PtO}$ and $\text{Pt}_3\text{O}_4$). This definitively ruled out the reconstruction model (which would produce much smaller intensity variations) and confirmed the oxide model.</p>
<h2 id="in-situ-x-ray-diffraction-and-activity-monitoring">In Situ X-ray Diffraction and Activity Monitoring</h2>
<p>The authors performed <strong>in situ X-ray diffraction</strong> experiments on a supported Pt catalyst (EuroPt-1) during the CO oxidation reaction.</p>
<ul>
<li><strong>Reaction Monitoring</strong>: They cycled the temperature and gas flow rates (CO, $\text{O}_2$, He) to induce ignition, extinction, and oscillations.</li>
<li><strong>Activity Metrics</strong>: Catalytic activity was tracked via sample temperature (using thermocouples) and $\text{CO}_2$ production (using a quadrupole mass spectrometer).</li>
<li><strong>Structural Monitoring</strong>: They recorded the intensity of the Pt(111) Bragg peak continuously.</li>
<li><strong>Cluster Analysis</strong>: Detailed angular scans of diffracted intensity were taken at stationary points (active vs. inactive states) and analyzed using Debye functions to determine cluster size and composition.</li>
</ul>
<h2 id="periodic-oxidation-mechanism-and-reversibility">Periodic Oxidation Mechanism and Reversibility</h2>
<p><strong>Key Findings</strong>:</p>
<ul>
<li><strong>Oscillation Mechanism</strong>: Rate oscillations are accompanied by the periodic oxidation and reduction of the Pt catalyst.</li>
<li><strong>Phase Relationship</strong>: The X-ray intensity (oxide amount) oscillates approximately 120° ahead of the temperature (reaction rate), consistent with the oxide model: oxidation deactivates the surface → rate drops → CO reduces the surface → rate rises.</li>
<li><strong>Oxide Composition</strong>: The oxidized state consists of a mixture of metallic clusters, $\text{PtO}$, and $\text{Pt}_3\text{O}_4$. $\text{PtO}_2$ was not found.</li>
<li><strong>Extent of Oxidation</strong>: Approximately 20-30% of the metal atoms are oxidized, corresponding effectively to a shell of oxide on the surface of the nanoclusters.</li>
<li><strong>Reversibility</strong>: The transition between metallic and oxidized states is fully reversible with no sintering observed under the experimental conditions.</li>
<li><strong>Scope Limitation</strong>: The authors note that whether the oxide model also applies to kinetic oscillations on Pt foils or Pt wires remains to be verified, since small Pt clusters likely have a much higher tendency to form oxides than massive Pt metal.</li>
</ul>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<p>The study used the <strong>EuroPt-1</strong> standard catalyst.</p>
<table>
	<thead>
			<tr>
					<th>Type</th>
					<th>Material</th>
					<th>Details</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Catalyst</strong></td>
					<td>EuroPt-1 ($\text{Pt/SiO}_2$)</td>
					<td>6.3% Pt loading on silica support</td>
			</tr>
			<tr>
					<td><strong>Particle Size</strong></td>
					<td>Pt Clusters</td>
					<td>Mean diameter ~15.5 Å; dispersion $65 \pm 5\%$</td>
			</tr>
			<tr>
					<td><strong>Sample Prep</strong></td>
					<td>Pellets</td>
					<td>40 mg of catalyst pressed into $15 \times 12 \times 0.3 \text{ mm}^3$ self-supporting pellets</td>
			</tr>
	</tbody>
</table>
<h3 id="algorithms">Algorithms</h3>
<p><strong>Debye Function Analysis (DFA)</strong></p>
<p>The study used DFA to fit theoretical scattering curves to experimental intensity profiles. This method is suitable for randomly oriented clusters where standard crystallographic methods might fail due to finite size effects.</p>
<p>$$I_{N}(b)=\sum_{m,n=1}^{N}f_{m}f_{n}\frac{\sin(2\pi br_{mn})}{2\pi br_{mn}}$$</p>
<p>Where:</p>
<ul>
<li><strong>$b$</strong>: Scattering vector magnitude, $b=2 \sin \vartheta/\lambda$</li>
<li><strong>$f_m, f_n$</strong>: Atomic scattering amplitudes</li>
<li><strong>$r_{mn}$</strong>: Distance between atom pairs</li>
<li><strong>Shape Assumption</strong>: Cuboctahedral clusters (nearly spherical)</li>
</ul>
<h3 id="models">Models</h3>
<p><strong>1. The Oxide Model (Physical Mechanism)</strong></p>
<p>Proposed by Sales, Turner, and Maple, validated here:</p>
<ol>
<li><strong>Oxidation</strong>: As oxygen coverage increases, the surface forms a catalytically inactive oxide layer ($\text{PtO}_x$).</li>
<li><strong>Deactivation</strong>: The reaction rate drops as the surface deactivates.</li>
<li><strong>Reduction</strong>: CO adsorption leads to the reduction of the oxide layer, restoring the metallic surface.</li>
<li><strong>Reactivation</strong>: The metallic surface is active for CO oxidation, increasing the rate until oxygen coverage builds up again.</li>
</ol>
<p><strong>2. Shell Model (Structural)</strong></p>
<p>The diffraction data was fit using a &ldquo;Shell Model&rdquo; where a metallic Pt core is surrounded by an oxide shell.</p>
<h3 id="evaluation">Evaluation</h3>
<p><strong>Key Experimental Signatures for Replication</strong>:</p>
<ul>
<li><strong>Ignition Point</strong>: A sharp increase in sample temperature accompanied by a steep 18% decrease in Bragg intensity. After the He flow was switched off, the intensity dropped further to a total decrease of 31.5%.</li>
<li><strong>Oscillation Regime</strong>: Observed at flow rates $\sim 100 \text{ ml/min}$ after cooling the sample to $\sim 375 \text{ K}$. Below $50 \text{ ml/min}$, only bistability is observed. Temperature oscillations had $\sim 50 \text{ K}$ peak-to-peak amplitude.</li>
<li><strong>Magnitude</strong>: Bragg intensity oscillations of ~11% amplitude.</li>
</ul>
<h3 id="hardware">Hardware</h3>
<p><strong>Experimental Setup</strong>:</p>
<ul>
<li><strong>Diffractometer</strong>: Commercial Guinier diffractometer (HUBER) with monochromatized Cu $K_{\alpha1}$ radiation (45° transmission geometry).</li>
<li><strong>Reactor Cell</strong>: Custom 115 $\text{cm}^3$ cell, evacuatable to $10^{-7}$ mbar, equipped with Kapton windows and a Be-cover.</li>
<li><strong>Gases</strong>: CO (4.7 purity), $\text{O}_2$ (4.5 purity), He (4.6 purity) regulated by flow controllers.</li>
<li><strong>Sensors</strong>: Two K-type thermocouples (surface and gas phase) and a differentially pumped Quadrupole Mass Spectrometer (QMS).</li>
</ul>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Hartmann, N., Imbihl, R., &amp; Vogel, W. (1994). Experimental evidence for an oxidation/reduction mechanism in rate oscillations of catalytic CO oxidation on Pt/SiO2. <em>Catalysis Letters</em>, 28(2-4), 373-381. <a href="https://doi.org/10.1007/BF00806068">https://doi.org/10.1007/BF00806068</a></p>
<p><strong>Publication</strong>: Catalysis Letters 1994</p>
<p><strong>Related Work</strong>: This work complements <a href="/notes/chemistry/molecular-simulation/surface-science/oscillatory-co-oxidation-pt110-1992/">Oscillatory CO Oxidation on Pt(110)</a>, which modeled oscillations via surface reconstruction. Here, the driving force is oxidation/reduction.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{hartmannExperimentalEvidenceOxidation1994,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span> = <span style="color:#e6db74">{Experimental Evidence for an Oxidation/Reduction Mechanism in Rate Oscillations of Catalytic {{CO}} Oxidation on {{Pt}}/{{SiO2}}}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span> = <span style="color:#e6db74">{Hartmann, N. and Imbihl, R. and Vogel, W.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span> = <span style="color:#ae81ff">1994</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span> = <span style="color:#e6db74">{Catalysis Letters}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span> = <span style="color:#e6db74">{28}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span> = <span style="color:#e6db74">{2-4}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span> = <span style="color:#e6db74">{373--381}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">issn</span> = <span style="color:#e6db74">{1011-372X, 1572-879X}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span> = <span style="color:#e6db74">{10.1007/BF00806068}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>Evans 1986: Thermal Conductivity of Lennard-Jones Fluid</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/evans-thermal-conductivity-1986/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/evans-thermal-conductivity-1986/</guid><description>A 1986 validation of the Evans NEMD method for simulating heat flow, identifying long-time tail anomalies near the critical point.</description><content:encoded><![CDATA[<h2 id="methodological-validation-and-physical-discovery">Methodological Validation and Physical Discovery</h2>
<p>This is primarily a <strong>Methodological Paper ($\Psi_{\text{Method}}$)</strong>, with a significant secondary component of <strong>Discovery ($\Psi_{\text{Discovery}}$)</strong>.</p>
<p>It focuses on validating a specific algorithm (the &ldquo;Evans method&rdquo;) for Non-Equilibrium Molecular Dynamics (NEMD) by comparing its results against experimental benchmarks. However, it also uncovers physical anomalies, specifically &ldquo;long-time tails&rdquo; in the heat flux autocorrelation function that deviate significantly from theoretical predictions, marking a discovery about the physics of the Lennard-Jones fluid itself.</p>
<h2 id="flow-gradients-and-boundary-limitations">Flow Gradients and Boundary Limitations</h2>
<p>The primary motivation is to overcome the limitations of simulating heat flow using physical boundaries (e.g., walls at different temperatures), which causes severe interpretive difficulties due to density and temperature gradients.</p>
<p>The &ldquo;Evans method&rdquo; uses a fictitious external field to induce heat flow in a periodic, homogeneous system. This paper serves to:</p>
<ol>
<li>Validate this method across a wide range of state points (temperatures and densities) beyond the triple point.</li>
<li>Investigate the system&rsquo;s behavior near the critical point, where transport properties are known to be anomalous.</li>
</ol>
<h2 id="core-innovations-of-the-evans-algorithm">Core Innovations of the Evans Algorithm</h2>
<p>The core contribution is the rigorous stress-testing of the <strong>homogeneous heat flow algorithm</strong> (Evans method) combined with a <strong>Gaussian thermostat</strong>.</p>
<p>Specific novel insights include:</p>
<ul>
<li><strong>Linearity Validation</strong>: Establishing that, away from phase boundaries, the effective thermal conductivity is a monotonic, virtually linear function of the external field, justifying the extrapolation to zero field.</li>
<li><strong>Critical Anomaly Detection</strong>: Finding that near the critical point, conductivity becomes a non-monotonic function of the field, challenging standard simulation approaches in this regime.</li>
<li><strong>Tail Amplitude Discovery</strong>: Demonstrating that the &ldquo;long-time tails&rdquo; of the heat flux autocorrelation function have amplitudes roughly 6 times larger than those predicted by mode-coupling theory.</li>
</ul>
<h2 id="nemd-simulation-setup">NEMD Simulation Setup</h2>
<p>The author performed <strong>Non-Equilibrium Molecular Dynamics (NEMD)</strong> simulations using the Lennard-Jones potential.</p>
<ul>
<li><strong>System</strong>: Mostly $N=108$ particles, with some checks using $N=256$ to test size dependence.</li>
<li><strong>Thermostat</strong>: A Gaussian thermostat was used to keep the kinetic energy (temperature) constant.</li>
<li><strong>State Points</strong>:
<ul>
<li><strong>Critical Isotherm</strong>: $T=1.35$, varying density.</li>
<li><strong>Supercritical Isotherm</strong>: $T=2.0$.</li>
<li><strong>Freezing Line</strong>: Two points ($T=2.74, \rho=1.113$ and $T=2.0, \rho=1.04$).</li>
</ul>
</li>
<li><strong>Validation</strong>: Results were compared against <strong>experimental data for Argon</strong> (using standard LJ parameters).</li>
<li><strong>Ablation</strong>:
<ul>
<li><strong>Field Strength ($F$)</strong>: Varied to check for linearity/non-linearity.</li>
<li><strong>System Size ($N$)</strong>: Comparison between 108 and 256 particles to rule out finite-size artifacts.</li>
</ul>
</li>
</ul>
<h2 id="linearity-regimes-and-long-time-tail-anomalies">Linearity Regimes and Long-Time Tail Anomalies</h2>
<ul>
<li><strong>Agreement with Experiment</strong>: The Evans method yields thermal conductivities in broad agreement with experimental Argon data for most state points.</li>
<li><strong>Linearity</strong>: Away from the critical point, conductivity is a virtually linear function of the field strength $F$, allowing for accurate zero-field extrapolation.</li>
<li><strong>Critical Region Failure</strong>: Near the critical point ($T=1.35, \rho=0.4$), the method struggles; the conductivity is non-monotonic with respect to $F$, and the zero-field extrapolation underestimates the experimental value by ~11%.</li>
<li><strong>Long-Time Tails</strong>: The decay of the heat flux autocorrelation function follows a $t^{-3/2}$ tail (consistent with mode-coupling theory), but the <strong>amplitude is ~6x larger</strong> than predicted.</li>
<li><strong>Phase Hysteresis</strong>: In high-density regions near the freezing line, the system exhibits hysteresis and bi-stability between solid and liquid phases depending on the field strength.</li>
</ul>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<p>The simulation relies on the Lennard-Jones (LJ) potential to model Argon. No external training data is used; the &ldquo;data&rdquo; consists of the physical constants defining the system.</p>
<table>
	<thead>
			<tr>
					<th>Parameter</th>
					<th>Value/Description</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Potential</strong></td>
					<td>$\Phi(q)=4(q^{-12}-q^{-6})$</td>
					<td>Standard LJ 12-6 potential</td>
			</tr>
			<tr>
					<td><strong>Cutoff</strong></td>
					<td>$r_c = 2.5$</td>
					<td>Truncated at 2.5 distance units</td>
			</tr>
			<tr>
					<td><strong>Comparison</strong></td>
					<td>Argon Experimental Data</td>
					<td>Sourced from NBS recommended values</td>
			</tr>
	</tbody>
</table>
<h3 id="algorithms">Algorithms</h3>
<p>The core algorithm is the <strong>Evans Homogeneous Heat Flow</strong> method. To reproduce this, one must implement the specific Equations of Motion (EOM) derived from linear response theory.</p>
<p><strong>Equations of Motion:</strong></p>
<p>The trajectories are generated by:
$$
\begin{aligned}
\dot{q}_i &amp;= \frac{p_i}{m} \\
\dot{p}_i &amp;= F_i^{\text{inter}} + (E_i - \bar{E})F(t) - \sum_{j} F_{ij} q_{ij} \cdot F(t) + \frac{1}{2N} \sum_{j,k} F_{jk} q_{jk} \cdot F(t) - \alpha p_i
\end{aligned}
$$</p>
<p>Where:</p>
<ul>
<li>$F(t)$ is the fictitious external field driving heat flow.</li>
<li>$E_i$ is the instantaneous energy of particle $i$.</li>
<li>$\alpha$ is the <strong>Gaussian Thermostat multiplier</strong> (calculated at every step to strictly conserve kinetic energy/Temperature):
$$\alpha = \frac{\sum_i [\dots]_{\text{force terms}} \cdot p_i}{\sum_i p_i \cdot p_i}$$</li>
</ul>
<p><strong>Conductivity Calculation:</strong></p>
<p>The zero-frequency limit is extrapolated as:
$$ \lambda = \lim_{F \to 0} \frac{J_Q}{FT} $$</p>
<p>The frequency-dependent conductivity relies on the heat-flux autocorrelation:
$$ \lambda(\omega) = \frac{V}{3k_B T^2} \int_0^\infty dt , e^{i\omega t} \langle J_Q(t) \cdot J_Q(0) \rangle $$</p>
<h3 id="models">Models</h3>
<p>The &ldquo;model&rdquo; here is the physical simulation setup.</p>
<ul>
<li><strong>Particle Count</strong>: $N = 108$ (primary), $N = 256$ (validation).</li>
<li><strong>Boundary Conditions</strong>: Periodic Boundary Conditions (PBC).</li>
<li><strong>Thermostat</strong>: Gaussian Isokinetic (Temperature is a constant of motion).</li>
</ul>
<h3 id="evaluation">Evaluation</h3>
<p>The primary metric is the <strong>Thermal Conductivity</strong> ($\lambda$).</p>
<table>
	<thead>
			<tr>
					<th>Metric</th>
					<th>Definition</th>
					<th>Baseline</th>
					<th>Result</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Thermal Conductivity</strong></td>
					<td>Ratio of heat flux $J_Q$ to field $F$ (extrapolated to $F=0$)</td>
					<td>Experimental Argon (NBS Data)</td>
					<td>Good agreement away from critical point</td>
			</tr>
			<tr>
					<td><strong>Tail Amplitude</strong></td>
					<td>Coefficient of the $\omega^{1/2}$ term in frequency-dependent conductivity</td>
					<td>Mode-Coupling Theory ($\approx 0.05$)</td>
					<td>Simulation value $\approx 0.3$ (6x larger)</td>
			</tr>
	</tbody>
</table>
<h3 id="hardware">Hardware</h3>
<ul>
<li><strong>Requirements</strong>: While 1986 hardware is obsolete, reproducing this requires a standard MD code capable of non-conservative forces (NEMD).</li>
<li><strong>Compute Cost</strong>: Low by modern standards. 108 particles for $\sim 10^5$ to $10^6$ steps is trivial on modern CPUs.</li>
</ul>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Evans, D. J. (1986). Thermal conductivity of the Lennard-Jones fluid. <em>Physical Review A</em>, 34(2), 1449-1453. <a href="https://doi.org/10.1103/PhysRevA.34.1449">https://doi.org/10.1103/PhysRevA.34.1449</a></p>
<p><strong>Publication</strong>: Physical Review A, 1986</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{PhysRevA.34.1449,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span> = <span style="color:#e6db74">{Thermal conductivity of the Lennard-Jones fluid}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span> = <span style="color:#e6db74">{Evans, Denis J.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span> = <span style="color:#e6db74">{Phys. Rev. A}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span> = <span style="color:#e6db74">{34}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span> = <span style="color:#e6db74">{2}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span> = <span style="color:#e6db74">{1449--1453}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">numpages</span> = <span style="color:#e6db74">{0}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span> = <span style="color:#e6db74">{1986}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">month</span> = <span style="color:#e6db74">{Aug}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span> = <span style="color:#e6db74">{American Physical Society}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span> = <span style="color:#e6db74">{10.1103/PhysRevA.34.1449}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">url</span> = <span style="color:#e6db74">{https://link.aps.org/doi/10.1103/PhysRevA.34.1449}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>Embedded-Atom Method: Theory and Applications Review</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-review-1993/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-review-1993/</guid><description>Comprehensive 1993 review of the Embedded-Atom Method (EAM), covering theory, parameterization, and applications to metallic systems.</description><content:encoded><![CDATA[<h2 id="systematizing-the-embedded-atom-method">Systematizing the Embedded-Atom Method</h2>
<p>This is a <strong>Systematization (Review)</strong> paper. It consolidates the theoretical development, semi-empirical parameterization, and broad applications of the Embedded-Atom Method (EAM) into a unified framework. The paper systematizes the field by connecting the EAM to related theories (Effective Medium Theory, Finnis-Sinclair, &ldquo;glue&rdquo; models) and organizing phenomenological results across diverse physical regimes (bulk, surfaces, interfaces).</p>
<p>The authors explicitly frame the work as a survey, stating &ldquo;We review here the history, development, and application of the EAM&rdquo; and &ldquo;This review emphasizes the physical insight that motivated the EAM.&rdquo; The paper follows a classic survey structure, organizing the literature by application domains.</p>
<h2 id="the-failure-of-pair-potentials-in-metallic-systems">The Failure of Pair Potentials in Metallic Systems</h2>
<p>The primary motivation is the failure of pair-potential models to accurately describe metallic bonding, particularly at defects and interfaces.</p>
<p><strong>Physics Gap</strong>: Pair potentials assume bond strength is independent of environment, implying cohesive energy scales linearly with coordination ($Z$), whereas in reality it scales roughly as $\sqrt{Z}$.</p>
<p><strong>Empirical Failures</strong>: Pair potentials incorrectly predict the &ldquo;Cauchy relation&rdquo; ($C_{12} = C_{44}$) and predict a vacancy formation energy equal to the cohesive energy, contradicting experimental data for fcc metals.</p>
<p><strong>Practical Need</strong>: First-principles calculations (like DFT) were computationally too expensive for low-symmetry systems like grain boundaries and fracture tips, creating a need for an efficient, semi-empirical many-body potential.</p>
<h2 id="theoretical-unification--core-innovations">Theoretical Unification &amp; Core Innovations</h2>
<p>The paper&rsquo;s core contribution is the synthesis of the EAM as a practical computational tool that captures &ldquo;coordination-dependent bond strength&rdquo; without the cost of ab initio methods.</p>
<p><strong>Theoretical Unification</strong>: It demonstrates that the EAM ansatz can be derived from Density Functional Theory (DFT) by assuming the total electron density is a superposition of atomic densities.</p>
<p><strong>Environmental Dependence</strong>: It explicitly formulates how the &ldquo;effective&rdquo; pair interaction stiffens and shortens as coordination decreases (e.g., at surfaces), a feature naturally arising from the non-linearity of the embedding function.</p>
<p><strong>Broad Validation</strong>: It provides a centralized evaluation of the method across a vast array of metallic properties, establishing it as the standard for atomistic simulations of face-centered cubic (fcc) metals.</p>
<h2 id="validating-eam-across-application-domains">Validating EAM Across Application Domains</h2>
<p>The authors review computational experiments using Energy Minimization, Molecular Dynamics (MD), and Monte Carlo (MC) simulations across several domains:</p>
<p><strong>Bulk Properties</strong>: Calculation of phonon spectra, liquid structure factors, thermal expansion coefficients, and melting points for fcc metals (Ni, Pd, Pt, Cu, Ag, Au).</p>
<p><strong>Defects</strong>: Computation of vacancy formation/migration energies and self-interstitial geometries.</p>
<p><strong>Grain Boundaries</strong>: Calculation of grain boundary structures, energies, and elastic properties for twist and tilt boundaries in Au and Al. Computed structures show good agreement with X-ray diffraction and HRTEM experiments. The many-body interactions in the EAM produce somewhat better agreement than pair potentials, which tend to overestimate boundary expansion.</p>
<p><strong>Surfaces</strong>: Analysis of surface energies, relaxations, reconstructions (e.g., Au(110) missing row), and surface phonons.</p>
<p><strong>Alloys</strong>: Investigation of heat of solution, surface segregation profiles (e.g., Ni-Cu), and order-disorder transitions.</p>
<p><strong>Mechanical Properties</strong>: Simulation of dislocation mobility, pinning by defects (He bubbles), and crack tip plasticity (ductile vs. brittle fracture modes).</p>
<h2 id="key-outcomes-and-the-limits-of-eam">Key Outcomes and the Limits of EAM</h2>
<p><strong>Many-Body Success</strong>: The EAM successfully reproduces the breakdown of the Cauchy relation and the correct ratio of vacancy formation energy to cohesive energy (~0.35) for fcc metals.</p>
<p><strong>Surface Accuracy</strong>: It correctly predicts that surface bonds are shorter and stiffer than bulk bonds due to lower coordination. It accurately predicts surface reconstructions (e.g., Au(110) $(1 \times 2)$).</p>
<p><strong>Alloy Behavior</strong>: The method naturally captures segregation phenomena, including oscillating concentration profiles in Ni-Cu, driven by the embedding energy.</p>
<p><strong>Limitations</strong>: The method is less accurate for systems with strong directional bonding (covalent materials) or significant Fermi-surface effects, as it assumes spherically averaged electron densities.</p>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<p><strong>Fitting Data</strong>: The semi-empirical functions are fitted to basic bulk properties: lattice constants, cohesive energy, elastic constants ($C_{11}$, $C_{12}$, $C_{44}$), and vacancy formation energy.</p>
<p><strong>Universal Binding Curve</strong>: The cohesive energy as a function of lattice constant is constrained to follow the &ldquo;universal binding curve&rdquo; of Rose et al. to ensure accurate anharmonic behavior.</p>
<p><strong>Alloy Data</strong>: For binary alloys, dilute heats of alloying are used for fitting cross-interactions.</p>
<h3 id="algorithms">Algorithms</h3>
<p><strong>Core Ansatz</strong>: The total energy is defined as:</p>
<p>$$E_{coh} = \sum_{i} G_i\left( \sum_{j \neq i} \rho_j^a(R_{ij}) \right) + \frac{1}{2} \sum_{i, j (j \neq i)} U_{ij}(R_{ij})$$</p>
<p>where $G$ is the embedding energy (function of local electron density $\rho$), and $U$ is a pair interaction.</p>
<p><strong>Simulation Techniques</strong>:</p>
<ul>
<li><strong>Molecular Dynamics (MD)</strong>: Used for liquids, phonons, and fracture simulations.</li>
<li><strong>Monte Carlo (MC)</strong>: Used for phase diagrams and segregation profiles (e.g., approximately $10^5$ iterations per atom).</li>
<li><strong>Phonons</strong>: Calculated via the dynamical matrix derived from the force-constant tensor $K_{ij}$.</li>
<li><strong>Normal-Mode Analysis</strong>: Vibrational normal modes obtained by diagonalizing the dynamical matrix, feasible for unit cells of up to about 260 atoms.</li>
</ul>
<h3 id="models">Models</h3>
<p><strong>Parameterizations</strong>: The review lists several specific function sets developed by the authors (Table 2), including:</p>
<ul>
<li><strong>Daw and Baskes</strong>: For Ni, Pd, H (elemental metals and H in solution/on surfaces)</li>
<li><strong>Foiles</strong>: For Cu, Ag, Au, Ni, Pd, Pt (elemental metals)</li>
<li><strong>Foiles</strong>: For Cu, Ni (tailored for the Ni-Cu alloy system)</li>
<li><strong>Foiles, Baskes and Daw</strong>: For Cu, Ag, Au, Ni, Pd, Pt (dilute alloys)</li>
<li><strong>Daw, Baskes, Bisson and Wolfer</strong>: For Ni, H (fracture, dislocations, H embrittlement)</li>
<li><strong>Foiles and Daw</strong>: For Ni, Al (Ni-rich end of the Ni-Al alloy system)</li>
<li><strong>Daw</strong>: For Ni (calculated from first principles, not semi-empirical)</li>
<li><strong>Hoagland, Daw, Foiles and Baskes</strong>: For Al (elemental Al)</li>
</ul>
<p>Many of these historical parameterizations are directly downloadable in machine-readable formats from the NIST Interatomic Potentials Repository (linked in the resources below).</p>
<p><strong>Transferability</strong>: EAM functions are generally <em>not</em> transferable between different parameterization sets; mixing functions from different sets (e.g., Daw-Baskes Ni with Foiles Pd) is invalid.</p>
<h3 id="evaluation">Evaluation</h3>
<p><strong>Bulk Validation</strong>: Phonon dispersion curves for Cu show excellent agreement with experiment across the full Brillouin zone.</p>
<p><strong>Thermal Properties</strong>: Linear thermal expansion coefficients match experiment well (e.g., Cu calculated: $16.4 \times 10^{-6}/K$ vs experimental: $16.7 \times 10^{-6}/K$).</p>
<p><strong>Defect Energetics</strong>: Vacancy migration energies and divacancy binding energies (~0.1-0.2 eV) align with experimental data.</p>
<p><strong>Surface Segregation</strong>: Correctly predicts segregation species for 18 distinct dilute alloy cases (e.g., Cu segregating in Ni).</p>
<h3 id="hardware">Hardware</h3>
<p><strong>Compute Scale</strong>: At the time of publication (1993), Molecular Dynamics simulations of up to 35,000 atoms were possible.</p>
<p><strong>Platforms</strong>: Calculations were performed on supercomputers like the <strong>CRAY-XMP</strong>, though smaller calculations were noted as feasible on high-performance workstations.</p>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Daw, M. S., Foiles, S. M., &amp; Baskes, M. I. (1993). The embedded-atom method: a review of theory and applications. <em>Materials Science Reports</em>, 9(7-8), 251-310. <a href="https://doi.org/10.1016/0920-2307(93)90001-U">https://doi.org/10.1016/0920-2307(93)90001-U</a></p>
<p><strong>Publication</strong>: Materials Science Reports 1993</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{dawEmbeddedatomMethodReview1993,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span> = <span style="color:#e6db74">{The embedded-atom method: a review of theory and applications}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">shorttitle</span> = <span style="color:#e6db74">{The Embedded-Atom Method}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span> = <span style="color:#e6db74">{Daw, Murray S. and Foiles, Stephen M. and Baskes, Michael I.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span> = <span style="color:#ae81ff">1993</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">month</span> = mar,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span> = <span style="color:#e6db74">{Materials Science Reports}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span> = <span style="color:#e6db74">{9}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span> = <span style="color:#e6db74">{7-8}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span> = <span style="color:#e6db74">{251--310}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">issn</span> = <span style="color:#e6db74">{0920-2307}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span> = <span style="color:#e6db74">{10.1016/0920-2307(93)90001-U}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Additional Resources</strong>:</p>
<ul>
<li><a href="/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method/">Original EAM Paper (1984)</a></li>
<li><a href="/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-voter-1994/">EAM User Guide (1994)</a></li>
<li><a href="https://www.ctcms.nist.gov/potentials/">NIST Interatomic Potentials Repository</a></li>
</ul>
]]></content:encoded></item><item><title>Embedded-Atom Method User Guide: Voter's 1994 Chapter</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-voter-1994/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-voter-1994/</guid><description>Comprehensive user guide for the Embedded-Atom Method (EAM), covering theory, potential fitting, and applications to intermetallics.</description><content:encoded><![CDATA[<h2 id="contribution-systematizing-the-embedded-atom-method">Contribution: Systematizing the Embedded-Atom Method</h2>
<p>This is a <strong>Systematization</strong> paper (specifically a handbook chapter) with a strong secondary <strong>Method</strong> projection.</p>
<p>Its primary goal is to serve as a &ldquo;users&rsquo; guide&rdquo; to the Embedded-Atom Method (EAM). The text organizes existing knowledge:</p>
<ul>
<li>It traces the physical origins of EAM from Density Functional Theory (DFT) and Effective Medium Theory.</li>
<li>It synthesizes &ldquo;closely related methods&rdquo; (Second Moment Approximation, Glue Model), showing they are mathematically equivalent or very similar to EAM.</li>
<li>It provides a pedagogical, step-by-step methodology for fitting potentials to experimental data.</li>
</ul>
<h2 id="motivation-bridging-the-gap-between-dft-and-pair-potentials">Motivation: Bridging the Gap Between DFT and Pair Potentials</h2>
<p>The primary motivation is to bridge the gap between accurate, expensive electronic structure calculations and fast, inaccurate pair potentials.</p>
<ul>
<li><strong>Computational Efficiency</strong>: First-principles methods scale as $O(N^3)$ or worse, limiting simulations to $&lt;100$ atoms (in 1994). Pair potentials scale as $O(N)$ and fail to capture essential many-body physics of metals.</li>
<li><strong>Physical Accuracy</strong>: Simple pair potentials cannot accurately model metallic defects; they predict zero Cauchy pressure ($C_{12} - C_{44} = 0$) and equate vacancy formation energy to cohesive energy, both of which are incorrect for transition metals.</li>
<li><strong>Practical Utility</strong>: There was a need for a clear guide on how to construct and apply these potentials for large-scale simulations ($10^6+$ atoms) of fracture and defects.</li>
</ul>
<h2 id="novelty-a-unified-framework-and-robust-fitting-recipe">Novelty: A Unified Framework and Robust Fitting Recipe</h2>
<p>As a review chapter, the novelty lies in the synthesis and the specific, reproducible recipe for potential construction. Central to this synthesis is the core EAM energy functional:</p>
<p>$$E_{\text{tot}} = \sum_i \left( F(\bar{\rho}_i) + \frac{1}{2} \sum_{j \neq i} \phi(r_{ij}) \right)$$</p>
<p>where the total energy $E_{\text{tot}}$ depends on embedding an atom $i$ into a local background electron density $\bar{\rho}_i = \sum_{j \neq i} \rho(r_{ij})$, plus a repulsive pair interaction $\phi(r_{ij})$.</p>
<ul>
<li><strong>Unified Framework</strong>: It explicitly maps the &ldquo;Second Moment Approximation&rdquo; (Tight Binding) and the &ldquo;Glue Model&rdquo; onto the fundamental EAM framework above, clarifying that they differ primarily in terminology or specific functional choices (e.g., square root embedding functions).</li>
<li><strong>Cross-Potential Fitting Recipe</strong>: It details a robust method for fitting alloy potentials (specifically Ni-Al-B) by using &ldquo;transformation invariance&rdquo;, scaling the density and shifting the embedding function to fit alloy properties without disturbing pure element fits.</li>
<li><strong>Specific Parameters</strong>: It publishes optimized potential parameters for Ni, Al, and B that accurately reproduce properties like the Boron interstitial preference in $\text{Ni}_3\text{Al}$.</li>
</ul>
<h2 id="validation-computational-benchmarks-and-simulations">Validation: Computational Benchmarks and Simulations</h2>
<p>The &ldquo;experiments&rdquo; described are computational validations and simulations using the fitted Ni-Al-B potential:</p>
<ol>
<li>
<p><strong>Potential Fitting</strong>:</p>
<ul>
<li>Pure elements (Ni, Al) were fitted to elastic constants, vacancy formation energies, and diatomic data. The Ni fit achieved $\chi_{\text{rms}} = 0.75%$ and Al achieved $\chi_{\text{rms}} = 3.85%$.</li>
<li>Boron was fitted using hypothetical crystal structures (fcc, bcc) calculated via LMTO (Linear Muffin-Tin Orbital) since experimental data for fcc B does not exist.</li>
</ul>
</li>
<li>
<p><strong>Molecular Statics (Validation)</strong>:</p>
<ul>
<li><strong>Surface Relaxation</strong>: Demonstrated that EAM captures the oscillatory relaxation of atomic layers near a free surface, a many-body effect that pair potentials fail to capture.</li>
<li><strong>Defect Energetics</strong>: Calculated formation energies for Boron interstitials in $\text{Ni}_3\text{Al}$. Found the 6Ni-octahedral site is most stable ($-4.59$ eV relative to an isolated B atom and unperturbed crystal), followed by the 4Ni-2Al octahedral site ($-3.65$ eV) and the 3Ni-1Al tetrahedral site ($-2.99$ eV), consistent with channeling experiments.</li>
</ul>
</li>
<li>
<p><strong>Molecular Dynamics (Application)</strong>:</p>
<ul>
<li><strong>Grain Boundary (GB) Cleavage</strong>: Simulated the fracture of a (210) tilt grain boundary in $\text{Ni}_3\text{Al}$ at a strain rate of $5 \times 10^{10}$ s$^{-1}$.</li>
<li><strong>Comparison</strong>: Compared pure $\text{Ni}_3\text{Al}$ boundaries vs. those doped with Boron and substitutional Nickel.</li>
</ul>
</li>
</ol>
<h2 id="key-outcomes-eam-efficiency-and-boron-strengthening">Key Outcomes: EAM Efficiency and Boron Strengthening</h2>
<ul>
<li><strong>EAM Efficiency</strong>: Confirmed that EAM scales linearly with atom count ($N$), requiring only 2-5 times the computational work of pair potentials.</li>
<li><strong>Boron Strengthening Mechanism</strong>: The simulations suggested that Boron segregates to grain boundaries and, specifically when co-segregated with Ni, significantly increases cohesion.
<ul>
<li>The maximum stress for the enriched boundary was approximately 22 GPa, compared to approximately 19 GPa for the clean boundary.</li>
<li>The B-doped boundary required approximately 44% more work to cleave than the undoped boundary.</li>
<li>The fracture mode shifted from cleaving along the GB to failure in the bulk.</li>
</ul>
</li>
<li><strong>Grain Boundary Segregation</strong>: Molecular statics calculations found B interstitial energies at the GB as low as $-6.9$ eV, compared to $-4.59$ eV in the bulk, consistent with experimental observations of boron segregation to grain boundaries.</li>
<li><strong>Limitations</strong>: The author concludes that while EAM is excellent for metals, it lacks the angular dependence required for strongly covalent materials (like $\text{MoSi}_2$) or directional bonding.</li>
</ul>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<p>The chapter provides nearly all details required to implement the described potential from scratch.</p>
<h3 id="data">Data</h3>
<ul>
<li><strong>Experimental/Reference Data</strong>: Used for fitting the cost function $\chi_{\text{rms}}$.
<ul>
<li><strong>Pure Elements</strong>: Lattice constants ($a_0$), cohesive energy ($E_{\text{coh}}$), bulk modulus ($B$), elastic constants ($C_{11}, C_{12}, C_{44}$), vacancy formation energy ($E_{\text{vac}}^f$), and diatomic bond length/strength ($R_e, D_e$).</li>
<li><strong>Alloys</strong>: Heat of solution and defect energies (APB, SISF) for $\text{Ni}_3\text{Al}$.</li>
<li><strong>Hypothetical Data</strong>: LMTO first-principles data used for unobserved phases (e.g., fcc Boron, B2 NiB) to constrain the fit.</li>
</ul>
</li>
</ul>
<h3 id="algorithms">Algorithms</h3>
<ul>
<li><strong>Component Functions</strong>:
<ul>
<li><strong>Pair Potential $\phi(r)$</strong>: Morse potential form:
$$\phi(r) = D_M {1 - \exp[-\alpha_M(r - R_M)]}^2 - D_M$$</li>
<li><strong>Density Function $\rho(r)$</strong>: Modified hydrogenic 4s orbital:
$$\rho(r) = r^6(e^{-\beta r} + 2^9 e^{-2\beta r})$$</li>
<li><strong>Embedding Function $F(\bar{\rho})$</strong>: Derived numerically to force the crystal energy to match the &ldquo;Universal Energy Relation&rdquo; (Rose et al.) as a function of lattice constant.</li>
</ul>
</li>
<li><strong>Fitting Strategy</strong>:
<ul>
<li><strong>Smooth Cutoff</strong>: A polynomial smoothing function ($h_{\text{smooth}}$) applied at $r_{\text{cut}}$ to ensure continuous derivatives.</li>
<li><strong>Simplex Algorithm</strong>: Used to optimize parameters ($D_M, R_M, \alpha_M, \beta, r_{\text{cut}}$).</li>
<li><strong>Alloy Invariance</strong>: Used transformations $F&rsquo;(\rho) = F(\rho) + g\rho$ and $\rho&rsquo;(r) = s\rho(r)$ to fit cross-potentials without altering pure-element properties.</li>
</ul>
</li>
</ul>
<h3 id="models">Models</h3>
<ul>
<li><strong>Parameters</strong>: The text provides the exact optimized parameters for the Ni-Al-B potential in <strong>Table 2</strong> (Pure elements) and <strong>Table 5</strong> (Cross-potentials).
<ul>
<li>Example Ni parameters: $D_M=1.5335$ eV, $\alpha_M=1.7728$ Å$^{-1}$, $r_{\text{cut}}=4.7895$ Å.</li>
</ul>
</li>
</ul>
<h3 id="hardware">Hardware</h3>
<ul>
<li><strong>1994 Context</strong>: Mentions that simulations of $10^6$ atoms were possible on the &ldquo;fastest computers available&rdquo;.</li>
<li><strong>Scaling</strong>: Explicitly notes computational work scales as $O(N)$, roughly 2-5x slower than pair potentials.</li>
</ul>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Voter, A. F. (1994). Chapter 4: The Embedded-Atom Method. In <em>Intermetallic Compounds: Vol. 1, Principles</em>, edited by J. H. Westbrook and R. L. Fleischer. John Wiley &amp; Sons Ltd.</p>
<p><strong>Publication</strong>: Intermetallic Compounds: Vol. 1, Principles (1994)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@incollection</span>{voterEmbeddedAtomMethod1994,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span> = <span style="color:#e6db74">{The Embedded-Atom Method}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span> = <span style="color:#e6db74">{Voter, Arthur F.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">booktitle</span> = <span style="color:#e6db74">{Intermetallic Compounds: Vol. 1, Principles}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">editor</span> = <span style="color:#e6db74">{Westbrook, J. H. and Fleischer, R. L.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span> = <span style="color:#e6db74">{1994}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span> = <span style="color:#e6db74">{John Wiley &amp; Sons Ltd}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span> = <span style="color:#e6db74">{77--90}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">chapter</span> = <span style="color:#e6db74">{4}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Additional Resources</strong>:</p>
<ul>
<li><a href="https://www.ctcms.nist.gov/potentials/">NIST Interatomic Potentials Repository</a> (Modern repository often hosting EAM files)</li>
<li><a href="/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method/">Original EAM Paper (1984)</a></li>
<li><a href="/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-review-1993/">EAM Review (1993)</a></li>
</ul>
]]></content:encoded></item><item><title>Correlations in the Motion of Atoms in Liquid Argon</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/correlations-motion-atoms-liquid-argon/</link><pubDate>Sat, 13 Dec 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/correlations-motion-atoms-liquid-argon/</guid><description>Rahman's 1964 MD simulation of 864 argon atoms with Lennard-Jones potential revealed the cage effect and validated classical molecular dynamics for liquids.</description><content:encoded><![CDATA[<h2 id="contribution-methodological-validation-of-md">Contribution: Methodological Validation of MD</h2>
<p>This is the archetypal <strong>Method</strong> paper (dominant classification with secondary <strong>Theory</strong> contribution). It establishes the architectural validity of Molecular Dynamics (MD) as a scientific tool. Rahman answers the question: &ldquo;Can a digital computer solving classical difference equations faithfully represent a physical liquid?&rdquo;</p>
<p>The paper utilizes specific rhetorical indicators of a methodological contribution:</p>
<ul>
<li><strong>Algorithmic Explication</strong>: A dedicated Appendix details the predictor-corrector difference equations.</li>
<li><strong>Validation against Ground Truth</strong>: Extensive comparison of calculated diffusion constants and pair-correlation functions against experimental neutron and X-ray scattering data.</li>
<li><strong>Robustness Checks</strong>: Ablation studies on the numerical integration stability (one vs. two corrector cycles).</li>
</ul>
<h2 id="motivation-bridging-neutron-scattering-and-many-body-theory">Motivation: Bridging Neutron Scattering and Many-Body Theory</h2>
<p>In the early 1960s, neutron scattering data provided insights into the dynamic structure of liquids, but theorists lacked concrete models to explain the observed two-body dynamical correlations. Analytic theories were limited by the difficulty of the many-body problem.</p>
<p>Rahman sought to bypass these analytical bottlenecks by assuming that <strong>classical dynamics</strong> with a simple 2-body potential (Lennard-Jones) could sufficiently describe the motion of atoms in liquid argon. The goal was to generate &ldquo;experimental&rdquo; data via simulation to test theoretical models (like the Vineyard convolution approximation) and provide a microscopic understanding of diffusion.</p>
<h2 id="core-innovation-system-stability-and-the-cage-effect">Core Innovation: System Stability and the Cage Effect</h2>
<p>This paper is widely considered the birth of modern molecular dynamics for continuous potentials. Its key novelties include:</p>
<ol>
<li><strong>System Size &amp; Stability</strong>: Successfully simulating 864 particles interacting via a continuous Lennard-Jones potential with stable temperature over the full simulation duration (approximately $10^{-11}$ sec, as confirmed by Table I in the paper).</li>
<li><strong>The &ldquo;Cage Effect&rdquo;</strong>: The discovery that the velocity autocorrelation function becomes negative after a short time:
$$ \langle \textbf{v}(0) \cdot \textbf{v}(t) \rangle &lt; 0 \quad \text{for } t &gt; 0.33 \times 10^{-12} \text{ s} $$
This proved that atoms in a liquid &ldquo;rattle&rdquo; against the cage of their nearest neighbors.</li>
<li><strong>Delayed Convolution</strong>: Proposing an improvement to the Vineyard approximation for the distinct Van Hove function $G_d(r,t)$ by introducing a time-delayed convolution to account for the persistence of local structure. Instead of convolving $g(r)$ with $G_s(r,t)$ at the same time $t$, Rahman convolves at a delayed time $t&rsquo; &lt; t$, using a one-parameter function with $\tau = 1.0 \times 10^{-12}$ sec. This makes $G_d(r,t)$ decay as $t^4$ at short times (instead of $t^2$ in the Vineyard approximation) and as $t$ at long times.</li>
</ol>
<h2 id="methodology-simulating-864-argon-atoms">Methodology: Simulating 864 Argon Atoms</h2>
<p>Rahman performed a &ldquo;computer experiment&rdquo; (simulation) of <strong>Liquid Argon</strong>:</p>
<ul>
<li><strong>System</strong>: 864 particles in a cubic box of side $L=10.229\sigma$.</li>
<li><strong>Conditions</strong>: Temperature $94.4^\circ$K, Density $1.374 \text{ g cm}^{-3}$.</li>
<li><strong>Interaction</strong>: Lennard-Jones potential, truncated at $R=2.25\sigma$.</li>
<li><strong>Time Step</strong>: $\Delta t = 10^{-14}$ s (780 steps total, covering approximately $7.8 \times 10^{-12}$ s).</li>
<li><strong>Output Analysis</strong>:
<ul>
<li>Radial distribution function $g(r)$.</li>
<li>Mean square displacement $\langle r^2 \rangle$.</li>
<li>Velocity autocorrelation function $\langle v(0)\cdot v(t) \rangle$.</li>
<li>Van Hove space-time correlation functions $G_s(r,t)$ and $G_d(r,t)$.</li>
</ul>
</li>
</ul>
<h2 id="results-validation-and-non-gaussian-diffusion-analysis">Results: Validation and Non-Gaussian Diffusion Analysis</h2>
<ul>
<li><strong>Validation</strong>: The calculated pair-distribution function $g(r)$ agreed well with X-ray scattering data from Eisenstein and Gingrich (at $91.8^\circ$K). The self-diffusion constant $D = 2.43 \times 10^{-5} \text{ cm}^2 \text{ sec}^{-1}$ at $94.4^\circ$K matched the experimental value from Naghizadeh and Rice at $90^\circ$K and the same density ($1.374 \text{ g cm}^{-3}$).</li>
<li><strong>Dynamics</strong>: The velocity autocorrelation has a negative region, contradicting simple exponential decay models (Langevin). Its frequency spectrum $f(\omega)$ shows a broad maximum at $\omega \approx 0.25 (k_BT/\hbar)$, reminiscent of solid-like behavior.</li>
<li><strong>Non-Gaussian Behavior</strong>: The self-diffusion function $G_s(r,t)$ attains its maximum departure from a Gaussian shape at about $t \approx 3.0 \times 10^{-12}$ s (with $\langle r^4 \rangle$ departing from its Gaussian value by about 13%), returning to Gaussian form by $\sim 10^{-11}$ s. At that time, the rms displacement ($3.8$ Angstrom) is close to the first-neighbor distance ($3.7$ Angstrom). This indicates that Fickian diffusion is an asymptotic limit and does not apply at short times.</li>
<li><strong>Fourier Transform Validation</strong>: The Fourier transform of $g(r)$ has peaks at $\kappa\sigma = 6.8$, 12.5, 18.5, 24.8, closely matching the X-ray scattering peaks at $\kappa\sigma = 6.8$, 12.3, 18.4, 24.4.</li>
<li><strong>Temperature Dependence</strong>: A second simulation at $130^\circ$K and $1.16 \text{ g cm}^{-3}$ yielded $D = 5.67 \times 10^{-5} \text{ cm}^2 \text{ sec}^{-1}$, compared to the experimental value of $6.06 \times 10^{-5} \text{ cm}^2 \text{ sec}^{-1}$ from Naghizadeh and Rice at $120^\circ$K and $1.16 \text{ g cm}^{-3}$. The paper notes that both calculated values are lower than experiment by about 20%, and suggests that allowing for a softer repulsive part in the interaction potential might reduce this discrepancy.</li>
<li><strong>Vineyard Approximation</strong>: The standard Vineyard convolution approximation ($G_d \approx g * G_s$) produces a too-rapid decay of $G_d(r,t)$ with time. The delayed convolution, matching pairs of $(t&rsquo;, t)$ in units of $10^{-12}$ sec as (0.2, 0.4), (0.5, 0.8), (1.0, 1.6), (1.5, 2.3), (2.0, 2.9), (2.5, 3.5), provides a substantially better fit.</li>
<li><strong>Conclusion</strong>: Classical N-body dynamics with a truncated pair potential is a sufficient model to reproduce both the structural and dynamical properties of simple liquids.</li>
</ul>
<hr>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="data">Data</h3>
<p>The simulation uses physical constants for Argon:</p>
<table>
	<thead>
			<tr>
					<th>Parameter</th>
					<th>Value</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Particle Mass ($M$)</td>
					<td>$39.95 \times 1.6747 \times 10^{-24}$ g</td>
					<td>Mass of Argon atom</td>
			</tr>
			<tr>
					<td>Potential Depth ($\epsilon/k_B$)</td>
					<td>$120^\circ$K</td>
					<td>Lennard-Jones parameter</td>
			</tr>
			<tr>
					<td>Potential Size ($\sigma$)</td>
					<td>$3.4$ Å</td>
					<td>Lennard-Jones parameter</td>
			</tr>
			<tr>
					<td>Cutoff Radius ($R$)</td>
					<td>$2.25\sigma$</td>
					<td>Potential truncated beyond this</td>
			</tr>
			<tr>
					<td>Density ($\rho$)</td>
					<td>$1.374$ g cm$^{-3}$</td>
					<td></td>
			</tr>
			<tr>
					<td>Particle Count ($N$)</td>
					<td>864</td>
					<td></td>
			</tr>
	</tbody>
</table>
<h3 id="algorithms">Algorithms</h3>
<p>Rahman utilized a <strong>Predictor-Corrector</strong> scheme for solving the second-order differential equations of motion.</p>
<p><strong>Step Size</strong>: $\Delta t = 10^{-14}$ sec.</p>
<p><strong>The Algorithm:</strong></p>
<ol>
<li><strong>Predict</strong> positions $\bar{\xi}$ at $t + \Delta t$ based on previous steps:
$$\bar{\xi}_i^{(n+1)} = \xi_i^{(n-1)} + 2\Delta u \eta_i^{(n)}$$</li>
<li><strong>Calculate Forces</strong> (Accelerations $\alpha$) using predicted positions.</li>
<li><strong>Correct</strong> positions and velocities using the trapezoidal rule:
$$
\begin{aligned}
\eta_i^{(n+1)} &amp;= \eta_i^{(n)} + \frac{1}{2}\Delta u (\alpha_i^{(n+1)} + \alpha_i^{(n)}) \\
\xi_i^{(n+1)} &amp;= \xi_i^{(n)} + \frac{1}{2}\Delta u (\eta_i^{(n+1)} + \eta_i^{(n)})
\end{aligned}
$$</li>
</ol>
<p><em>Note: The paper compared one vs. two repetitions of the corrector step, finding that two passes improved precision slightly. The results presented in the paper were obtained using two passes.</em></p>
<h3 id="models">Models</h3>
<p><strong>Interaction Potential</strong>: Lennard-Jones 12-6
$$V(r_{ij}) = 4\epsilon \left[ \left(\frac{\sigma}{r_{ij}}\right)^{12} - \left(\frac{\sigma}{r_{ij}}\right)^6 \right]$$</p>
<p><strong>Boundary Conditions</strong>: Periodic Boundary Conditions (PBC) in 3 dimensions. When a particle moves out of the box ($x &gt; L$), it re-enters at $x - L$.</p>
<h3 id="hardware">Hardware</h3>
<p>This is a historical benchmark for computational capability in 1964:</p>
<table>
	<thead>
			<tr>
					<th>Resource</th>
					<th>Specification</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Computer</strong></td>
					<td>CDC 3600</td>
					<td>Control Data Corporation mainframe</td>
			</tr>
			<tr>
					<td><strong>Compute Time</strong></td>
					<td>45 seconds / cycle</td>
					<td>Per predictor-corrector cycle for 864 particles (floating point)</td>
			</tr>
			<tr>
					<td><strong>Language</strong></td>
					<td>FORTRAN + Machine Language</td>
					<td>Machine language used for the most time-consuming parts</td>
			</tr>
	</tbody>
</table>
<p><em>Modern Context: Rahman&rsquo;s system (864 Argon atoms, LJ-potential) is highly reproducible today and serves as a classic pedagogical exercise. It can be simulated in standard MD frameworks (LAMMPS, OpenMM) in fractions of a second on consumer hardware.</em></p>
<hr>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Rahman, A. (1964). Correlations in the Motion of Atoms in Liquid Argon. <em>Physical Review</em>, 136(2A), A405-A411. <a href="https://doi.org/10.1103/PhysRev.136.A405">https://doi.org/10.1103/PhysRev.136.A405</a></p>
<p><strong>Publication</strong>: Physical Review 1964</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{rahman1964correlations,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Correlations in the motion of atoms in liquid argon}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Rahman, A.}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{Physical Review}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{136}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span>=<span style="color:#e6db74">{2A}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{A405--A411}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{1964}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{APS}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.1103/PhysRev.136.A405}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Additional Resources</strong>:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Aneesur_Rahman">Aneesur Rahman - Wikipedia</a></li>
</ul>
]]></content:encoded></item><item><title>NInChI: Toward a Chemical Identifier for Nanomaterials</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-representations/notations/ninchi-alpha/</link><pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-representations/notations/ninchi-alpha/</guid><description>NInChI (Nanomaterials InChI) extends chemical identifiers to represent complex, multi-component nanomaterials.</description><content:encoded><![CDATA[<h2 id="a-new-standard-for-nanoinformatics">A New Standard for Nanoinformatics</h2>
<p>This is a <strong>Systematization paper</strong> that proposes a new standard: the NInChI. It addresses a fundamental limitation in nanoinformatics. The result of a collaborative workshop organized by the H2020 research infrastructure NanoCommons and the nanoinformatics project NanoSolveIT, this work uses <strong>six detailed case studies</strong> to systematically develop a <strong>hierarchical, machine-readable notation</strong> for complex nanomaterials that could work across experimental research, regulatory frameworks, and computational modeling.</p>
<h2 id="the-breakdown-of-traditional-chemical-identifiers">The Breakdown of Traditional Chemical Identifiers</h2>
<p>Chemoinformatics has fantastic tools for representing small molecules: SMILES strings, InChI identifiers, and standardized databases that make molecular data searchable and shareable. But when you step into nanotechnology, everything breaks down.</p>
<p>Consider trying to describe a gold nanoparticle with a silica shell and organic surface ligands. How do you capture:</p>
<ul>
<li>The gold core composition and size</li>
<li>The silica shell thickness and interface</li>
<li>The surface chemistry and ligand density</li>
<li>The overall shape and morphology</li>
</ul>
<p>There&rsquo;s simply no standardized way to represent this complexity in a machine-readable format. This creates massive problems for:</p>
<ul>
<li><strong>Data sharing</strong> between research groups</li>
<li><strong>Regulatory assessment</strong> where precise identification matters</li>
<li><strong>Computational modeling</strong> that needs structured input</li>
<li><strong>Database development</strong> and search capabilities</li>
</ul>
<p>Without a standard notation, nanomaterials research suffers from the same data fragmentation that plagued small molecule chemistry before SMILES existed.</p>
<h2 id="the-five-tier-nanomaterial-description-hierarchy">The Five-Tier Nanomaterial Description Hierarchy</h2>
<p>The authors propose NInChI (Nanomaterials InChI), a layered extension to the existing InChI system. The core insight is organizing nanomaterial description from the inside out, following the OECD&rsquo;s framework for risk assessment, with a five-tier hierarchy:</p>
<ol>
<li><strong>Tier 1: Chemical Composition</strong>: What is the core made of? This differentiates uniform compositions (Tier 1.1), randomly mixed (Tier 1.2), ordered core-shell materials (Tier 1.3), and onion-like multi-shell morphologies (Tier 1.4).</li>
<li><strong>Tier 2: Morphology</strong>: What shape, size, and dimensionality? This encodes dimension (0D-3D), size and size distribution, and shape information.</li>
<li><strong>Tier 3: Surface Properties</strong>: Physical and chemical surface parameters such as charge, roughness, and hydrophobicity. Many of these depend on external conditions (pH, solvent, temperature).</li>
<li><strong>Tier 4: Surface Functionalization</strong>: How are coatings attached to the core? This includes functionalization density, orientation, and binding type (covalent vs. non-covalent).</li>
<li><strong>Tier 5: Surface Ligands</strong>: What molecules are on the surface, their density, orientation, and distribution?</li>
</ol>
<p>This hierarchy captures the essential information needed to distinguish between different nanomaterials while building on familiar chemical concepts.</p>
<h2 id="testing-the-standard-six-case-studies">Testing the Standard: Six Case Studies</h2>
<p>The authors tested their concept against six real-world case studies to identify what actually matters in practice.</p>
<p><strong>Case Study 1: Gold Nanoparticles</strong></p>
<p>Gold NPs provided a relatively simple test case: an inert metallic core with various surface functionalizations. Key insights: core composition and size are essential, surface chemistry (what molecules are attached) matters critically, shape affects properties, and dynamic properties like protein corona formation belong outside the intrinsic NInChI representation. This established the boundary: NInChI should capture intrinsic, stable properties.</p>
<p><strong>Case Study 2: Graphene-Family NMs</strong></p>
<p>Carbon nanotubes and graphene introduced additional complexity: dimensionality (1D tubes vs 2D sheets vs 0D fullerenes), chirality (the (n,m) vector that defines a nanotube&rsquo;s structure), defects and impurities that can alter properties, and number of layers (for nanotubes, single-wall vs multi-wall). This case showed that the notation needed to handle both topological complexity and chemical composition.</p>
<p><strong>Case Study 3: Complex Engineered (Doped and Multi-Metallic) NMs</strong></p>
<p>Doped materials, alloys, and core-shell structures revealed key requirements: need to distinguish true alloys (homogeneous mixing) and core-shell structures with the same overall composition, crystal structure information becomes crucial, and component ratios must be precisely specified. The case study assessed whether the MInChI extension could represent these solid solutions.</p>
<p><strong>Case Study 4: Database Applications</strong></p>
<p>The FAIR (Findable, Accessible, Interoperable, Reusable) principles guided this analysis. NInChI addresses real database problems: it provides greater specificity than CAS numbers (which lack nanoform distinction), offers a systematic alternative to ad-hoc naming schemes, and enables machine-searchability.</p>
<p><strong>Case Study 5: Computational Modeling</strong></p>
<p>This explored several applications: automated descriptor generation from NInChI structure, read-across predictions for untested materials, and model input preparation from standardized notation. The layered structure provides structured input that computational tools need for both physics-based and data-driven nanoinformatics approaches.</p>
<p><strong>Case Study 6: Regulatory Applications</strong></p>
<p>Under frameworks like REACH, regulators need to distinguish between different &ldquo;nanoforms&rdquo;, which are materials with the same chemical composition but different sizes, shapes, or surface treatments. NInChI directly addresses this by encoding the specific properties that define regulatory categories, providing precision sufficient for legal definitions and risk assessment frameworks.</p>
<h2 id="the-ninchi-alpha-specification-in-practice">The NInChI Alpha Specification in Practice</h2>
<p>Synthesizing insights from all six case studies, the authors propose the <strong>NInChI alpha specification</strong> (version 0.00.1A), a three-layer structure. Importantly, the paper distinguishes the five-tier NM description hierarchy (Section 1.2 above) from the three-layer NInChI notation hierarchy. NM properties from the five tiers are encoded into these three notation layers:</p>
<p><strong>Layer 1 (Version Number)</strong>: Standard header indicating the NInChI version, denoted as <code>0.00.1A</code> for the alpha version. This follows the convention of all <a href="/notes/chemistry/molecular-representations/notations/inchi-2013/">InChI</a>-based notations.</p>
<p><strong>Layer 2 (Composition)</strong>: Each component (core, shell, ligands, impurities, dopants, linkers) gets described using standard InChI (or PInChI/MInChI) for chemical composition, with additional sublayers for morphology (prefix <code>m</code>, e.g., <code>sp</code> for sphere, <code>sh</code> for shell, <code>tu</code> for tube), size (prefix <code>s</code>, in scientific notation in meters), crystal structure (prefix <code>k</code>), and chirality (prefix <code>w</code> for carbon nanotubes). Components are separated by <code>!</code>.</p>
<p><strong>Layer 3 (Arrangement)</strong>: Specified with prefix <code>y</code>, this layer describes how the components from Layer 2 are combined, proceeding from inside out. A core-shell material is written as <code>y2&amp;1</code> where the numbers reference components in Layer 2. Covalent bonding between components is indicated with parentheses, e.g., <code>(1&amp;2&amp;3)</code> for a nano core with a covalently bound ligand coating.</p>
<p>The paper provides concrete worked examples from the case studies:</p>
<ul>
<li><strong>Silica with gold coating</strong> (20 nm silica, 2 nm gold shell):
<code>NInChI=0.00.1A/Au/msh/s2t10r1-9;12r2-9!/O2Si/c1-3-2/msp/s20d-9/k000/y2&amp;1</code></li>
<li><strong>CTAB-capped gold nanoparticle</strong> (20 nm diameter):
<code>NinChI=0.00.1A/Au/msp/s20d-9!C19H42N.BrH/c1-5-6-7.../y1&amp;2</code></li>
<li><strong>Chiral single-wall nanotube</strong> of the (3,1) type with 0.4 nm diameter:
<code>NInChI=0.00.1A/C/mtu/s4d-10/w(3,1)/y1</code></li>
</ul>
<p><strong>Property Prioritization</strong>: The case studies produced a prioritization of NM properties into four categories (Table 3 in the paper):</p>
<table>
	<thead>
			<tr>
					<th>Category 1: Must Have</th>
					<th>Category 2a: Nice to Have</th>
					<th>Category 2b: Extrinsic</th>
					<th>Category 3: Out of Scope</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Chemical composition</td>
					<td>Structural defects</td>
					<td>Surface charge</td>
					<td>Optical properties</td>
			</tr>
			<tr>
					<td>Size/size distribution</td>
					<td>Density</td>
					<td>Corona</td>
					<td>Magnetic properties</td>
			</tr>
			<tr>
					<td>Shape</td>
					<td>Surface composition</td>
					<td>Agglomeration state</td>
					<td>Chemical/oxidation state</td>
			</tr>
			<tr>
					<td>Crystal structure</td>
					<td></td>
					<td>Dispersion</td>
					<td></td>
			</tr>
			<tr>
					<td>Chirality</td>
					<td></td>
					<td></td>
					<td></td>
			</tr>
			<tr>
					<td>Ligand and ligand binding</td>
					<td></td>
					<td></td>
					<td></td>
			</tr>
	</tbody>
</table>
<p><strong>Implementation</strong>: The authors built a prototype NInChI generation tool using the ZK framework with a Java backend, available through the <a href="http://enaloscloud.novamechanics.com/nanocommons/NInChI/">Enalos Cloud Platform</a>. The tool lets users specify core composition, morphology, size, crystal structure, and chirality, then build outward by adding shells or clusters. InChIs for shell components are retrieved via the NCI/CADD chemical structure REST API.</p>
<p><strong>Limitations</strong>: The alpha version acknowledges areas for future development: nanocomposite and nanostructured materials, inverse NMs (nano holes in bulk material), and nanoporous materials are beyond current scope. Dynamic properties such as dissolution, agglomeration, and protein corona formation are excluded. The stochastic nature of NMs (e.g., broad size distributions) is not yet fully addressed. Covalent bonding between components needs further refinement.</p>
<p><strong>Impact</strong>: For researchers, NInChI enables precise structural queries for nanomaterials data sharing. For regulators, it provides systematic identification for risk assessment and nanoform classification under frameworks like REACH. For computational modelers, it enables automated descriptor generation and read-across predictions.</p>
<p><strong>Key Conclusions</strong>: The 8-month collaborative process demonstrates that creating systematic notation for nanomaterials is feasible. The hierarchical, inside-out organization provides an approach that satisfies experimentalists, modelers, database owners, and regulators. Testing against six case studies identified the essential features that must be captured. By extending InChI and reusing conventions from MInChI, RInChI, and PInChI, the work builds on existing infrastructure. The proposed NInChI alpha is intended to stimulate further analysis and refinement with the broader community and the InChI Trust.</p>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<ul>
<li><strong>Paper Accessibility</strong>: The paper is fully open-access under the CC BY 4.0 license, allowing for straightforward reading and analysis.</li>
<li><strong>Tools &amp; Code</strong>: The authors provided a prototype NInChI generation tool available through the <a href="http://enaloscloud.novamechanics.com/nanocommons/NInChI/">Enalos Cloud Platform</a>, built using the ZK framework with a Java backend. The underlying backend code was not released as an open-source library.</li>
<li><strong>Documentation</strong>: The paper serves as the first alpha specification for community discussion and refinement. No formal algorithmic pseudocode for automated string parsing or generation from structured nanomaterials files (like <code>.cif</code>) is provided.</li>
</ul>
<table>
	<thead>
			<tr>
					<th>Artifact</th>
					<th>Type</th>
					<th>License</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><a href="http://enaloscloud.novamechanics.com/nanocommons/NInChI/">NInChI Generator (Enalos Cloud)</a></td>
					<td>Other</td>
					<td>Unknown</td>
					<td>Prototype web tool for generating NInChI strings; backend not open-source</td>
			</tr>
			<tr>
					<td><a href="https://www.mdpi.com/2079-4991/10/12/2493">Paper (MDPI)</a></td>
					<td>Other</td>
					<td>CC BY 4.0</td>
					<td>Open-access alpha specification</td>
			</tr>
	</tbody>
</table>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Lynch, I., Afantitis, A., Exner, T., Himly, M., Lobaskin, V., Doganis, P., &hellip; &amp; Melagraki, G. (2020). Can an InChI for Nano Address the Need for a Simplified Representation of Complex Nanomaterials across Experimental and Nanoinformatics Studies? <em>Nanomaterials</em>, <em>10</em>(12), 2493. <a href="https://doi.org/10.3390/nano10122493">https://doi.org/10.3390/nano10122493</a></p>
<p><strong>Publication</strong>: Nanomaterials (2020)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{lynch2020inchi,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Can an InChI for Nano Address the Need for a Simplified Representation of Complex Nanomaterials across Experimental and Nanoinformatics Studies?}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Lynch, Iseult and Afantitis, Antreas and Exner, Thomas and others}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{Nanomaterials}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{10}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span>=<span style="color:#e6db74">{12}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{2493}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2020}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{MDPI}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.3390/nano10122493}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>Modernizing Rahman's 1964 Argon Simulation</title><link>https://hunterheidenreich.com/posts/rahman-1964-lammps-liquid-argon/</link><pubDate>Sat, 23 Aug 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/posts/rahman-1964-lammps-liquid-argon/</guid><description>How I used modern software engineering (caching, vectorization, and dependency locking) to reproduce a 60-year-old physics milestone.</description><content:encoded><![CDATA[<p>Some papers invent entire fields. Aneesur Rahman&rsquo;s 1964 paper, <strong>&ldquo;Correlations in the Motion of Atoms in Liquid Argon&rdquo;</strong>, is the &ldquo;Hello World&rdquo; of molecular dynamics (MD). Using a computer with less memory than a modern microwave, Rahman solved Newton&rsquo;s equations for 864 atoms and proved that liquids have distinct, quantifiable structure.</p>
<p>The physics of liquid argon is a solved problem. We know the answer.</p>
<p>So, why replicate it in 2025? <strong>To apply modern engineering standards to legacy science.</strong></p>
<p>This project served as an exercise in <strong>software archaeology</strong>: taking a vintage scientific workflow and rebuilding it with a modular Python analysis pipeline. I wanted to see if I could replace Rahman&rsquo;s &ldquo;write-once&rdquo; Fortran mentality with modern reproducibility, type safety, and intelligent caching.</p>
<p>The full source code is available on <a href="https://github.com/hunter-heidenreich/argon-simulation">GitHub</a>. The complete project overview, including analysis results and pipeline architecture, is on the <a href="/projects/rahman-1964-replication/">Rahman 1964 Replication project page</a>.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
			<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/KjFixUt6bnQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
		</div>

<hr>
<h2 id="engineering-the-pipeline">Engineering the Pipeline</h2>
<p>The most interesting part of this project isn&rsquo;t the simulation engine (LAMMPS handles that); it&rsquo;s the architecture of the analysis suite. MD analysis is computationally expensive ($O(N^2)$), and iterating on plots can be painfully slow if you re-compute trajectory data every time.</p>
<p>Why bother? Don&rsquo;t modern MD packages come with analysis tools?
Well, some say that writing is thinking.
Sometimes getting into the weeds of how an algorithm works or an analysis is performed, you gain insights and a deeper understanding that might be obscured by a plug-and-play tool.</p>
<h3 id="intelligent-caching">Intelligent Caching</h3>
<p>I built the <code>argon_sim</code> package with a decorator-based caching layer. The system hashes the source file&rsquo;s modification time and the function&rsquo;s arguments to avoid re-calculating the Radial Distribution Function (RDF) or Van Hove correlations on every script run.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#a6e22e">@cached_computation</span>(<span style="color:#e6db74">&#34;gr&#34;</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">compute_radial_distribution</span>(filename: str, dr: float <span style="color:#f92672">=</span> <span style="color:#ae81ff">0.05</span>):
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># ... expensive O(N^2) distance calculations ...</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> r_values, g_r, density
</span></span></code></pre></div><p>If I tweak a plot axis, the script runs instantly, loading pre-computed arrays from disk instead of re-running the $O(N^2)$ computation. If I change the simulation trajectory, the cache invalidates automatically.</p>
<h3 id="vectorization--memory-management">Vectorization &amp; Memory Management</h3>
<p>Rahman likely relied on nested loops. Python is too slow for that. I utilized <strong>NumPy broadcasting</strong> to vectorize the calculation of atomic displacements.</p>
<p>However, calculating an $864 \times 864$ distance matrix for 5,000 frames consumes significant RAM. I implemented a <strong>chunked MSD (Mean Square Displacement) algorithm</strong> that processes the trajectory in blocks, balancing vectorization speed with memory constraints. The chunking trades some vectorization speed for a bounded memory footprint, so the analysis is not capped by holding the full distance matrix in RAM.</p>
<h3 id="reproducibility-as-a-feature">Reproducibility as a Feature</h3>
<p>Academic code is notorious for &ldquo;it works on my machine.&rdquo; To combat this, I used <strong><code>uv</code></strong> for dependency management, locking the exact environment state. The entire workflow (from simulation to final figure generation) is abstracted into a <code>Makefile</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># One command to run the physics, analyze data, and generate plots</span>
</span></span><span style="display:flex;"><span>make workflow
</span></span></code></pre></div><hr>
<h2 id="the-simulation-1964-vs-2025">The Simulation: 1964 vs. 2025</h2>
<p>I preserved Rahman&rsquo;s physical parameters exactly to ensure a fair comparison:</p>
<ul>
<li><strong>System</strong>: 864 Argon atoms</li>
<li><strong>Potential</strong>: Lennard-Jones ($\sigma = 3.4$ Å, $\epsilon/k_B = 120$ K)</li>
<li><strong>Target</strong>: 94.4 K, 1.374 g/cm³</li>
</ul>
<p>However, I modernized the <em>numerical</em> methods to ensure stability:</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Feature</th>
					<th style="text-align: left">Rahman (1964)</th>
					<th style="text-align: left">This Work (2025)</th>
					<th style="text-align: left">Why it Matters</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><strong>Integration</strong></td>
					<td style="text-align: left">Predictor-Corrector</td>
					<td style="text-align: left">Velocity Verlet</td>
					<td style="text-align: left">Better energy conservation over long runs</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Timestep</strong></td>
					<td style="text-align: left">10 fs</td>
					<td style="text-align: left">2 fs</td>
					<td style="text-align: left">Rahman&rsquo;s step was aggressive; 2 fs ensures numerical stability</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Equilibration</strong></td>
					<td style="text-align: left">Velocity Scaling</td>
					<td style="text-align: left">1 ns NVT</td>
					<td style="text-align: left">Rahman couldn&rsquo;t afford long equilibrations; I melted the crystal properly to remove bias</td>
			</tr>
	</tbody>
</table>
<p>The production run lasted 10 ps in the NVE ensemble, generating 5,001 frames. Temperature remained within 1% of target with an RMS fluctuation of 0.0165.</p>
<hr>
<h2 id="validation-results">Validation Results</h2>
<p>The replication was quantitatively successful. The analysis pipeline faithfully reproduced every key signature of liquid argon.</p>
<h3 id="the-cage-effect">The Cage Effect</h3>
<p>This is the paper&rsquo;s crown jewel. In a gas, velocity correlations decay exponentially. In a liquid, Rahman discovered that atoms get trapped by their neighbors and bounce back, causing the correlation to go <em>negative</em>.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-velocity-autocorrelation.webp"
         alt="Velocity Autocorrelation Function"
         title="Velocity Autocorrelation Function"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">The VACF dips below zero at 0.3 ps. This &rsquo;negative correlation&rsquo; is the signature of the cage effect: atoms rattling against their neighbors.</figcaption>
    
</figure>

<p>My simulation captures this minimum at -0.083, matching Rahman&rsquo;s observation. The Fourier transform of this data (the frequency spectrum) reveals a peak at $\beta \approx 0.25$, physically representing the frequency of atomic collisions within the cage.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-vacf-frequency-spectrum.webp"
         alt="Frequency spectrum of the VACF showing characteristic peak from atomic caging effects"
         title="Frequency spectrum of the VACF showing characteristic peak from atomic caging effects"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Frequency spectrum of the VACF showing characteristic peak from atomic caging effects</figcaption>
    
</figure>

<h3 id="structural-fingerprints">Structural Fingerprints</h3>
<p>The Radial Distribution Function $g(r)$ and its Fourier transform, the Structure Factor $S(k)$, are the &ldquo;fingerprints&rdquo; of a liquid&rsquo;s structure.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-radial-distribution-function.webp"
         alt="Radial Distribution Function and Structure Factor"
         title="Radial Distribution Function and Structure Factor"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">The sharp first peak (3.82 Å) shows defined nearest neighbors, while the decay shows the lack of long-range order. My calculated peaks match Rahman&rsquo;s within 3%.</figcaption>
    
</figure>

<p>The agreement here is striking. My first peak appeared at <strong>3.82 Å</strong> (Rahman: 3.7 Å). The slight discrepancy is likely due to my improved equilibration method, which allowed the system to relax into a more natural liquid state than Rahman&rsquo;s 1960s hardware allowed.</p>
<h3 id="diffusion-and-non-gaussian-behavior">Diffusion and Non-Gaussian Behavior</h3>
<p>By calculating the Mean Square Displacement (MSD), I derived a diffusion coefficient of <strong>$D = 2.47 \times 10^{-5}$ cm²/s</strong>, which deviates only <strong>2%</strong> from Rahman&rsquo;s reported $2.43 \times 10^{-5}$.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-mean-square-displacement.webp"
         alt="Mean Square Displacement vs time showing ballistic to diffusive transition"
         title="Mean Square Displacement vs time showing ballistic to diffusive transition"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Mean Square Displacement vs. time showing ballistic to diffusive transition</figcaption>
    
</figure>

<p>More interestingly, I reproduced the &ldquo;Non-Gaussian&rdquo; parameters. Standard diffusion assumes a Gaussian distribution of displacements. Rahman found (and I confirmed) that liquid atoms deviate from this. They exhibit &ldquo;jump&rdquo; and &ldquo;wait&rdquo; dynamics, a behavior that standard Brownian motion models fail to capture.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-non-gaussian-parameters.webp"
         alt="Non-Gaussian parameters showing deviation from simple diffusive behavior"
         title="Non-Gaussian parameters showing deviation from simple diffusive behavior"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Evidence that atoms do not follow a simple random walk. The non-zero alpha parameters indicate heterogeneous dynamics.</figcaption>
    
</figure>

<h3 id="advanced-analysis-van-hove-functions">Advanced Analysis: Van Hove Functions</h3>
<p>Rahman also explored advanced properties like the Van Hove correlation function $G(r,t)$, which describes how liquid structure evolves over time.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-van-hove-correlation.webp"
         alt="Van Hove distinct correlation function G_d(r,t) at two time points"
         title="Van Hove distinct correlation function G_d(r,t) at two time points"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Van Hove distinct correlation function showing how neighbor coordination shells &lsquo;melt&rsquo; as time progresses</figcaption>
    
</figure>

<p>At 1.0 ps, the structure remains well-defined with clear shells. By 2.5 ps, it becomes increasingly diffuse. Rahman compared this evolution to theoretical predictions (the Vineyard approximation) and found that theory predicted overly rapid structural decay. My results confirm this finding.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-delayed-convolution.webp"
         alt="Delayed convolution approximation testing Rahman&#39;s theoretical improvement"
         title="Delayed convolution approximation testing Rahman&#39;s theoretical improvement"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Testing Rahman&rsquo;s &lsquo;delayed convolution approximation&rsquo; (his proposed improvement over existing theory)</figcaption>
    
</figure>

<hr>
<h2 id="system-validation">System Validation</h2>
<p>Before analyzing physics, basic sanity checks confirmed proper thermal equilibrium.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-temperature-stability.webp"
         alt="Temperature vs time plot showing excellent temperature control around 94.4 K target"
         title="Temperature vs time plot showing excellent temperature control around 94.4 K target"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Temperature vs. Time - 5001 frames showing excellent temperature control with mean 94.73 K</figcaption>
    
</figure>

<p>Mean temperature was 94.73 K (0.33 K off target) with a standard deviation of 1.56 K.</p>















<figure class="post-figure center ">
    <img src="/img/rahman-1964-argon-molecular-dynamics/rahman-argon-maxwell-boltzmann-velocity.webp"
         alt="Maxwell-Boltzmann velocity distribution"
         title="Maxwell-Boltzmann velocity distribution"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Maxwell-Boltzmann velocity distribution from 12.9 million velocity components</figcaption>
    
</figure>

<p>The velocity distribution from 12.9 million velocity components produces a clean Maxwell-Boltzmann distribution, as expected for thermal equilibrium. The distribution widths at various heights closely match Rahman&rsquo;s results: 1.77, 2.48, and 3.56 compared to his 1.77, 2.52, and 3.52.</p>
<hr>
<h2 id="conclusion">Conclusion</h2>
<p>Replicating a 60-year-old paper might seem like a solved puzzle, but it teaches a valuable lesson in computational science. Rahman relied on brilliance and raw mathematical intuition because he lacked compute power. Today, pairing modern compute with disciplined software practices makes the same result reproducible and auditable.</p>
<p>Applying modern software engineering (<strong>modular architecture, caching, and automated workflows</strong>) to classical physics reproduces the past and builds a foundation that makes the <em>next</em> discovery easier, faster, and more reliable.</p>
<p>The quantitative agreement is striking: diffusion coefficients within 2%, structural peaks within 0.1 Å, velocity distributions matching to three significant figures. This level of reproducibility, achieved with completely different hardware and software, validates something fundamental: Rahman&rsquo;s physical model was remarkably sound, and his computational methodology was scientifically rigorous despite 1960s constraints.</p>
<p>The cage effect, velocity correlations, and structural evolution are fundamental characteristics of how matter behaves at the atomic scale, as relevant today as they were six decades ago.</p>
]]></content:encoded></item><item><title>Liquid Argon: LAMMPS Simulation</title><link>https://hunterheidenreich.com/videos/liquid-argon-lammps-simulation/</link><pubDate>Sat, 23 Aug 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/videos/liquid-argon-lammps-simulation/</guid><description>LAMMPS molecular dynamics simulation of liquid argon demonstrating fundamental liquid-state behavior and molecular motion.</description><content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
			<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/KjFixUt6bnQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
		</div>

<p>Details on the simulation can be found in the <a href="/posts/rahman-1964-lammps-liquid-argon/">Liquid Argon: LAMMPS Simulation</a> post.</p>
]]></content:encoded></item><item><title>eSEN: Smooth Interatomic Potentials (ICML Spotlight)</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/learning-smooth-interatomic-potentials/</link><pubDate>Sat, 23 Aug 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/ml-potentials/learning-smooth-interatomic-potentials/</guid><description>Fu et al. propose energy conservation as a key MLIP diagnostic and introduce eSEN, bridging test accuracy and real performance.</description><content:encoded><![CDATA[<h2 id="paper-overview">Paper Overview</h2>
<p>This is a <strong>method paper</strong>. It addresses a critical disconnect in the evaluation of Machine Learning Interatomic Potentials (MLIPs) and introduces a novel architecture, <strong>eSEN</strong>, designed based on insights from this analysis. The paper proposes a new standard for evaluating MLIPs beyond simple test-set errors.</p>
<h2 id="the-energy-conservation-gap-in-mlip-evaluation">The Energy Conservation Gap in MLIP Evaluation</h2>
<p>The motivation addresses a well-known but under-addressed problem in the field: improvements in standard MLIP metrics (lower energy/force MAE on static test sets) do not reliably translate to better performance on complex downstream tasks like molecular dynamics (MD) simulations, materials stability prediction, or phonon calculations. The authors seek to understand why this gap exists and how to design models that are both accurate on test sets and physically reliable in practical scientific workflows.</p>
<h2 id="the-esen-architecture-and-continuous-representation">The eSEN Architecture and Continuous Representation</h2>
<p>The novelty is twofold, spanning both a conceptual framework for evaluation and a new model architecture:</p>
<ol>
<li>
<p><strong>Energy Conservation as a Diagnostic Test</strong>: The core conceptual contribution is using an MLIP&rsquo;s ability to conserve energy in out-of-distribution MD simulations as a crucial diagnostic test. The authors demonstrate that for models passing this test, a strong correlation between test-set error and downstream task performance is restored.</p>
</li>
<li>
<p><strong>The eSEN Architecture</strong>: The paper introduces the <strong>equivariant Smooth Energy Network (eSEN)</strong>, designed with specific choices to ensure a smooth and well-behaved Potential Energy Surface (PES):</p>
<ul>
<li><strong>Strictly Conservative Forces</strong>: Forces are computed exclusively as the negative gradient of energy ($F = -\nabla E$), using conservative force prediction instead of faster direct-force prediction heads.</li>
<li><strong>Continuous Representations</strong>: Maintains strict equivariance and smoothness by using equivariant gated non-linearities instead of discretizing spherical harmonic representations during nodewise processing.</li>
<li><strong>Smooth PES Construction</strong>: Critical design choices include using distance cutoffs, polynomial envelope functions ensuring derivatives go to zero at cutoffs, and limited radial basis functions to avoid overly sensitive PES.</li>
</ul>
</li>
<li>
<p><strong>Efficient Training Strategy</strong>: A two-stage training regimen with fast pre-training using a non-conservative direct-force model, followed by fine-tuning to enforce energy conservation. This captures the efficiency of direct-force training while ensuring physical robustness.</p>
</li>
</ol>
<h2 id="evaluating-ood-energy-conservation-and-physical-properties">Evaluating OOD Energy Conservation and Physical Properties</h2>
<p>The paper presents a comprehensive experimental validation:</p>
<ol>
<li>
<p><strong>Ablation Studies on Energy Conservation</strong>: MD simulations on out-of-distribution systems (TM23 and MD22 datasets) systematically tested key design choices (direct-force vs. conservative, representation discretization, neighbor limits, envelope functions). This empirically demonstrated which choices lead to energy drift despite negligible impact on test-set MAE.</p>
</li>
<li>
<p><strong>Physical Property Prediction Benchmarks</strong>: The eSEN model was evaluated on challenging downstream tasks:</p>
<ul>
<li><strong>Matbench-Discovery</strong>: Materials stability and thermal conductivity prediction, where eSEN achieved the highest F1 score among compliant models and excelled at both metrics simultaneously.</li>
<li><strong>MDR Phonon Benchmark</strong>: Predicting phonon properties that test accurate second and third-order derivatives of the PES. eSEN achieved state-of-the-art results, particularly outperforming direct-force models.</li>
<li><strong>SPICE-MACE-OFF</strong>: Standard energy and force prediction on organic molecules, demonstrating that physical plausibility design choices enhanced raw accuracy.</li>
</ul>
</li>
<li>
<p><strong>Correlation Analysis</strong>: Explicit plots of test-set energy MAE versus performance on downstream benchmarks showed weak overall correlation that becomes strong and predictive when restricted to models passing the energy conservation test.</p>
</li>
</ol>
<h2 id="outcomes-and-conclusions">Outcomes and Conclusions</h2>
<ul>
<li>
<p><strong>Primary Conclusion</strong>: Energy conservation is a critical, practical property for MLIPs. Using it as a filter re-establishes test-set error as a reliable proxy for model development, dramatically accelerating the innovation cycle. Models that are not conservative, even with low test error, are unreliable for many critical scientific applications.</p>
</li>
<li>
<p><strong>Model Performance</strong>: The eSEN architecture outperforms base models across diverse tasks, from energy/force prediction to geometry optimization, phonon calculations, and thermal conductivity prediction.</p>
</li>
<li>
<p><strong>Actionable Design Principles</strong>: The paper provides experimentally-validated architectural choices that promote physical plausibility. Seemingly minor details, like how atomic neighbors are selected, can have profound impacts on a model&rsquo;s utility in simulations.</p>
</li>
<li>
<p><strong>Efficient Path to Robust Models</strong>: The direct-force pre-training plus conservative fine-tuning strategy offers a practical method for developing physically robust models without incurring the full computational cost of conservative training from scratch.</p>
</li>
</ul>
<hr>
<h2 id="reproducibility">Reproducibility</h2>
<h3 id="artifacts">Artifacts</h3>
<table>
	<thead>
			<tr>
					<th>Artifact</th>
					<th>Type</th>
					<th>License</th>
					<th>Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><a href="https://github.com/facebookresearch/fairchem">fairchem (GitHub)</a></td>
					<td>Code</td>
					<td>MIT</td>
					<td>Official implementation within FAIR Chemistry framework</td>
			</tr>
			<tr>
					<td><a href="https://huggingface.co/facebook/OMAT24">OMAT24 (Hugging Face)</a></td>
					<td>Model</td>
					<td>FAIR Acceptable Use Policy</td>
					<td>Pre-trained eSEN-30M-MP and eSEN-30M-OAM checkpoints</td>
			</tr>
			<tr>
					<td><a href="https://openreview.net/forum?id=R0PBjxIbgm">OpenReview</a></td>
					<td>Paper</td>
					<td>CC BY 4.0</td>
					<td>ICML 2025 camera-ready paper</td>
			</tr>
	</tbody>
</table>
<h3 id="models">Models</h3>
<p>The eSEN architecture builds on components from <strong>eSCN</strong> (Equivariant Spherical Channel Network) and <strong>Equiformer</strong>, combining them with design choices that prioritize smoothness and energy conservation. The implementation integrates into the standard <code>fairchem</code> Open Catalyst experimental framework.</p>
<h4 id="layer-structure">Layer Structure</h4>
<ul>
<li><strong>Edgewise Convolution</strong>: Uses <code>SO2</code> convolution layers (from eSCN) with an envelope function applied. Source and target embeddings are concatenated before convolution.</li>
<li><strong>Nodewise Feed-Forward</strong>: Two equivariant linear layers with an intermediate <strong>SiLU-based gated non-linearity</strong> (from Equiformer).</li>
<li><strong>Normalization</strong>: Equivariant Layer Normalization (from Equiformer).</li>
</ul>
<h4 id="smoothness-design-choices">Smoothness Design Choices</h4>
<p>Several architectural decisions distinguish eSEN from prior work:</p>
<ul>
<li><strong>No Grid Projection</strong>: eSEN performs operations directly in the spherical harmonic space to maintain equivariance and energy conservation, bypassing the projection of spherical harmonics to spatial grids for non-linearity.</li>
<li><strong>Distance Cutoff for Graph Construction</strong>: Uses a strict distance cutoff (6 Å for MPTrj models, 5 Å for SPICE models). Neighbor limits introduce discontinuities that break energy conservation.</li>
<li><strong>Polynomial Envelope Functions</strong>: Ensures derivatives go to zero smoothly at the cutoff radius.</li>
</ul>
<h3 id="algorithms">Algorithms</h3>
<h4 id="two-stage-training-esen-30m-mp">Two-Stage Training (eSEN-30M-MP)</h4>
<ol>
<li><strong>Direct-Force Pre-training</strong> (60 epochs): Uses <strong>DeNS</strong> (Denoising Non-equilibrium Structures) to reduce overfitting. This stage is fast because it does not require backpropagation through energy gradients.</li>
<li><strong>Conservative Fine-tuning</strong> (40 epochs): The direct-force head is removed, and forces are calculated via gradients ($F = -\nabla E$). This enforces energy conservation.</li>
</ol>
<p><strong>Important</strong>: DeNS is used exclusively during the direct-force pre-training stage, with a noising probability of 0.5, a standard deviation of 0.1 Å for the added Gaussian noise, and a DeNS loss coefficient of 10. The fine-tuning strategy reduces the wall-clock time for model training by 40%.</p>
<h4 id="optimization">Optimization</h4>
<ul>
<li><strong>Optimizer</strong>: AdamW with cosine learning rate scheduler</li>
<li><strong>Max Learning Rate</strong>: $4 \times 10^{-4}$</li>
<li><strong>Batch Size</strong>: 512 (for MPTrj models)</li>
<li><strong>Weight Decay</strong>: $1 \times 10^{-3}$</li>
<li><strong>Gradient Clipping</strong>: Norm of 100</li>
<li><strong>Warmup</strong>: 0.1 epochs with a factor of 0.2</li>
</ul>
<h4 id="loss-function">Loss Function</h4>
<p>A composite loss combining per-atom energy MAE, force $L_2$ loss, and stress MAE:</p>
<p>$$
\begin{aligned}
\mathcal{L} = \lambda_{\text{e}} \frac{1}{N} \sum_{i=1}^N \lvert E_{i} - \hat{E}_{i} \rvert + \lambda_{\text{f}} \frac{1}{3N} \sum_{i=1}^N \lVert \mathbf{F}_{i} - \hat{\mathbf{F}}_{i} \rVert_2^2 + \lambda_{\text{s}} \lVert \mathbf{S} - \hat{\mathbf{S}} \rVert_1
\end{aligned}
$$</p>
<p>For MPTrj-30M, the weighting coefficients are set to $\lambda_{\text{e}} = 20$, $\lambda_{\text{f}} = 20$, and $\lambda_{\text{s}} = 5$.</p>
<h3 id="data">Data</h3>
<h4 id="training-data">Training Data</h4>
<ul>
<li><strong>Inorganic</strong>: MPTrj (Materials Project Trajectory) dataset</li>
<li><strong>Organic</strong>: SPICE-MACE-OFF dataset</li>
</ul>
<h4 id="test-data-construction">Test Data Construction</h4>
<ul>
<li><strong>MPTrj Testing</strong>: Since MPTrj lacks an official test split, the authors created a test set using 5,000 random samples from the <strong>subsampled Alexandria (sAlex)</strong> dataset to ensure fair comparison.</li>
<li><strong>Out-of-Distribution Conservation Testing</strong>:
<ul>
<li><em>Inorganic</em>: <strong>TM23</strong> dataset (transition metal defects). Simulation: 100 ps, 5 fs timestep.</li>
<li><em>Organic</em>: <strong>MD22</strong> dataset (large molecules). Simulation: 100 ps, 1 fs timestep.</li>
</ul>
</li>
</ul>
<h3 id="hardware">Hardware</h3>
<p>Compute for training operations predominantly utilizes <strong>80GB NVIDIA A100 GPUs</strong>.</p>
<h4 id="inference-efficiency">Inference Efficiency</h4>
<p>For a periodic system of <strong>216 atoms</strong> on a single A100 (PyTorch 2.4.0, CUDA 12.1, no compile/torchscript), the 2-layer eSEN models achieve approximately <strong>0.4 million steps per day</strong> (3.2M parameters) and <strong>0.8 million steps per day</strong> (6.5M parameters), comparable to MACE-OFF-L at 0.7 million steps per day.</p>
<h3 id="evaluation">Evaluation</h3>
<p>The paper evaluated eSEN across three major benchmark tasks. Key evaluation metrics included energy MAE (meV/atom), force MAE (meV/Å), stress MAE (meV/Å/atom), F1 score for stability prediction, $\kappa_{\text{SRME}}$ for thermal conductivity, and phonon frequency accuracy.</p>
<h4 id="ablation-test-set-mae-table-1">Ablation Test-Set MAE (Table 1)</h4>
<p>Design choices that dramatically affect energy conservation have negligible impact on static test-set MAE, which is precisely why test-set error alone is misleading. All models are 2-layer with 3.2M parameters, $L_{\text{max}} = 2$, $M_{\text{max}} = 2$:</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>Energy MAE</th>
					<th>Force MAE</th>
					<th>Stress MAE</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>eSEN (default)</td>
					<td>17.02</td>
					<td>43.96</td>
					<td>0.14</td>
			</tr>
			<tr>
					<td>eSEN, direct-force</td>
					<td>18.66</td>
					<td>43.62</td>
					<td>0.16</td>
			</tr>
			<tr>
					<td>eSEN, neighbor limit</td>
					<td>17.30</td>
					<td>44.11</td>
					<td>0.14</td>
			</tr>
			<tr>
					<td>eSEN, no envelope</td>
					<td>17.60</td>
					<td>44.69</td>
					<td>0.14</td>
			</tr>
			<tr>
					<td>eSEN, $N_{\text{basis}} = 512$</td>
					<td>19.87</td>
					<td>48.29</td>
					<td>0.15</td>
			</tr>
			<tr>
					<td>eSEN, Bessel</td>
					<td>17.65</td>
					<td>44.83</td>
					<td>0.15</td>
			</tr>
			<tr>
					<td>eSEN, discrete, res=6</td>
					<td>17.05</td>
					<td>43.10</td>
					<td>0.14</td>
			</tr>
			<tr>
					<td>eSEN, discrete, res=10</td>
					<td>17.11</td>
					<td>43.13</td>
					<td>0.14</td>
			</tr>
			<tr>
					<td>eSEN, discrete, res=14</td>
					<td>17.12</td>
					<td>43.09</td>
					<td>0.14</td>
			</tr>
	</tbody>
</table>
<p>Energy MAE in meV/atom. Force MAE in meV/Å. Stress MAE in meV/Å/atom.</p>
<h4 id="matbench-discovery-tables-2-and-3">Matbench-Discovery (Tables 2 and 3)</h4>
<p><strong>Compliant models</strong> (trained only on MPTrj or its subset), unique prototype split:</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>F1</th>
					<th>DAF</th>
					<th>$\kappa_{\text{SRME}}$</th>
					<th>RMSD</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>eSEN-30M-MP</strong></td>
					<td><strong>0.831</strong></td>
					<td><strong>5.260</strong></td>
					<td><strong>0.340</strong></td>
					<td><strong>0.0752</strong></td>
			</tr>
			<tr>
					<td>eqV2-S-DeNS</td>
					<td>0.815</td>
					<td>5.042</td>
					<td>1.676</td>
					<td>0.0757</td>
			</tr>
			<tr>
					<td>MatRIS-MP</td>
					<td>0.809</td>
					<td>5.049</td>
					<td>0.861</td>
					<td>0.0773</td>
			</tr>
			<tr>
					<td>AlphaNet-MP</td>
					<td>0.799</td>
					<td>4.863</td>
					<td>1.31</td>
					<td>0.1067</td>
			</tr>
			<tr>
					<td>DPA3-v2-MP</td>
					<td>0.786</td>
					<td>4.822</td>
					<td>0.959</td>
					<td>0.0823</td>
			</tr>
			<tr>
					<td>ORB v2 MPtrj</td>
					<td>0.765</td>
					<td>4.702</td>
					<td>1.725</td>
					<td>0.1007</td>
			</tr>
			<tr>
					<td>SevenNet-13i5</td>
					<td>0.760</td>
					<td>4.629</td>
					<td>0.550</td>
					<td>0.0847</td>
			</tr>
			<tr>
					<td>GRACE-2L-MPtrj</td>
					<td>0.691</td>
					<td>4.163</td>
					<td>0.525</td>
					<td>0.0897</td>
			</tr>
			<tr>
					<td>MACE-MP-0</td>
					<td>0.669</td>
					<td>3.777</td>
					<td>0.647</td>
					<td>0.0915</td>
			</tr>
			<tr>
					<td>CHGNet</td>
					<td>0.613</td>
					<td>3.361</td>
					<td>1.717</td>
					<td>0.0949</td>
			</tr>
			<tr>
					<td>M3GNet</td>
					<td>0.569</td>
					<td>2.882</td>
					<td>1.412</td>
					<td>0.1117</td>
			</tr>
	</tbody>
</table>
<p>eSEN-30M-MP excels at both F1 and $\kappa_{\text{SRME}}$ simultaneously, while all previous models only achieve SOTA on one or the other.</p>
<p><strong>Non-compliant models</strong> (trained on additional datasets):</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>F1</th>
					<th>$\kappa_{\text{SRME}}$</th>
					<th>RMSD</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>eSEN-30M-OAM</strong></td>
					<td><strong>0.925</strong></td>
					<td><strong>0.170</strong></td>
					<td><strong>0.0608</strong></td>
			</tr>
			<tr>
					<td>eqV2-M-OAM</td>
					<td>0.917</td>
					<td>1.771</td>
					<td>0.0691</td>
			</tr>
			<tr>
					<td>ORB v3</td>
					<td>0.905</td>
					<td>0.210</td>
					<td>0.0750</td>
			</tr>
			<tr>
					<td>SevenNet-MF-ompa</td>
					<td>0.901</td>
					<td>0.317</td>
					<td>0.0639</td>
			</tr>
			<tr>
					<td>DPA3-v2-OpenLAM</td>
					<td>0.890</td>
					<td>0.687</td>
					<td>0.0679</td>
			</tr>
			<tr>
					<td>GRACE-2L-OAM</td>
					<td>0.880</td>
					<td>0.294</td>
					<td>0.0666</td>
			</tr>
			<tr>
					<td>MatterSim-v1-5M</td>
					<td>0.862</td>
					<td>0.574</td>
					<td>0.0733</td>
			</tr>
			<tr>
					<td>MACE-MPA-0</td>
					<td>0.852</td>
					<td>0.412</td>
					<td>0.0731</td>
			</tr>
	</tbody>
</table>
<p>The eSEN-30M-OAM model is pre-trained on the OMat24 dataset, then fine-tuned on the subsampled Alexandria (sAlex) dataset and MPTrj dataset.</p>
<h4 id="mdr-phonon-benchmark-table-4">MDR Phonon Benchmark (Table 4)</h4>
<p>Metrics: maximum phonon frequency MAE($\omega_{\text{max}}$) in K, vibrational entropy MAE($S$) in J/K/mol, Helmholtz free energy MAE($F$) in kJ/mol, heat capacity MAE($C_V$) in J/K/mol.</p>
<table>
	<thead>
			<tr>
					<th>Model</th>
					<th>MAE($\omega_{\text{max}}$)</th>
					<th>MAE($S$)</th>
					<th>MAE($F$)</th>
					<th>MAE($C_V$)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>eSEN-30M-MP</strong></td>
					<td><strong>21</strong></td>
					<td><strong>13</strong></td>
					<td><strong>5</strong></td>
					<td><strong>4</strong></td>
			</tr>
			<tr>
					<td>SevenNet-13i5</td>
					<td>26</td>
					<td>28</td>
					<td>10</td>
					<td>5</td>
			</tr>
			<tr>
					<td>GRACE-2L (r6)</td>
					<td>40</td>
					<td>25</td>
					<td>9</td>
					<td>5</td>
			</tr>
			<tr>
					<td>SevenNet-0</td>
					<td>40</td>
					<td>48</td>
					<td>19</td>
					<td>9</td>
			</tr>
			<tr>
					<td>MACE</td>
					<td>61</td>
					<td>60</td>
					<td>24</td>
					<td>13</td>
			</tr>
			<tr>
					<td>CHGNet</td>
					<td>89</td>
					<td>114</td>
					<td>45</td>
					<td>21</td>
			</tr>
			<tr>
					<td>M3GNet</td>
					<td>98</td>
					<td>150</td>
					<td>56</td>
					<td>22</td>
			</tr>
	</tbody>
</table>
<p>Direct-force models show dramatically worse performance at the standard 0.01 Å displacement (e.g., eqV2-S-DeNS: 280/224/54/94) but improve at larger displacements (0.2 Å: 58/26/8/8), revealing that their PES is rough near energy minima.</p>
<h4 id="spice-mace-off-table-5">SPICE-MACE-OFF (Table 5)</h4>
<p>Test set MAE for organic molecule energy/force prediction. Energy MAE in meV/atom, force MAE in meV/Å:</p>
<table>
	<thead>
			<tr>
					<th>Dataset</th>
					<th>MACE-4.7M (E/F)</th>
					<th>EscAIP-45M* (E/F)</th>
					<th>eSEN-3.2M (E/F)</th>
					<th>eSEN-6.5M (E/F)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>PubChem</td>
					<td>0.88 / 14.75</td>
					<td>0.53 / 5.86</td>
					<td>0.22 / 6.10</td>
					<td><strong>0.15</strong> / <strong>4.21</strong></td>
			</tr>
			<tr>
					<td>DES370K M.</td>
					<td>0.59 / 6.58</td>
					<td>0.41 / 3.48</td>
					<td>0.17 / 1.85</td>
					<td><strong>0.13</strong> / <strong>1.24</strong></td>
			</tr>
			<tr>
					<td>DES370K D.</td>
					<td>0.54 / 6.62</td>
					<td>0.38 / 2.18</td>
					<td>0.20 / 2.77</td>
					<td><strong>0.15</strong> / <strong>2.12</strong></td>
			</tr>
			<tr>
					<td>Dipeptides</td>
					<td>0.42 / 10.19</td>
					<td>0.31 / 5.21</td>
					<td>0.10 / 3.04</td>
					<td><strong>0.07</strong> / <strong>2.00</strong></td>
			</tr>
			<tr>
					<td>Sol. AA</td>
					<td>0.98 / 19.43</td>
					<td>0.61 / 11.52</td>
					<td>0.30 / 5.76</td>
					<td><strong>0.25</strong> / <strong>3.68</strong></td>
			</tr>
			<tr>
					<td>Water</td>
					<td>0.83 / 13.57</td>
					<td>0.72 / 10.31</td>
					<td>0.24 / 3.88</td>
					<td><strong>0.15</strong> / <strong>2.50</strong></td>
			</tr>
			<tr>
					<td>QMugs</td>
					<td>0.45 / 16.93</td>
					<td>0.41 / 8.74</td>
					<td>0.16 / 5.70</td>
					<td><strong>0.12</strong> / <strong>3.78</strong></td>
			</tr>
	</tbody>
</table>
<p>*EscAIP-45M is a direct-force model. eSEN-6.5M outperforms MACE-OFF-L and EscAIP on all test splits. The smaller eSEN-3.2M has inference efficiency comparable to MACE-4.7M while achieving lower MAE.</p>
<hr>
<h2 id="why-these-design-choices-matter">Why These Design Choices Matter</h2>
<h3 id="bounded-energy-derivatives-and-the-verlet-integrator">Bounded Energy Derivatives and the Verlet Integrator</h3>
<p>The theoretical foundation for why smoothness matters comes from Theorem 5.1 of Hairer et al. (2003). For the Verlet integrator (the standard NVE integrator), the total energy drift satisfies:</p>
<p>$$
|E(\mathbf{r}_T, \mathbf{a}) - E(\mathbf{r}_0, \mathbf{a})| \leq C \Delta t^2 + C_N \Delta t^N T
$$</p>
<p>where $T$ is the total simulation time ($T \leq \Delta t^{-N}$), $N$ is the highest order for which the $N$th derivative of $E$ is continuously differentiable with bounded derivative, and $C$, $C_N$ are constants independent of $T$ and $\Delta t$. The first term is a time-independent fluctuation of $O(\Delta t^2)$; the second term governs long-term conservation. This means the PES must be continuously differentiable to high order, with bounded derivatives, for energy conservation in long-time simulations.</p>
<h3 id="architectural-choices-that-break-conservation">Architectural Choices That Break Conservation</h3>
<p>The authors provide theoretical justification for why specific architectural choices break energy conservation:</p>
<ul>
<li><strong>Max Neighbor Limit (KNN)</strong>: Introduces discontinuity in the PES. If a neighbor at distance $r$ moves to $r + \epsilon$ and drops out of the top-$K$, the energy changes discontinuously.</li>
<li><strong>Grid Discretization</strong>: Projecting spherical harmonics to a spatial grid introduces discretization errors in energy gradients that break conservation. This can be mitigated with higher-resolution grids but not eliminated.</li>
<li><strong>Direct-Force Prediction</strong>: Imposes no mathematical constraint that forces must be the gradient of an energy scalar field. In other words, $\nabla \times \mathbf{F} \neq 0$ is permitted, violating the requirement for a conservative force field.</li>
</ul>
<h3 id="displacement-sensitivity-in-phonon-calculations">Displacement Sensitivity in Phonon Calculations</h3>
<p>An important empirical finding concerns how displacement values affect phonon predictions. Conservative models (eSEN, MACE) show convergent phonon band structures as displacement decreases toward zero. In contrast, direct-force models (eqV2-S-DeNS) fail to converge, exhibiting missing acoustic branches and spurious imaginary frequencies at small displacements. While direct-force models achieve competitive thermodynamic property accuracy at large displacements (0.2 Å), this is deceptive: the underlying phonon band structures remain inaccurate, and the apparent accuracy comes from Boltzmann-weighted integrals smoothing over errors.</p>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Fu, X., Wood, B. M., Barroso-Luque, L., Levine, D. S., Gao, M., Dzamba, M., &amp; Zitnick, C. L. (2025). Learning Smooth and Expressive Interatomic Potentials for Physical Property Prediction. <em>Proceedings of the 42nd International Conference on Machine Learning (ICML)</em>, PMLR 267:17875–17893.</p>
<p><strong>Publication</strong>: ICML 2025 (Spotlight)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@inproceedings</span>{fu2025learning,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Learning Smooth and Expressive Interatomic Potentials for Physical Property Prediction}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Fu, Xiang and Wood, Brandon M. and Barroso-Luque, Luis and Levine, Daniel S. and Gao, Meng and Dzamba, Misko and Zitnick, C. Lawrence}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">booktitle</span>=<span style="color:#e6db74">{Proceedings of the 42nd International Conference on Machine Learning}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">series</span>=<span style="color:#e6db74">{Proceedings of Machine Learning Research}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{267}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{17875--17893}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{PMLR}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{2025}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Additional Resources</strong>:</p>
<ul>
<li><a href="https://icml.cc/virtual/2025/poster/45302">ICML 2025 poster page</a></li>
<li><a href="https://openreview.net/forum?id=R0PBjxIbgm">OpenReview forum</a></li>
<li><a href="https://openreview.net/pdf?id=R0PBjxIbgm">PDF on OpenReview</a></li>
<li><a href="https://huggingface.co/facebook/OMAT24">OMAT24 model on Hugging Face</a></li>
<li><a href="https://github.com/facebookresearch/fairchem">Code on GitHub (fairchem)</a></li>
</ul>
]]></content:encoded></item><item><title>Embedded-Atom Method: Impurities and Defects in Metals</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method/</link><pubDate>Fri, 22 Aug 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method/</guid><description>Daw and Baskes's foundational 1984 paper introducing the Embedded-Atom Method (EAM), a many-body potential for metal simulations.</description><content:encoded><![CDATA[<h2 id="contribution-adaptive-many-body-potentials">Contribution: Adaptive Many-Body Potentials</h2>
<p>This is a foundational <strong>method paper</strong> that introduces a new class of semi-empirical, many-body interatomic potential: the <strong>Embedded-Atom Method (EAM)</strong>. It is designed for large-scale atomistic simulations of metallic systems, bridging the gap between computationally cheap (but physically limited) pair potentials and accurate (but expensive) quantum mechanical methods. The EAM achieves pair-potential speed while incorporating many-body physics inspired by density functional theory.</p>
<h2 id="motivation-the-geometric-limits-of-pair-potentials">Motivation: The Geometric Limits of Pair Potentials</h2>
<p>The authors sought to overcome the limitations of <strong>pair potentials</strong> (the dominant method of the time), which failed in three key areas:</p>
<ul>
<li><strong>Elastic Anisotropy:</strong> Pair potentials enforce the Cauchy relation ($C_{12} = C_{44}$), which is violated by most transition metals.</li>
<li><strong>Volume Ambiguity:</strong> Pair potentials require a volume-dependent energy term, making them impossible to use accurately on surfaces or cracks where local volume is undefined.</li>
<li><strong>Chemical Incompatibility:</strong> Pair potentials cannot model chemically active impurities like Hydrogen.</li>
</ul>
<p>First-principles quantum mechanical methods (e.g., band theory) are limited by basis-set size and periodicity requirements, making them impractical for the large systems (thousands of atoms) needed to study defects, surfaces, and mechanical properties.</p>
<p>The goal was to create a new model that bridges this gap in accuracy and computational cost.</p>
<h2 id="core-innovation-the-embedding-energy-function">Core Innovation: The Embedding Energy Function</h2>
<p>The EAM postulates that the energy of an atom is determined by the local electron density of its neighbors. The total energy is:</p>
<p>$$E_{tot} = \sum_{i} F_i(\rho_{h,i}) + \frac{1}{2}\sum_{i \neq j} \phi_{ij}(R_{ij})$$</p>
<ul>
<li><strong>$F_i(\rho_{h,i})$ (Embedding Energy):</strong> The energy required to embed atom $i$ into the background electron density $\rho$ provided by its neighbors. This term is non-linear and captures many-body effects.</li>
<li><strong>$\phi_{ij}$ (Pair Potential):</strong> A short-range electrostatic repulsion between cores.</li>
<li><strong>$\rho_{h,i}$ (Host Density):</strong> Approximated as a linear superposition of atomic densities: $\rho_{h,i} = \sum_{j \neq i} \rho^a_j(R_{ij})$.</li>
</ul>
<p>The key innovations are:</p>
<ol>
<li><strong>The Embedding Energy</strong>: Each atom $i$ contributes an energy $F_i$ which is a non-linear function of the local electron density $\rho_{h,i}$ it is embedded in. This density is approximated as a simple linear superposition of the atomic electron densities of all its neighbors. This term captures the crucial many-body effects of metallic bonding.</li>
<li><strong>A Redefined Pair Potential</strong>: A short-range, two-body potential $\phi_{ij}$ is retained, but it primarily models the electrostatic core-core repulsion.</li>
<li><strong>Elimination of the &ldquo;Volume&rdquo; Problem</strong>: Because the embedding energy depends on the local electron density (a quantity that is always well-defined, even at a surface or a crack tip), the method circumvents the ambiguities of volume-dependent pair potentials.</li>
<li><strong>Intrinsic Many-Body Nature</strong>: The non-linearity of the embedding function $F(\rho)$ naturally accounts for why chemically active impurities (like hydrogen) cannot be described by pair potentials and correctly breaks the Cauchy relation for elastic constants.</li>
</ol>
<h2 id="experimental-design-robust-parameter-validation">Experimental Design: Robust Parameter Validation</h2>
<p>The authors validated EAM through a rigorous split between parameterization data and prediction tasks:</p>
<p><strong>Fitting Data (Bulk Properties Only):</strong></p>
<p>The model parameters were fitted exclusively to these experimental values for Ni and Pd:</p>
<ul>
<li>Lattice constant ($a_0$)</li>
<li>Elastic constants ($C_{11}, C_{12}, C_{44}$)</li>
<li>Sublimation energy ($E_s$)</li>
<li>Vacancy-formation energy ($E^F_{1V}$)</li>
<li>Hydrogen heat of solution (for fitting H parameters)</li>
</ul>
<p><strong>Validation Tests (No Further Fitting):</strong></p>
<p>The model was then evaluated on its ability to predict these properties without any additional parameter adjustments:</p>
<ul>
<li><strong>Surface Relaxations:</strong> Ni(110) surface contraction</li>
<li><strong>Surface Energy:</strong> Ni(100) surface energy</li>
<li><strong>Hydrogen Migration:</strong> H migration energy in Pd</li>
<li><strong>Fracture Mechanics:</strong> Hydrogen embrittlement in Ni slabs</li>
</ul>
<h2 id="results-extending-predictive-power-to-surfaces-and-defects">Results: Extending Predictive Power to Surfaces and Defects</h2>
<ol>
<li><strong>Many-Body Physics:</strong> The embedding function $F(\rho)$ successfully captures the volume-dependence of metallic cohesion, fixing the &ldquo;Cauchy discrepancy&rdquo; inherent in pair potentials.</li>
<li><strong>Surface Properties:</strong> A single set of functions, fitted only to bulk data, correctly reproduces surface relaxations within 0.1 Å of experiment across three faces (100), (110), and (111) for Ni. The Ni(100) surface energy (1550 erg/cm²) compares well with the measured crystal-vapor average (1725 erg/cm²).</li>
<li><strong>Hydrogen in Bulk:</strong> The method predicts H migration energy in Pd as 0.26 eV, matching experiment exactly. Hydride lattice expansions are also well reproduced: 4.5% for NiH (experiment: 5%) and 4% for PdH (experiment: 3.5% for PdH$_{0.6}$).</li>
<li><strong>Hydrogen on Surfaces:</strong> Calculated adsorption sites on all three Ni and Pd faces agree with experimentally determined sites. Adsorption energies on Ni surfaces are systematically about 0.25 eV too low, while on Pd surfaces the error is much smaller (about 0.05 eV too high on average).</li>
<li><strong>Fracture Mechanics:</strong> Static fracture calculations on Ni slabs demonstrate brittle fracture behavior and show that hydrogen lowers the fracture stress, providing a qualitative model of hydrogen embrittlement.</li>
</ol>
<h2 id="limitations">Limitations</h2>
<p>The authors acknowledge several limitations:</p>
<ul>
<li>The functions $F$ and $\phi$ are not uniquely determined by the empirical fitting procedure. The short-range pair potential (restricted to first neighbors in fcc metals) may not be the best choice for all crystal structures.</li>
<li>The choice of hydrogen embedding function (Puska et al. vs. Norskov&rsquo;s corrected function) remains undecided and may affect hydrogen binding energies.</li>
<li>The fracture calculations are static, and dynamical effects and plasticity play important roles in real fracture that are not captured.</li>
<li>The method has only been demonstrated for fcc metals (Ni and Pd). Extension to bcc metals and other crystal structures requires further investigation.</li>
</ul>
<h2 id="reproducibility-details">Reproducibility Details</h2>
<h3 id="algorithms">Algorithms</h3>
<p>To replicate the method, three specific algorithmic definitions are needed:</p>
<ol>
<li>
<p><strong>Atomic Density Construction</strong>: The electron density $\rho^a(r)$ is a weighted sum of Hartree-Fock $s$ and $d$ orbital densities (from Clementi &amp; Roetti tables), controlled by a parameter $N_s$ (the number of s-like electrons):
$$\rho^a(r) = N_s\rho_s^a(r) + (N-N_s)\rho_d^a(r)$$
For Ni, $N_s = 0.85$; for Pd, $N_s = 0.65$ (fitted to H solution heat).</p>
</li>
<li>
<p><strong>Pair Potential Form</strong>: The short-range pair interaction derives from an effective charge function $Z(r)$ to handle core repulsion:
$$\phi_{ij}(r) = \frac{Z_i(r)Z_j(r)}{r}$$
Splines for $Z(r)$ are provided in Table II.</p>
</li>
<li>
<p><strong>Analytic Forces</strong>: Because embedding energy depends on neighbor density, the force calculation is many-body:
$$\vec{f}_{k} = -\sum_{j(\neq k)} (F&rsquo;_{k} \rho&rsquo;_{j} + F&rsquo;_{j} \rho&rsquo;_{k} + \phi&rsquo;_{jk}) \vec{r}_{jk}$$</p>
</li>
</ol>
<h3 id="models">Models</h3>
<p>The functions $F(\rho)$ and $\phi(r)$ are modeled using <strong>cubic splines</strong>, with parameters fitted to reproduce bulk experimental constants. The embedding function $F(\rho)$ is constrained to have a single minimum and to be linear at high densities, matching the qualitative form of the first-principles calculations by Puska et al. Energy minimization uses the <strong>conjugate gradients</strong> technique. The paper explicitly lists spline knots, coefficients, and cutoffs in Tables II and IV, making the method fully reproducible.</p>















<figure class="post-figure center ">
    <img src="/img/notes/chemistry/eam-embedding-effective-charge.webp"
         alt="Reproduction of Figures 1 and 2 from Daw &amp; Baskes (1984) showing the embedding energy and effective charge functions for Ni and Pd"
         title="Reproduction of Figures 1 and 2 from Daw &amp; Baskes (1984) showing the embedding energy and effective charge functions for Ni and Pd"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption"><strong>Left:</strong> Dimensionless embedding energy ($E/E_s$) vs. normalized electron density ($\rho/\bar{\rho}$). The minimum near $\rho/\bar{\rho} \approx 1.0$ drives metallic cohesion. <strong>Right:</strong> Normalized effective charge ($Z/Z_0$) vs. normalized distance ($R/a_0$). The charge drops to zero near $R/a_0 = 0.85$, ensuring short-range interactions. Reproduced from Table II spline knots.</figcaption>
    
</figure>

<h3 id="evaluation">Evaluation</h3>
<p><strong>Fitting Data (Used for Parameterization):</strong></p>
<p>Bulk experimental properties for Ni and Pd only:</p>
<ul>
<li>Lattice constant ($a_0$)</li>
<li>Elastic constants ($C_{11}, C_{12}, C_{44}$)</li>
<li>Sublimation energy ($E_s$)</li>
<li>Vacancy-formation energy ($E^F_{1V}$)</li>
<li>Hydrogen heat of solution (for fitting H parameters)</li>
</ul>
<p><strong>Validation Results (Predictions Without Further Fitting):</strong></p>
<table>
	<thead>
			<tr>
					<th>Property</th>
					<th>Predicted</th>
					<th>Experimental</th>
					<th>Agreement</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Ni(110) surface contraction</td>
					<td>-0.11 Å</td>
					<td>-0.06 to -0.10 Å</td>
					<td>Within 0.1 Å</td>
			</tr>
			<tr>
					<td>Ni(100) surface energy</td>
					<td>1550 erg/cm²</td>
					<td>1725 erg/cm² (avg.)</td>
					<td>Close</td>
			</tr>
			<tr>
					<td>H migration in Pd</td>
					<td>0.26 eV</td>
					<td>0.26 eV</td>
					<td>Exact</td>
			</tr>
			<tr>
					<td>NiH lattice expansion</td>
					<td>4.5%</td>
					<td>5%</td>
					<td>Close</td>
			</tr>
			<tr>
					<td>PdH lattice expansion</td>
					<td>4%</td>
					<td>3.5% (PdH$_{0.6}$)</td>
					<td>Close</td>
			</tr>
			<tr>
					<td>H adsorption sites (Ni, Pd)</td>
					<td>Correct on all faces</td>
					<td>Matches experiment</td>
					<td>Exact</td>
			</tr>
			<tr>
					<td>H embrittlement in Ni</td>
					<td>Qualitative model</td>
					<td>-</td>
					<td>Qualitative</td>
			</tr>
	</tbody>
</table>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Daw, M. S., &amp; Baskes, M. I. (1984). Embedded-atom method: Derivation and application to impurities, surfaces, and other defects in metals. <em>Physical Review B</em>, 29(12), 6443-6453. <a href="https://doi.org/10.1103/PhysRevB.29.6443">https://doi.org/10.1103/PhysRevB.29.6443</a></p>
<p><strong>Publication</strong>: Physical Review B, 1984</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{daw1984embedded,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Embedded-atom method: Derivation and application to impurities, surfaces, and other defects in metals}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Daw, Murray S and Baskes, Mike I}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{Physical Review B}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{29}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">number</span>=<span style="color:#e6db74">{12}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{6443--6453}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{1984}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{APS}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">doi</span>=<span style="color:#e6db74">{10.1103/PhysRevB.29.6443}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Additional Resources</strong>:</p>
<ul>
<li><a href="/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-review-1993/">EAM Review (1993)</a></li>
<li><a href="/notes/chemistry/molecular-simulation/classical-methods/embedded-atom-method-voter-1994/">EAM User Guide (1994)</a></li>
<li><a href="https://www.ctcms.nist.gov/potentials/">NIST Interatomic Potentials Repository</a></li>
</ul>
]]></content:encoded></item><item><title>Lennard-Jones on Adsorption and Diffusion on Surfaces</title><link>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/processes-of-adsorption/</link><pubDate>Sun, 17 Aug 2025 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/notes/chemistry/molecular-simulation/classical-methods/processes-of-adsorption/</guid><description>Lennard-Jones's 1932 foundational paper introducing potential energy surface models to unify physical and chemical adsorption.</description><content:encoded><![CDATA[<h2 id="the-theoretical-foundation-of-adsorption-and-diffusion">The Theoretical Foundation of Adsorption and Diffusion</h2>
<p>This paper represents a foundational <strong>Theory</strong> contribution with dual elements of <strong>Systematization</strong>. It derives physical laws for adsorption potentials (Section 2) and diffusion kinetics (Section 4) from first principles, validating them against external experimental data (Ward, Benton). It bridges <strong>electronic structure theory</strong> (potential curves) and <strong>statistical mechanics</strong> (diffusion rates). It provides a unifying theoretical framework to explain a range of experimental observations.</p>
<h2 id="reconciling-physisorption-and-chemisorption">Reconciling Physisorption and Chemisorption</h2>
<p>The primary motivation was to reconcile conflicting experimental evidence regarding the nature of gas-solid interactions. At the time, it was observed that the same gas and solid could interact weakly at low temperatures (consistent with van der Waals forces) but exhibit strong, chemical-like bonding at higher temperatures, a process requiring significant activation energy. The paper seeks to provide a single, coherent model that can explain both &ldquo;physical adsorption&rdquo; (physisorption) and &ldquo;activated&rdquo; or &ldquo;chemical adsorption&rdquo; (chemisorption) and the transition between them.</p>
<h2 id="quantum-mechanical-potential-energy-surfaces-for-adsorption">Quantum Mechanical Potential Energy Surfaces for Adsorption</h2>
<p>The core novelty is the application of quantum mechanical potential energy surfaces to the problem of surface adsorption. The key conceptual breakthroughs are:</p>
<ol>
<li>
<p><strong>Dual Potential Energy Curves</strong>: The paper proposes that the state of the system must be described by at least two distinct potential energy curves as a function of the distance from the surface:</p>
<ul>
<li>One curve represents the interaction of the intact molecule with the surface (e.g., H₂ with a metal). This corresponds to weak, long-range van der Waals forces.</li>
<li>A second curve represents the interaction of the dissociated constituent atoms with the surface (e.g., 2H atoms with the metal). This corresponds to strong, short-range chemical bonds.</li>
</ul>
</li>
<li>
<p><strong>Activated Adsorption via Curve Crossing</strong>: The transition from the molecular (physisorbed) state to the atomic (chemisorbed) state occurs at the intersection of these two potential energy curves. For a molecule to dissociate and chemisorb, it must possess sufficient energy to reach this crossing point. This energy is identified as the <strong>energy of activation</strong>, which had been observed experimentally.</p>
</li>
<li>
<p><strong>Unified Model</strong>: This model unifies physisorption and chemisorption into a single continuous process. A molecule approaching the surface is first trapped in the shallow potential well of the physisorption curve. If it acquires enough thermal energy to overcome the activation barrier, it can transition to the much deeper potential well of the chemisorption state. This provides a clear physical picture for temperature-dependent adsorption phenomena.</p>
</li>
<li>
<p><strong>Quantum Mechanical Basis for Cohesion</strong>: To explain the nature of the chemisorption bond itself, Lennard-Jones draws on the then-recent quantum theory of metals (Sommerfeld, Bloch). In a metal, electrons are not bound to individual atoms but instead occupy shared energy states (bands) spread across the crystal. When an atom approaches the surface, local energy levels form in the gap between the bulk bands, creating sites where bonding can occur. The adsorption bond arises from the interaction between the valency electron of the approaching atom and conduction electrons of the metal, forming a closed shell analogous to a homopolar bond.</p>
</li>
</ol>
<h2 id="validating-theory-against-experimental-gas-solid-interactions">Validating Theory Against Experimental Gas-Solid Interactions</h2>
<p>This is a theoretical paper with no original experiments performed by the author. However, Lennard-Jones validates his theoretical framework against existing experimental data from other researchers:</p>
<ul>
<li><strong>Ward&rsquo;s data</strong>: Hydrogen absorption on copper, used to validate the square root time law for slow sorption kinetics (§4)</li>
<li><strong>Activated adsorption experiments</strong>: Benton and White (hydrogen on nickel), Taylor and Williamson, and Taylor and McKinney all provided isobar data showing temperature-dependent transitions between adsorption types (§3). Garner and Kingman documented three distinct adsorption regimes at different temperatures.</li>
<li><strong>van der Waals constant data</strong>: Used existing measurements of diamagnetic susceptibility to calculate predicted heats of adsorption (e.g., argon on copper yielding approximately 6000 cal/gram atom, nitrogen roughly 2500 cal/gram mol, hydrogen roughly 1300 cal/gram mol)</li>
<li><strong>KCl crystal calculations</strong>: Computed the full attractive potential field of argon above a KCl crystal lattice, accounting for the discrete ionic structure to produce detailed potential energy curves at different surface positions (§2)</li>
</ul>
<p>The validation approach involves deriving theoretical predictions from first principles and showing they match the functional form and magnitude of independently measured experimental results.</p>
<h2 id="the-lennard-jones-diagram-and-activated-adsorption">The Lennard-Jones Diagram and Activated Adsorption</h2>
<p><strong>Key Outcomes</strong>:</p>
<ul>
<li>The paper introduced the now-famous Lennard-Jones diagram for surface interactions, plotting potential energy versus distance from the surface for both molecular and dissociated atomic species. This graphical model became a cornerstone of surface science.</li>
<li>Derived the square root time law ($S \propto \sqrt{t}$) for slow sorption kinetics, validated against Ward&rsquo;s experimental data.</li>
<li>Established quantitative connection between adsorption potentials and measurable atomic properties (diamagnetic susceptibility).</li>
</ul>
<p><strong>Conclusions</strong>:</p>
<ul>
<li>The nature of adsorption is determined by the interplay between two distinct potential states (molecular and atomic).</li>
<li>&ldquo;Activated adsorption&rdquo; is the process of overcoming an energy barrier to transition from a physically adsorbed molecular state to a chemically adsorbed atomic state.</li>
<li>The model predicts that the specific geometry of the surface (i.e., the lattice spacing) and the orientation of the approaching molecule are critical, as they influence the shape of the potential energy surfaces and thus the magnitude of the activation energy.</li>
<li>The reverse process (recombination of atoms and desorption of a molecule) also requires activation energy to move from the chemisorbed state back to the molecular state.</li>
<li>This entire mechanism is proposed as a fundamental factor in heterogeneous <strong>catalysis</strong>, where the surface acts to lower the activation energy for molecular dissociation, facilitating chemical reactions.</li>
</ul>
<p><strong>Limitations</strong>:</p>
<ul>
<li>The initial &ldquo;method of images&rdquo; derivation assumes a perfectly continuous conducting surface, an approximation that breaks down at the atomic orbital level close to the surface.</li>
<li>While Lennard-Jones uses one-dimensional calculations to estimate initial potential well depths, he later qualitatively extends this to 3D &ldquo;contour tunnels&rdquo; to explain surface migration. However, these early geometric approximations lack the many-body, multi-dimensional complexity natively handled by modern Density Functional Theory (DFT) simulations.</li>
</ul>
<hr>
<h2 id="mathematical-derivations">Mathematical Derivations</h2>
<h3 id="van-der-waals-calculation-section-2">Van der Waals Calculation (Section 2)</h3>
<p>The paper derives the attractive force between a neutral atom and a metal surface using the <strong>classical method of electrical images</strong>. The key steps are:</p>
<ol>
<li><strong>Method of Images</strong>: Lennard-Jones models the metal as a continuum of perfectly mobile electric fluid (a perfectly polarisable system). When a neutral atom approaches, its instantaneous dipole moment induces image charges in the metal surface.</li>
</ol>















<figure class="post-figure center ">
    <img src="/img/notes/method-of-images-atom-surface.webp"
         alt="Diagram showing an atom with nucleus (&#43;Ne) and electrons (-e) at distance R from a conducting surface, with its electrical image reflected on the opposite side"
         title="Diagram showing an atom with nucleus (&#43;Ne) and electrons (-e) at distance R from a conducting surface, with its electrical image reflected on the opposite side"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">An atom and its electrical image in a conducting surface. The nucleus (+Ne) and electrons create mirror charges across the metal plane.</figcaption>
    
</figure>

<ol start="2">
<li><strong>The Interaction Potential</strong>: The resulting potential energy $W$ of an atom at distance $R$ from the metal surface is:</li>
</ol>
<p>$$W = -\frac{e^2 \overline{r^2}}{6R^3}$$</p>
<p>where $\overline{r^2}$ is the mean square distance of electrons from the nucleus.</p>
<ol start="3">
<li><strong>Connection to Measurable Properties</strong>: This theoretical potential can be calculated using <strong>diamagnetic susceptibility</strong> ($\chi$). The interaction simplifies to:</li>
</ol>
<p>$$W = \mu R^{-3}$$</p>
<p>where $\mu = mc^2\chi/L$, with $m$ the electron mass, $c$ the speed of light, $\chi$ the diamagnetic susceptibility, and $L$ Loschmidt&rsquo;s number ($6.06 \times 10^{23}$). This connects the adsorption potential to measurable magnetic properties of the atom.</p>
<ol start="4">
<li><strong>Repulsive Forces and Equilibrium</strong>: By assuming repulsive forces account for approximately 40% of the potential at equilibrium, Lennard-Jones estimates heats of adsorption. For argon on copper, this yields approximately 6000 cal per gram atom. Similar calculations give roughly 2500 cal/gram mol for nitrogen on copper and 1300 cal/gram mol for hydrogen.</li>
</ol>
<hr>
<h2 id="kinetic-theory-of-slow-sorption-section-4">Kinetic Theory of Slow Sorption (Section 4)</h2>
<p>The paper extends beyond surface phenomena to model how gas <em>enters</em> the bulk solid (absorption). This section is critical for understanding time-dependent adsorption kinetics.</p>
<h3 id="the-cracks-hypothesis">The &ldquo;Cracks&rdquo; Hypothesis</h3>
<p>Lennard-Jones proposes that &ldquo;slow sorption&rdquo; is <strong>lateral diffusion along surface cracks</strong> (fissures between microcrystal boundaries) in the solid. The outer surface presents not a uniform plane but a network of narrow, deep crevasses where gas can penetrate. This reframes the problem: the rate-limiting step is diffusion along these crack walls, explaining why sorption rates differ from predictions based on bulk diffusion coefficients.</p>
<h3 id="the-diffusion-equation">The Diffusion Equation</h3>
<p>The problem is formulated using Fick&rsquo;s second law:</p>
<p>$$\frac{\partial n}{\partial t} = D \frac{\partial^{2}n}{\partial x^{2}}$$</p>
<p>where $n$ is the concentration of adsorbed atoms, $t$ is time, $D$ is the diffusion coefficient, and $x$ is the position along the crack.</p>
<h3 id="derivation-of-the-diffusion-coefficient">Derivation of the Diffusion Coefficient</h3>
<p>The diffusion coefficient is derived from kinetic theory:</p>
<p>$$D = \frac{\bar{c}^2 \tau^2}{2\tau^*}$$</p>
<p>where:</p>
<ul>
<li>$\bar{c}$ is the mean lateral velocity of mobile atoms parallel to the surface</li>
<li>$\tau$ is the time an atom spends in the mobile (activated) state</li>
<li>$\tau^*$ is the interval between activation events</li>
</ul>
<p>Atoms are &ldquo;activated&rdquo; to a mobile state with energy $E_0$, after which they can migrate along the surface.</p>
<h3 id="the-square-root-law">The Square Root Law</h3>
<p>Solving the diffusion equation for a semi-infinite crack yields the total amount of gas absorbed $S$ as a function of time:</p>
<p>$$S = 2n_0 \sqrt{\frac{Dt}{\pi}}$$</p>
<p>This predicts that <strong>absorption scales with the square root of time</strong>:</p>
<p>$$S \propto \sqrt{t}$$</p>
<h3 id="experimental-validation">Experimental Validation</h3>
<p>Lennard-Jones validates this derivation by re-analyzing Ward&rsquo;s experimental data on the Copper/Hydrogen system. Plotting the absorbed quantity against $\sqrt{t}$ produces linear curves, confirming the theoretical prediction. From the slope of the $\log_{10}(S^2/q^2t)$ vs. $1/T$ plot, Ward determined an activation energy of 14,100 cal per gram-molecule for the surface diffusion process.</p>
<hr>
<h2 id="surface-topography-and-3d-contours">Surface Topography and 3D Contours</h2>
<p>The notes above imply a one-dimensional process (distance from surface). The paper explicitly expands this to three dimensions to explain surface migration.</p>
<h3 id="potential-tunnels">Potential &ldquo;Tunnels&rdquo;</h3>
<p>Lennard-Jones models the surface potential as <strong>3D contour surfaces</strong> resembling &ldquo;underground caverns&rdquo; or tunnels. The potential energy landscape above a crystalline surface has periodic minima and saddle points.</p>
<h3 id="surface-migration">Surface Migration</h3>
<p>Atoms migrate along &ldquo;tunnels&rdquo; of low potential energy between surface atoms. The activation energy for surface diffusion corresponds to the barrier height between adjacent potential wells on the surface. This geometric picture explains:</p>
<ul>
<li>Why certain crystallographic orientations are more reactive</li>
<li>The temperature dependence of surface diffusion rates</li>
<li>The role of surface defects in catalysis</li>
</ul>
<h2 id="reproducibility">Reproducibility</h2>
<p>This is a 1932 theoretical paper with no associated code, datasets, or models. The mathematical derivations are fully presented in the text and can be followed from first principles. The experimental data referenced (Ward&rsquo;s copper/hydrogen measurements, Benton and White&rsquo;s nickel/hydrogen isobars) are cited from independently published sources. No computational artifacts exist.</p>
<ul>
<li><strong>Status</strong>: Closed (theoretical paper, no reproducibility artifacts)</li>
<li><strong>Hardware</strong>: N/A (analytical derivations only)</li>
</ul>
<h2 id="paper-information">Paper Information</h2>
<p><strong>Citation</strong>: Lennard-Jones, J. E. (1932). Processes of Adsorption and Diffusion on Solid Surfaces. <em>Transactions of the Faraday Society</em>, 28, 333-359. <a href="https://doi.org/10.1039/tf9322800333">https://doi.org/10.1039/tf9322800333</a></p>
<p><strong>Publication</strong>: Transactions of the Faraday Society, 1932</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bibtex" data-lang="bibtex"><span style="display:flex;"><span><span style="color:#a6e22e">@article</span>{lennardjones1932processes,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">title</span>=<span style="color:#e6db74">{Processes of adsorption and diffusion on solid surfaces}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">author</span>=<span style="color:#e6db74">{Lennard-Jones, John Edward}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">journal</span>=<span style="color:#e6db74">{Transactions of the Faraday Society}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">volume</span>=<span style="color:#e6db74">{28}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">pages</span>=<span style="color:#e6db74">{333--359}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">year</span>=<span style="color:#e6db74">{1932}</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">publisher</span>=<span style="color:#e6db74">{Royal Society of Chemistry}</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded></item><item><title>Kabsch Algorithm: NumPy, PyTorch, TensorFlow, and JAX</title><link>https://hunterheidenreich.com/posts/kabsch-algorithm/</link><pubDate>Tue, 03 Oct 2023 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/posts/kabsch-algorithm/</guid><description>Learn about the Kabsch algorithm for optimal point alignment with implementations in NumPy, PyTorch, TensorFlow, and JAX for ML applications.</description><content:encoded><![CDATA[<h2 id="what-is-the-kabsch-algorithm">What is the Kabsch Algorithm?</h2>
<p>In computer vision or scientific computing, a common problem frequently arises: given two sets of points, what is the optimal rigid body transformation for their alignment? The Kabsch algorithm provides a nice solution.</p>















<figure class="post-figure center ">
    <img src="/img/scientific-computing/kabsch-alignment-before-and-after.webp"
         alt="Visualization of two point sets before and after Kabsch alignment"
         title="Visualization of two point sets before and after Kabsch alignment"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">The Kabsch algorithm optimally rotates and translates the blue points to align with the red points.</figcaption>
    
</figure>

<p>What are some concrete situations where this crops up?</p>
<ul>
<li><strong>Molecular Dynamics</strong>: Your points are a set of atoms (with physically relevant types), and you want to compare two molecular conformations. Are they the same structure with minor noise or rotation? Or are they different conformations, like a different folding of a protein? This is especially helpful when applying generative models to chemical structures. For example, if you are building a <a href="/notes/chemistry/molecular-simulation/ml-potentials/denoise-vae/">3D Molecular VAE</a> in PyTorch or working with <a href="/notes/machine-learning/generative-models/flow-matching-for-generative-modeling/">Flow Matching models</a>, Kabsch alignment ensures your generative loss function remains rotationally invariant.</li>
<li><strong>Computer Vision</strong>: You have two point clouds from 3D scans of an object taken from different angles. You want to align them to reconstruct the full shape. Or perhaps you&rsquo;re generating 3D shapes from 2D images and need to compare the generated shape to a ground truth scan. Anytime a 3D system is represented as a point cloud, the Kabsch algorithm can help with alignment.</li>
</ul>
<p>Of course, existing libraries implement this algorithm. However, often I find it beneficial to implement algorithms from scratch to build intuition. Furthermore, modern machine learning applications require automatic differentiation, so we will implement the algorithm in PyTorch, TensorFlow, and JAX.</p>
<p>Below, we&rsquo;ll cover the math behind the Kabsch algorithm (and its scaling variant, the <strong>Kabsch-Umeyama</strong> algorithm) and provide complete, differentiable implementations in <strong>NumPy</strong>, <strong>PyTorch</strong>, <strong>TensorFlow</strong>, and <strong>JAX</strong>, demonstrating both single-pair and batched computations for ML applications.</p>
<h2 id="the-math">The Math</h2>















<figure class="post-figure center ">
    <img src="/img/scientific-computing/kabsch-algorithm-basic-animation.webp"
         alt="Animation showing the iterative steps of centroid alignment and rotation"
         title="Animation showing the iterative steps of centroid alignment and rotation"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Visualizing the alignment process: first centering the datasets, then finding the optimal rotation.</figcaption>
    
</figure>

<p>Let&rsquo;s say we have two sets of paired points,
$P={\mathbf{p}_i} \in \mathbb{R}^{N \times D}$ and $Q={\mathbf{q}_i} \in \mathbb{R}^{N \times D}$, for $i = 1, \dots, N$
(where $D$ is the dimensionality and $N$ is the number of points).
We want to find a translation vector $\mathbf{t}$ and rotation matrix $R$ to transform $P$ to align with $Q$.</p>
<p>The optimization problem is:</p>
<p>$$
\min_{\mathbf{t}, \ R} \mathcal{L}(\mathbf{t}, R) = \frac{1}{2} \sum_{i=1}^N | \mathbf{q}_i - (R\mathbf{p}_i + \mathbf{t}) |^2
$$</p>
<p>where $\mathbf{t}^\ast \in \mathbb{R}^D$ and $R^\ast \in \mathbb{R}^{D \times D}$ are the optimal translation and rotation.</p>
<p>Often we use a weighted version with weights $w_i$ (e.g., atomic masses in molecular dynamics):</p>
<p>$$
\min_{\mathbf{t}, \ R} \mathcal{L}(\mathbf{t}, R) = \frac{1}{2} \sum_{i=1}^N w_i | \mathbf{q}_i - (R\mathbf{p}_i + \mathbf{t}) |^2
$$</p>
<h3 id="the-translation">The Translation</h3>
<p>The translation and rotation are coupled, but they separate cleanly once we work in centroid-centered coordinates. Compute the centroids (averages) of both point sets:</p>
<p>$$
\bar{\mathbf{p}} = \frac{1}{N} \sum_{i=1}^N \mathbf{p}_i \quad \text{and} \quad \bar{\mathbf{q}} = \frac{1}{N} \sum_{i=1}^N \mathbf{q}_i
$$</p>
<p>For any fixed rotation $R$, the translation that minimizes $\mathcal{L}$ is found by setting $\partial \mathcal{L} / \partial \mathbf{t} = 0$. It maps the rotated source centroid onto the target centroid:</p>
<p>$$
\mathbf{t} = \bar{\mathbf{q}} - R\bar{\mathbf{p}}
$$</p>
<p>A tempting shortcut is to write $\mathbf{t} = \bar{\mathbf{q}} - \bar{\mathbf{p}}$, but that is only correct when $R = I$. In general the translation depends on the rotation, so we compute it <em>after</em> solving for $R$. Substituting this optimal $\mathbf{t}$ back into the objective cancels the centroids and leaves a rotation-only problem in the centered coordinates $\mathbf{p}_i^\prime = \mathbf{p}_i - \bar{\mathbf{p}}$ and $\mathbf{q}_i^\prime = \mathbf{q}_i - \bar{\mathbf{q}}$:</p>
<p>$$
\mathcal{L}(R) = \frac{1}{2} \sum_{i=1}^N | \mathbf{q}_i^\prime - R\mathbf{p}_i^\prime |^2
$$</p>
<p>which is what the next section solves.</p>
<h3 id="the-rotation-matrix">The Rotation Matrix</h3>
<p>We now minimize $\mathcal{L}(R)$ over rotations, using the centered points $\mathbf{p}_i^\prime$ and $\mathbf{q}_i^\prime$ from above. Compute the cross-covariance matrix between the centered sets:</p>
<p>$$
C = P^{\prime T} Q^\prime = \sum_{i=1}^N \mathbf{p}_i^{\prime T} \mathbf{q}_i^{\prime} \in \mathbb{R}^{D \times D}
$$</p>
<p>This is a fairly lightweight operation since $D$ is typically small (e.g., 3 for 3D points), even if $N$ is large.</p>
<p>With $C$ in hand, we want to compute its Singular Value Decomposition (SVD):</p>
<p>$$
C = U \Sigma V^T
$$</p>
<p>This operation is computationally expensive. It scales cubically with $D$ (i.e., $O(D^3)$).
However, since we&rsquo;re often interested in cases where $D$ is small (e.g., 2D or 3D points), this is manageable.</p>
<p>Next, we check for improper rotations (i.e., reflections) and correct for them where necessary:</p>
<p>$$
d = \text{sign}(\det(V U^T))
$$</p>
<p>If $d = -1$, we need to flip the last column of $V$ in the final rotation matrix.</p>
<p>Let $B = \text{diag}(1, 1, d)$.
The optimal rotation matrix comes out:</p>
<p>$$
R^\ast = V B U^T
$$</p>
<h3 id="summary">Summary</h3>
<p>In a nutshell, the Kabsch algorithm boils down to:</p>
<ol>
<li>Compute centroids of $P$ and $Q$ ($\bar{\mathbf{p}}$ and $\bar{\mathbf{q}}$)</li>
<li>Center both point sets by subtracting centroids: $P^\prime$ and $Q^\prime$</li>
<li>Compute cross-covariance matrix $C = P^{\prime T} Q^\prime$</li>
<li>Compute SVD: $C = U \Sigma V^T$ (<em>expensive step</em>)</li>
<li>Compute $d = \text{sign}(\det(V U^T))$ and $B = \text{diag}(1, 1, d)$</li>
<li>Optimal rotation: $R^\ast = V B U^T$</li>
<li>Optimal translation (using the rotation from step 6): $\mathbf{t}^\ast = \bar{\mathbf{q}} - R^\ast\bar{\mathbf{p}}$</li>
</ol>
<p>The resulting root-mean-square deviation (RMSD) between aligned point sets is</p>
<p>$$
\text{RMSD} = \sqrt{\frac{1}{N} \sum_{i=1}^N | \mathbf{q}_i - (R^\ast\mathbf{p}_i + \mathbf{t}^\ast) |^2}
$$</p>















<figure class="post-figure center ">
    <img src="/img/scientific-computing/kabsch-algorithm-visualized-rmsd.webp"
         alt="Diagram illustrating Root Mean Square Deviation (RMSD) distances"
         title="Diagram illustrating Root Mean Square Deviation (RMSD) distances"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">RMSD measures the average distance between the aligned points.</figcaption>
    
</figure>

<p>which is frequently used as a measure of similarity between molecular structures or as a metric in loss functions for ML applications.</p>
<h3 id="the-kabsch-umeyama-algorithm-scaling">The Kabsch-Umeyama Algorithm (Scaling)</h3>
<p>While the standard Kabsch algorithm solves for optimal rotation and translation, the <strong>Kabsch-Umeyama algorithm</strong> extends this by also finding an optimal <strong>scaling factor</strong> $c$. This is essential when aligning structures of different scales, such as a 3D scan versus a ground truth model.</p>
<p><em>(Note: This is sometimes searched for as the &ldquo;Absch-Umeyama algorithm&rdquo; due to typos, but the correct attribution is to Shinji Umeyama based on Wolfgang Kabsch&rsquo;s work.)</em></p>
<p>The method estimates the transformation $\mathbf{q}_i \approx c R \mathbf{p}_i + \mathbf{t}$. The optimal scale is the trace of the (reflection-corrected) singular values of the cross-covariance divided by the variance of the source points about their centroid. See the <a href="/notes/computational-biology/umeyama-similarity-transformation/">Umeyama paper notes</a> for the full derivation.</p>
<p><strong>A Note on SVD and Automatic Differentiation</strong></p>
<p>While modern frameworks allow us to backpropagate through the Singular Value Decomposition (SVD), it comes with a known stability issue: if the cross-covariance matrix has identical (degenerate) singular values (which can occur if the point clouds are perfectly aligned or have certain symmetries), the gradient of the SVD approaches infinity, causing <code>NaN</code> values during backpropagation. If you plan to use this algorithm as a loss function for a neural network, it is often necessary to add a tiny epsilon to the matrix before computing the SVD, or to utilize an SVD gradient patch. The <a href="/projects/kabsch-horn-cookbook/">Kabsch-Horn Cookbook</a> library provides a SafeSVD primitive that floors the singular-value-gap denominator at machine epsilon in the backward pass, producing finite gradients at degenerate inputs across PyTorch, JAX, TensorFlow, and MLX.</p>
<h2 id="implementation">Implementation</h2>
<p>Let&rsquo;s implement the algorithm in different frameworks. Note that for simplicity, the following implementations cover the <strong>unweighted</strong> Kabsch algorithm. If your application (like molecular dynamics) requires weights (e.g., atomic masses), the <a href="/projects/kabsch-horn-cookbook/">Kabsch-Horn Cookbook</a> library provides per-point weighted alignment out of the box.</p>
<h3 id="numpy">NumPy</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> numpy <span style="color:#66d9ef">as</span> np
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_numpy</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>mean(P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>mean(Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>dot(p<span style="color:#f92672">.</span>T, q)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    U, S, Vt <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Validate right-handed coordinate system</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> np<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>det(np<span style="color:#f92672">.</span>dot(Vt<span style="color:#f92672">.</span>T, U<span style="color:#f92672">.</span>T)) <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0.0</span>:
</span></span><span style="display:flex;"><span>        Vt[<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>, :] <span style="color:#f92672">*=</span> <span style="color:#f92672">-</span><span style="color:#ae81ff">1.0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal rotation</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>dot(Vt<span style="color:#f92672">.</span>T, U<span style="color:#f92672">.</span>T)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q <span style="color:#f92672">-</span> np<span style="color:#f92672">.</span>dot(R, centroid_P)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>sqrt(np<span style="color:#f92672">.</span>sum(np<span style="color:#f92672">.</span>square(np<span style="color:#f92672">.</span>dot(p, R<span style="color:#f92672">.</span>T) <span style="color:#f92672">-</span> q)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">0</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><p>Here&rsquo;s a quick test to verify correctness:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">test_numpy</span>():
</span></span><span style="display:flex;"><span>    np<span style="color:#f92672">.</span>random<span style="color:#f92672">.</span>seed(<span style="color:#ae81ff">12345</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    P <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>random<span style="color:#f92672">.</span>randn(<span style="color:#ae81ff">100</span>, <span style="color:#ae81ff">3</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    alpha <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>random<span style="color:#f92672">.</span>rand() <span style="color:#f92672">*</span> <span style="color:#ae81ff">2</span> <span style="color:#f92672">*</span> np<span style="color:#f92672">.</span>pi
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>array([[np<span style="color:#f92672">.</span>cos(alpha), <span style="color:#f92672">-</span>np<span style="color:#f92672">.</span>sin(alpha), <span style="color:#ae81ff">0</span>],
</span></span><span style="display:flex;"><span>                    [np<span style="color:#f92672">.</span>sin(alpha), np<span style="color:#f92672">.</span>cos(alpha), <span style="color:#ae81ff">0</span>],
</span></span><span style="display:flex;"><span>                    [<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>]])
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>random<span style="color:#f92672">.</span>randn(<span style="color:#ae81ff">3</span>) <span style="color:#f92672">*</span> <span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    Q <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>dot(P, R<span style="color:#f92672">.</span>T) <span style="color:#f92672">+</span> t
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    R_opt, t_opt, rmsd <span style="color:#f92672">=</span> kabsch_numpy(P, Q)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;RMSD: </span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(rmsd))
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;R:</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(R))
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;R_opt:</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(R_opt))
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;t:</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(t))
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;t_opt:</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(t_opt))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    l2_t <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>norm(t <span style="color:#f92672">-</span> t_opt)
</span></span><span style="display:flex;"><span>    l2_R <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>norm(R <span style="color:#f92672">-</span> R_opt)
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;l2_t: </span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(l2_t))
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#39;l2_R: </span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#39;</span><span style="color:#f92672">.</span>format(l2_R))
</span></span></code></pre></div><p>Running this test shows the algorithm correctly recovers the rotation and translation:</p>
<pre><code>RMSD: 3.2111501877699246e-15
R:
[[-0.8475392 -0.5307328  0.       ]
 [ 0.5307328 -0.8475392  0.       ]
 [ 0.         0.         1.       ]]
R_opt:
[[-8.47539198e-01 -5.30732803e-01 -2.95434260e-16]
 [ 5.30732803e-01 -8.47539198e-01  2.92859649e-16]
 [ 0.00000000e+00 -2.77555756e-16  1.00000000e+00]]
t:
[ 5.99726796  1.50078468 -3.34633977]
t_opt:
[ 5.99726796  1.50078468 -3.34633977]
l2_t: 2.7012892057857038e-15
l2_R: 8.028174304721057e-16
</code></pre>
<p>Both the rotation and the translation are recovered to within floating-point precision (the residuals <code>l2_t</code> and <code>l2_R</code> are on the order of <code>1e-15</code>).</p>
<p>For batch processing:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_numpy_batched</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A BxNx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A BxNx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>mean(P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)  <span style="color:#75715e"># Bx1x3</span>
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>mean(Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)  <span style="color:#75715e"># Bx1x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P  <span style="color:#75715e"># BxNx3</span>
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q  <span style="color:#75715e"># BxNx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>matmul(p<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>), q)  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    U, S, Vt <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Validate right-handed coordinate system</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>det(np<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>), U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>)))
</span></span><span style="display:flex;"><span>    flip <span style="color:#f92672">=</span> d <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0.0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> flip<span style="color:#f92672">.</span>any():
</span></span><span style="display:flex;"><span>        Vt[flip, <span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>, :] <span style="color:#f92672">*=</span> <span style="color:#f92672">-</span><span style="color:#ae81ff">1.0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal rotation</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>), U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>))  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q<span style="color:#f92672">.</span>squeeze(<span style="color:#ae81ff">1</span>) <span style="color:#f92672">-</span> np<span style="color:#f92672">.</span>matmul(centroid_P, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>))<span style="color:#f92672">.</span>squeeze(<span style="color:#ae81ff">1</span>)  <span style="color:#75715e"># Bx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> np<span style="color:#f92672">.</span>sqrt(np<span style="color:#f92672">.</span>sum(np<span style="color:#f92672">.</span>square(np<span style="color:#f92672">.</span>matmul(p, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>)) <span style="color:#f92672">-</span> q), axis<span style="color:#f92672">=</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><h3 id="pytorch">PyTorch</h3>


<p><details >
  <summary markdown="span">📝 Important Update (February 15, 2026)</summary>
  <strong>Bug Fix Notice:</strong> The PyTorch implementation has been updated to use the &ldquo;B-matrix&rdquo; broadcasting approach. This eliminates in-place tensor modification (which breaks <code>autograd</code>) and data-dependent control flow (which breaks <code>torch.compile</code> and <code>torch.vmap</code>).
</details></p>

<p>The PyTorch implementation now uses broadcasting to ensure differentiability:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> torch
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_torch</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>mean(P, dim<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>mean(Q, dim<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>matmul(p<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>), q)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    U, S, Vt <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 1. Calculate determinant</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>det(torch<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>), U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>)))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 2. Build diagonal B tensor without in-place mutation</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># We use stack to preserve gradients and graph connections</span>
</span></span><span style="display:flex;"><span>    B_diag <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>stack([torch<span style="color:#f92672">.</span>tensor(<span style="color:#ae81ff">1.0</span>, device<span style="color:#f92672">=</span>d<span style="color:#f92672">.</span>device, dtype<span style="color:#f92672">=</span>d<span style="color:#f92672">.</span>dtype),
</span></span><span style="display:flex;"><span>                          torch<span style="color:#f92672">.</span>tensor(<span style="color:#ae81ff">1.0</span>, device<span style="color:#f92672">=</span>d<span style="color:#f92672">.</span>device, dtype<span style="color:#f92672">=</span>d<span style="color:#f92672">.</span>dtype),
</span></span><span style="display:flex;"><span>                          torch<span style="color:#f92672">.</span>sign(d)])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 3. Scale columns of Vt.T via broadcasting, then multiply by U^T</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Vt.T: (3, 3). B_diag: (3) -&gt; B_diag[None, :]: (1, 3)</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>) <span style="color:#f92672">*</span> B_diag[<span style="color:#66d9ef">None</span>, :], U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q <span style="color:#f92672">-</span> centroid_P <span style="color:#f92672">@</span> R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>sqrt(torch<span style="color:#f92672">.</span>sum(torch<span style="color:#f92672">.</span>square(torch<span style="color:#f92672">.</span>matmul(p, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">1</span>)) <span style="color:#f92672">-</span> q)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">0</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><p>And our batched version:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_torch_batched</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD, in a batched manner.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A BxNx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A BxNx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>mean(P, dim<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)  <span style="color:#75715e"># Bx1x3</span>
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>mean(Q, dim<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)  <span style="color:#75715e"># Bx1x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P  <span style="color:#75715e"># BxNx3</span>
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q  <span style="color:#75715e"># BxNx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>matmul(p<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>), q)  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    U, S, Vt <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 1. Calculate batched determinant</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>det(torch<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>), U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>)))  <span style="color:#75715e"># B</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 2. Build batched B_diag without in-place mutation or control flow</span>
</span></span><span style="display:flex;"><span>    ones <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>ones_like(d)
</span></span><span style="display:flex;"><span>    B_diag <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>stack([ones, ones, torch<span style="color:#f92672">.</span>sign(d)], dim<span style="color:#f92672">=-</span><span style="color:#ae81ff">1</span>) <span style="color:#75715e"># Bx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 3. Scale columns of Vt.T and multiply</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Vt.T: (B, 3, 3). B_diag: (B, 3). B_diag[:, None, :]: (B, 1, 3).</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>) <span style="color:#f92672">*</span> B_diag[:, <span style="color:#66d9ef">None</span>, :], U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q<span style="color:#f92672">.</span>squeeze(<span style="color:#ae81ff">1</span>) <span style="color:#f92672">-</span> torch<span style="color:#f92672">.</span>matmul(centroid_P, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>))<span style="color:#f92672">.</span>squeeze(<span style="color:#ae81ff">1</span>)  <span style="color:#75715e"># Bx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> torch<span style="color:#f92672">.</span>sqrt(torch<span style="color:#f92672">.</span>sum(torch<span style="color:#f92672">.</span>square(torch<span style="color:#f92672">.</span>matmul(p, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>)) <span style="color:#f92672">-</span> q), dim<span style="color:#f92672">=</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><h3 id="tensorflow">TensorFlow</h3>
<p>The TensorFlow implementation returns <code>S</code>, <code>U</code>, and <code>V</code> directly. To handle immutability and potential compilation (e.g., via <code>@tf.function</code>), we avoid explicit conditional branching by constructing a correction matrix $B$ and broadcasting it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> tensorflow <span style="color:#66d9ef">as</span> tf
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_tensorflow</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    P <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>convert_to_tensor(P, dtype<span style="color:#f92672">=</span>tf<span style="color:#f92672">.</span>float32)
</span></span><span style="display:flex;"><span>    Q <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>convert_to_tensor(Q, dtype<span style="color:#f92672">=</span>tf<span style="color:#f92672">.</span>float32)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>reduce_mean(P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>reduce_mean(Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>matmul(tf<span style="color:#f92672">.</span>transpose(p), q)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    S, U, V <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 1. Calculate determinant</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Note: V in TF SVD is V, not V^T.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># R = V * U^T. Det(R) = Det(V * U^T)</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>det(tf<span style="color:#f92672">.</span>matmul(V, tf<span style="color:#f92672">.</span>transpose(U)))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 2. Build diagonal B tensor: [1.0, 1.0, sign(d)]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Use static shape 3 if possible, or infer from D. Assuming D=3 here.</span>
</span></span><span style="display:flex;"><span>    B_diag <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>stack([<span style="color:#ae81ff">1.0</span>, <span style="color:#ae81ff">1.0</span>, tf<span style="color:#f92672">.</span>sign(d)])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 3. Scale columns of V via broadcasting (V * B_diag), then multiply by U^T</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># V is DxD, B_diag is D. V * B_diag[None, :] multiplies each column j by B_diag[j]</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>matmul(V <span style="color:#f92672">*</span> B_diag[<span style="color:#66d9ef">None</span>, :], tf<span style="color:#f92672">.</span>transpose(U))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q <span style="color:#f92672">-</span> tf<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>matvec(R, centroid_P)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>sqrt(tf<span style="color:#f92672">.</span>reduce_sum(tf<span style="color:#f92672">.</span>square(tf<span style="color:#f92672">.</span>matmul(p, tf<span style="color:#f92672">.</span>transpose(R)) <span style="color:#f92672">-</span> q)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">0</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><p>and a batched version:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_tensorflow_batched</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    P <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>convert_to_tensor(P, dtype<span style="color:#f92672">=</span>tf<span style="color:#f92672">.</span>float32)
</span></span><span style="display:flex;"><span>    Q <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>convert_to_tensor(Q, dtype<span style="color:#f92672">=</span>tf<span style="color:#f92672">.</span>float32)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>reduce_mean(P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>reduce_mean(Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>matmul(tf<span style="color:#f92672">.</span>transpose(p, perm<span style="color:#f92672">=</span>[<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>]), q)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    S, U, V <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 1. Calculate batched determinant</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>det(tf<span style="color:#f92672">.</span>matmul(V, tf<span style="color:#f92672">.</span>transpose(U, perm<span style="color:#f92672">=</span>[<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>])))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 2. Build batched B_diag: shape (B, 3)</span>
</span></span><span style="display:flex;"><span>    ones <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>ones_like(d)
</span></span><span style="display:flex;"><span>    B_diag <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>stack([ones, ones, tf<span style="color:#f92672">.</span>sign(d)], axis<span style="color:#f92672">=-</span><span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 3. Scale columns of V (Broadcasting adds the middle dimension)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># V: (B, 3, 3), B_diag: (B, 3) -&gt; B_diag[:, None, :]: (B, 1, 3)</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>matmul(V <span style="color:#f92672">*</span> B_diag[:, <span style="color:#66d9ef">None</span>, :], tf<span style="color:#f92672">.</span>transpose(U, perm<span style="color:#f92672">=</span>[<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>]))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>squeeze(centroid_Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>) <span style="color:#f92672">-</span> tf<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>matvec(R, tf<span style="color:#f92672">.</span>squeeze(centroid_P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>))  <span style="color:#75715e"># Bx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>sqrt(tf<span style="color:#f92672">.</span>reduce_sum(tf<span style="color:#f92672">.</span>square(tf<span style="color:#f92672">.</span>matmul(p, tf<span style="color:#f92672">.</span>transpose(R, perm<span style="color:#f92672">=</span>[<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>])) <span style="color:#f92672">-</span> q), axis<span style="color:#f92672">=</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><h3 id="jax">JAX</h3>
<p>The JAX implementation closely mirrors NumPy, replacing <code>np</code> with <code>jnp</code>. However, we again avoid <code>if</code> statements and in-place assignment (which JAX disallows) by using the broadcasting B-matrix approach.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> jax.numpy <span style="color:#66d9ef">as</span> jnp
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_jax</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A Nx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    P <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>array(P)
</span></span><span style="display:flex;"><span>    Q <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>array(Q)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>mean(P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>mean(Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>dot(p<span style="color:#f92672">.</span>T, q)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    U, S, Vt <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 1. Calculate determinant</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>det(jnp<span style="color:#f92672">.</span>dot(Vt<span style="color:#f92672">.</span>T, U<span style="color:#f92672">.</span>T))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 2. Build diagonal B array</span>
</span></span><span style="display:flex;"><span>    B_diag <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>array([<span style="color:#ae81ff">1.0</span>, <span style="color:#ae81ff">1.0</span>, jnp<span style="color:#f92672">.</span>sign(d)])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 3. Scale columns of Vt.T and multiply by U.T</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Vt.T is V.</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>dot(Vt<span style="color:#f92672">.</span>T <span style="color:#f92672">*</span> B_diag[<span style="color:#66d9ef">None</span>, :], U<span style="color:#f92672">.</span>T)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q <span style="color:#f92672">-</span> jnp<span style="color:#f92672">.</span>dot(R, centroid_P)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>sqrt(jnp<span style="color:#f92672">.</span>sum(jnp<span style="color:#f92672">.</span>square(jnp<span style="color:#f92672">.</span>dot(p, R<span style="color:#f92672">.</span>T) <span style="color:#f92672">-</span> q)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">0</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div><p>and batched:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">kabsch_jax_batched</span>(P, Q):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Computes the optimal rotation and translation to align two sets of points (P -&gt; Q),
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    and their RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param P: A BxNx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :param Q: A BxNx3 matrix of points
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    :return: A tuple containing the optimal rotation matrix, the optimal
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">             translation vector, and the RMSD.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    P <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>array(P)
</span></span><span style="display:flex;"><span>    Q <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>array(Q)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">assert</span> P<span style="color:#f92672">.</span>shape <span style="color:#f92672">==</span> Q<span style="color:#f92672">.</span>shape, <span style="color:#e6db74">&#34;Matrix dimensions must match&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute centroids</span>
</span></span><span style="display:flex;"><span>    centroid_P <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>mean(P, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)  <span style="color:#75715e"># Bx1x3</span>
</span></span><span style="display:flex;"><span>    centroid_Q <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>mean(Q, axis<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>, keepdims<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)  <span style="color:#75715e"># Bx1x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Center the points</span>
</span></span><span style="display:flex;"><span>    p <span style="color:#f92672">=</span> P <span style="color:#f92672">-</span> centroid_P  <span style="color:#75715e"># BxNx3</span>
</span></span><span style="display:flex;"><span>    q <span style="color:#f92672">=</span> Q <span style="color:#f92672">-</span> centroid_Q  <span style="color:#75715e"># BxNx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Compute the covariance matrix</span>
</span></span><span style="display:flex;"><span>    H <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>matmul(p<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>), q)  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># SVD</span>
</span></span><span style="display:flex;"><span>    U, S, Vt <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>svd(H)  <span style="color:#75715e"># Bx3x3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 1. Calculate batched determinant</span>
</span></span><span style="display:flex;"><span>    d <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>linalg<span style="color:#f92672">.</span>det(jnp<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>), U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>)))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 2. Build batched B_diag</span>
</span></span><span style="display:flex;"><span>    ones <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>ones_like(d)
</span></span><span style="display:flex;"><span>    B_diag <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>stack([ones, ones, jnp<span style="color:#f92672">.</span>sign(d)], axis<span style="color:#f92672">=-</span><span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># 3. Scale columns of Vt.T and multiply by U.T</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Vt.T: (B, 3, 3). B_diag: (B, 3).</span>
</span></span><span style="display:flex;"><span>    R <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>matmul(Vt<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>) <span style="color:#f92672">*</span> B_diag[:, <span style="color:#66d9ef">None</span>, :], U<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Optimal translation (depends on R, so computed after it)</span>
</span></span><span style="display:flex;"><span>    t <span style="color:#f92672">=</span> centroid_Q<span style="color:#f92672">.</span>squeeze(<span style="color:#ae81ff">1</span>) <span style="color:#f92672">-</span> jnp<span style="color:#f92672">.</span>matmul(centroid_P, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>))<span style="color:#f92672">.</span>squeeze(<span style="color:#ae81ff">1</span>)  <span style="color:#75715e"># Bx3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># RMSD</span>
</span></span><span style="display:flex;"><span>    rmsd <span style="color:#f92672">=</span> jnp<span style="color:#f92672">.</span>sqrt(jnp<span style="color:#f92672">.</span>sum(jnp<span style="color:#f92672">.</span>square(jnp<span style="color:#f92672">.</span>matmul(p, R<span style="color:#f92672">.</span>transpose(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">1</span>)) <span style="color:#f92672">-</span> q), axis<span style="color:#f92672">=</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>)) <span style="color:#f92672">/</span> P<span style="color:#f92672">.</span>shape[<span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> R, t, rmsd
</span></span></code></pre></div>














<figure class="post-figure center ">
    <img src="/img/scientific-computing/kabsch-animated-protein-conformational-alignment-analysis.webp"
         alt="Animation of a protein structure being aligned using the Kabsch algorithm"
         title="Animation of a protein structure being aligned using the Kabsch algorithm"
         
         
         loading="lazy"
         class="post-image">
    
    <figcaption class="post-caption">Real-world application: Aligning protein conformations to analyze structural changes.</figcaption>
    
</figure>

<h2 id="extensions">Extensions</h2>
<p>The Kabsch algorithm has several important extensions that go beyond the formulation dealt with here:</p>
<ul>
<li><strong>Quaternion Form</strong>: The algorithm can be reformulated using quaternions for better numerical stability, particularly useful in applications requiring high precision.</li>
<li><strong>Iterative Versions</strong>: More robust variants that handle noise better and have improved scaling properties for large point sets. This also can be advantageous for setups with limited computational resources.</li>
<li><strong>Weighted Kabsch</strong>: Extensions that incorporate point weights (e.g., atomic masses in molecular dynamics). While SciPy provides a <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.align_vectors.html#scipy.spatial.transform.Rotation.align_vectors">weighted version</a>, it lacks batch processing capabilities.</li>
<li><strong>The Umeyama Algorithm</strong>: If your point sets are rotated, translated, and scaled differently, the Umeyama algorithm is the direct extension of Kabsch. It solves the same optimization problem but introduces a scaling factor $c$, finding the optimal alignment for $Q \approx c R P + t$.</li>
</ul>
<p>Several of these extensions are implemented in the <a href="/projects/kabsch-horn-cookbook/">Kabsch-Horn Cookbook</a> library, which provides differentiable Kabsch, Horn, and Umeyama alignment across NumPy, PyTorch, JAX, TensorFlow, and MLX.</p>
<h2 id="further-reading">Further Reading</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Kabsch_algorithm">Wikipedia, Kabsch Algorithm</a></li>
<li><a href="https://zalo.github.io/blog/kabsch/">Zalo on Kabsch</a>: An interactive shape matching demo.</li>
</ul>
<h3 id="original-papers">Original Papers</h3>
<ul>
<li><strong>[Kabsch 1976]</strong> Kabsch, W. (1976). &ldquo;A solution for the best rotation to relate two sets of vectors.&rdquo; <em>Acta Crystallographica Section A</em>, 32(5), 922-923. <a href="https://doi.org/10.1107/S0567739476001873">DOI: 10.1107/S0567739476001873</a>
<em>The original paper: a closed-form, non-iterative optimal-rotation solution derived via Lagrange multipliers and eigendecomposition of $\tilde{R}R$ (the SVD reformulation came later; see Arun et al. 1987).</em> See also: <a href="/notes/computational-biology/kabsch-algorithm/">paper notes</a>.</li>
<li><strong>[Kabsch 1978]</strong> Kabsch, W. (1978). &ldquo;A discussion of the solution for the best rotation to relate two sets of vectors.&rdquo; <em>Acta Crystallographica Section A</em>, 34(5), 827-828. <a href="https://doi.org/10.1107/S0567739478001680">DOI: 10.1107/S0567739478001680</a>
<em>The follow-up paper correcting for improper rotations (reflections).</em></li>
<li><strong>[Arun et al. 1987]</strong> Arun, K. S., Huang, T. S., &amp; Blostein, S. D. (1987). &ldquo;Least-Squares Fitting of Two 3-D Point Sets.&rdquo; <em>IEEE Transactions on Pattern Analysis and Machine Intelligence</em>, PAMI-9(5), 698-700. <a href="https://doi.org/10.1109/TPAMI.1987.4767965">DOI: 10.1109/TPAMI.1987.4767965</a>
<em>The first SVD-based formulation for 3D point set alignment.</em> See also: <a href="/notes/computational-biology/arun-svd-point-fitting/">paper notes</a>.</li>
<li><strong>[Horn et al. 1988]</strong> Horn, B. K. P., Hilden, H. M., &amp; Negahdaripour, S. (1988). &ldquo;Closed-form solution of absolute orientation using orthonormal matrices.&rdquo; <em>Journal of the Optical Society of America A</em>, 5(7), 1127-1135. <a href="https://doi.org/10.1364/JOSAA.5.001127">DOI: 10.1364/JOSAA.5.001127</a>
<em>The matrix square root (polar decomposition) approach to the same problem.</em> See also: <a href="/notes/computational-biology/horn-orthonormal-matrices/">paper notes</a>.</li>
<li><strong>[Horn 1987]</strong> Horn, B. K. P. (1987). &ldquo;Closed-form solution of absolute orientation using unit quaternions.&rdquo; <em>Journal of the Optical Society of America A</em>, 4(4), 629-642. <a href="https://doi.org/10.1364/JOSAA.4.000629">DOI: 10.1364/JOSAA.4.000629</a>
<em>An alternative quaternion-based closed-form solution that also handles scale.</em> See also: <a href="/notes/computational-biology/horn-absolute-orientation/">paper notes</a>.</li>
<li><strong>[Umeyama 1991]</strong> Umeyama, S. (1991). &ldquo;Least-squares estimation of transformation parameters between two point patterns.&rdquo; <em>IEEE Transactions on Pattern Analysis and Machine Intelligence</em>, 13(4), 376-380. <a href="https://doi.org/10.1109/34.88573">DOI: 10.1109/34.88573</a>
<em>The extension of the algorithm to include optimal scaling in addition to rotation and translation.</em> See also: <a href="/notes/computational-biology/umeyama-similarity-transformation/">paper notes</a>.</li>
</ul>
]]></content:encoded></item><item><title>Platinum Adatom Diffusion on Pt(100): LAMMPS Simulation</title><link>https://hunterheidenreich.com/videos/pt-adatom-diffusion/</link><pubDate>Wed, 27 Sep 2023 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/videos/pt-adatom-diffusion/</guid><description>LAMMPS molecular dynamics simulation of platinum adatom diffusion on a Pt(100) surface, showing atomic mobility mechanisms.</description><content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
			<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/1hhf5cQh56w?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
		</div>

<p>Details on the simulation can be found in the <a href="/posts/adatom-cu-diffusion/">LAMMPS Tutorial: Copper and Platinum Adatom Diffusion</a> post and the <a href="/projects/lammps-adatom-diffusion/">Automated Adatom Diffusion Workflow</a> project page.</p>
]]></content:encoded></item><item><title>Copper Adatom Diffusion on Cu(100): LAMMPS Simulation</title><link>https://hunterheidenreich.com/videos/cu-adatom-diffusion/</link><pubDate>Wed, 27 Sep 2023 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/videos/cu-adatom-diffusion/</guid><description>LAMMPS molecular dynamics simulation of copper adatom diffusion on a Cu(100) surface, showing atomic mobility mechanisms.</description><content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
			<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/nIdbNqEEPys?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
		</div>

<p>Details on the simulation can be found in the <a href="/posts/adatom-cu-diffusion/">Cu Adatom Diffusion on Cu(100)</a> post and the <a href="/projects/lammps-adatom-diffusion/">Automated Adatom Diffusion Workflow</a> project page.</p>
]]></content:encoded></item><item><title>Automated Adatom Diffusion Workflow</title><link>https://hunterheidenreich.com/projects/lammps-adatom-diffusion/</link><pubDate>Thu, 21 Sep 2023 00:00:00 +0000</pubDate><guid>https://hunterheidenreich.com/projects/lammps-adatom-diffusion/</guid><description>Python-wrapped reference implementation for surface diffusion simulations using LAMMPS and EAM potentials, with automated analysis pipelines.</description><content:encoded><![CDATA[<h2 id="overview">Overview</h2>
<p>This project provides an &ldquo;input-to-analysis&rdquo; workflow for simulating adatom diffusion on FCC metal surfaces. It demonstrates how to set up surface diffusion simulations in LAMMPS, manage EAM potentials, and parse trajectory data into energy and trajectory plots using Python. The LAMMPS input scripts are adapted from Eric N. Hahn&rsquo;s adatom tutorial; the Python analysis layer (<code>plot_energy.py</code>, <code>plot_xy.py</code>) is my own, written while in CSElab (Harvard, 2023).</p>
<p>The workflow covers two material systems (Copper (Cu) and Platinum (Pt)) providing comparative datasets that highlight how atomic mass and bonding strength affect surface dynamics.</p>
<h2 id="features">Features</h2>
<h3 id="simulation-architecture">Simulation Architecture</h3>
<p>The project separates simulation logic from analysis code:</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Directory</th>
					<th style="text-align: left">Description</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><strong><code>/adatom_cu</code></strong></td>
					<td style="text-align: left">Copper adatom diffusion on Cu(100)</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong><code>/adatom_pt</code></strong></td>
					<td style="text-align: left">Platinum adatom diffusion on Pt(100)</td>
			</tr>
	</tbody>
</table>
<p>Each directory contains:</p>
<ul>
<li><strong>LAMMPS input scripts</strong> (<code>.in</code> files) defining the physics</li>
<li><strong>EAM potential files</strong> for metallic bonding (the Cu potential is committed; the Pt potential must be downloaded separately from the NIST Interatomic Potentials Repository, so the Pt system does not run as-checked-out)</li>
<li><strong>Python analysis scripts</strong> for trajectory and energy parsing</li>
</ul>
<h3 id="key-features">Key Features</h3>
<ul>
<li><strong>EAM Potentials</strong>: Uses Embedded Atom Method alloy potentials to accurately model metallic bonding and surface energies, providing accuracy beyond simple Lennard-Jones potentials</li>
<li><strong>Automated Analysis</strong>: Python pipeline (<code>plot_energy.py</code>, <code>plot_xy.py</code>) that parses raw thermodynamic logs and trajectory dumps to generate &ldquo;health check&rdquo; dashboards</li>
<li><strong>Workflow Orchestration</strong>: Demonstrates the &ldquo;Input → Simulation → Analysis&rdquo; loop, automating the transition from raw <code>.lammpstrj</code> files to publication-ready plots</li>
<li><strong>Kokkos Support</strong>: Includes Kokkos execution commands for GPU/multi-threaded runs</li>
</ul>
<h3 id="simulation-parameters">Simulation Parameters</h3>
<table>
	<thead>
			<tr>
					<th style="text-align: left">Parameter</th>
					<th style="text-align: left">Value</th>
					<th style="text-align: left">Purpose</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><strong>Ensemble</strong></td>
					<td style="text-align: left">NVT → NVE</td>
					<td style="text-align: left">Equilibration followed by energy conservation checks</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Potential</strong></td>
					<td style="text-align: left">EAM/alloy</td>
					<td style="text-align: left">Accurate metallic bonding for surface dynamics</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Minimization</strong></td>
					<td style="text-align: left">CG (1.0e-4)</td>
					<td style="text-align: left">Remove steric overlaps before dynamics</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Timestep</strong></td>
					<td style="text-align: left">5 fs (metal units)</td>
					<td style="text-align: left">EAM-appropriate integration step</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>Trajectory dump</strong></td>
					<td style="text-align: left">every 5 steps (25 fs)</td>
					<td style="text-align: left">Tracks adatom site-to-site hops</td>
			</tr>
	</tbody>
</table>
<h2 id="usage">Usage</h2>
<p>The repository includes LAMMPS input scripts and Python analysis scripts. Run the LAMMPS scripts to generate trajectory data, then use the Python scripts to visualize the results.</p>
<h2 id="results">Results</h2>
<p>This workflow is documented in detail in companion blog posts:</p>
<ul>
<li><a href="/posts/adatom-cu-diffusion/">LAMMPS Tutorial: Copper and Platinum Adatom Diffusion</a> - Complete setup walkthrough with line-by-line script explanation and comparison of how heavier atoms behave differently on surfaces</li>
</ul>
]]></content:encoded></item></channel></rss>