OSCR

A unified machine-learning framework for ab initio multiscale modeling of liquids.

Code ↔ Paper

4 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 4 matches
  1. [1] § Materials and Methods › Generation of Training Data for Neural cDFT. ↔ src/tools.py, lines 239–272 · score 0.68 · oxygen atom, carbon atom, molecular centers, uniformly
  2. [2] § Materials and Methods › Training Neural cDFT. ↔ cdft-training/train_latent.py, lines 160–208 · score 0.61 · TensorFlow, Keras, activation, softplus, errors, batch
  3. [3] § Materials and Methods › Training Neural cDFT. ↔ cdft-analysis/neural_utils.py, lines 201–249 · score 0.60 · TensorFlow, Keras, activation, softplus, errors, batch
  4. [4] § Materials and Methods › Evaluating Neural cDFT. ↔ cdft-analysis/minimise.py, lines 40–116 · score 0.59 · Picard iteration, Lagrange multiplier, neural, cDFT

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 273 lines · 8 KB · GPL-3.0 · 1 match

  1. '''
  2. GCMC simulation for fluids with short-ranged potentials
  3. Copyright (C) 2024 Anna Bui
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. '''
  15. import numpy as np
  16. # Origin Positions for Molecules
  17. SPCE_origin = np.array([
  18. [1.000000, 0.000000, 0.000000],
  19. [0.000000, 0.000000, 0.000000],
  20. [1.33331324756823743627, 0.9428161427317179, 0.000000]
  21. ])
  22. CO2_origin = np.array([
  23. [1.0000, 1.000000, 1.160000],
  24. [1.000000, 1.000000, 0.000000],
  25. [1.000000, 1.000000, 2.320000]
  26. ])
  27. ABC_origin = np.array([
  28. [0.0000, 1.0000, 0.000000],
  29. [0.000000, 1.050, 0.000000],
  30. [0.000000, 0.950, 0.00000]
  31. ])
  32. AB_origin = np.array([
  33. [0.0000, 1.0000, 0.000000],
  34. [0.000000, 1.000, 0.250000],
  35. ])
  36. EMI_origin = np.array([
  37. [0.000, -0.527, 1.365],
  38. [0.000, 1.641, 2.987],
  39. [0.000, 0.187, -2.389]
  40. ])
  41. # Rotation Utilities
  42. def genrot(alpha,beta,gamma):
  43. '''
  44. Rotates a 3D vector by the angles alpha, beta, and gamma
  45. '''
  46. # Precompute sin and cos values
  47. ca, sa = np.cos(alpha), np.sin(alpha)
  48. cb, sb = np.cos(beta), np.sin(beta)
  49. cg, sg = np.cos(gamma), np.sin(gamma)
  50. # Directly compute the combined rotation matrix
  51. R = np.array([
  52. [ca * cb, ca * sb * sg - sa * cg, ca * sb * cg + sa * sg],
  53. [sa * cb, sa * sb * sg + ca * cg, sa * sb * cg - ca * sg],
  54. [-sb, cb * sg, cb * cg]
  55. ])
  56. return R
  57. def quaternion_to_rotation_matrix(q):
  58. """
  59. Converts a quaternion to a 3x3 rotation matrix.
  60. """
  61. w, x, y, z = q
  62. return np.array([
  63. [1 - 2 * (y**2 + z**2), 2 * (x*y - z*w), 2 * (x*z + y*w)],
  64. [2 * (x*y + z*w), 1 - 2 * (x**2 + z**2), 2 * (y*z - x*w)],
  65. [2 * (x*z - y*w), 2 * (y*z + x*w), 1 - 2 * (x**2 + y**2)]
  66. ])
  67. def quaternion_multiply(q1, q2):
  68. """
  69. Multiplies two quaternions q1 and q2.
  70. q1, q2 = [w, x, y, z]
  71. Returns the product quaternion.
  72. """
  73. w1, x1, y1, z1 = q1
  74. w2, x2, y2, z2 = q2
  75. return np.array([
  76. w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2, # w
  77. w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2, # x
  78. w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2, # y
  79. w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2 # z
  80. ])
  81. def quaternion_rotate_vector(q, v):
  82. """
  83. Rotates a vector v using quaternion q.
  84. q = [w, x, y, z]
  85. v = [vx, vy, vz]
  86. Returns the rotated vector.
  87. """
  88. w, x, y, z = q
  89. v_q = np.array([0, *v]) # Represent vector as a pure quaternion
  90. q_conj = np.array([w, -x, -y, -z]) # Conjugate of quaternion q
  91. # Perform quaternion multiplication: q * v_q * q_conj
  92. rotated_v = quaternion_multiply(
  93. quaternion_multiply(q, v_q),
  94. q_conj
  95. )
  96. return rotated_v[1:] # Return the vector part
  97. def sample_random_quaternion():
  98. """
  99. Samples a random quaternion uniformly on the 4D hypersphere.
  100. """
  101. u1, u2, u3 = np.random.rand(3)
  102. w = np.sqrt(1 - u1) * np.sin(2 * np.pi * u2)
  103. x = np.sqrt(1 - u1) * np.cos(2 * np.pi * u2)
  104. y = np.sqrt(u1) * np.sin(2 * np.pi * u3)
  105. z = np.sqrt(u1) * np.cos(2 * np.pi * u3)
  106. return np.array([w, x, y, z])
  107. # Rotation Functions
  108. def RotMove_init(pos, MAXANG=np.pi, MAXCOS=1):
  109. """
  110. Performs a random rotation of the water molecule
  111. pos = position matrix of water molecule
  112. MAXANG = max angle to rotate through
  113. returns the modified positions
  114. """
  115. randf = np.random.rand(3)
  116. alpha = (2*randf[0]-1) * MAXANG
  117. cosbeta = (2*randf[1]-1) * MAXCOS
  118. gamma = (2*randf[2]-1) * MAXANG
  119. beta = np.arccos(cosbeta)
  120. # Generate rotation matrix
  121. Rot = genrot(alpha, beta, gamma)
  122. # Reference position of the first atom
  123. refpos = pos[0,:]
  124. # Shift positions to origin, rotate, and shift back
  125. newpos = (pos - refpos) @ Rot.T + refpos
  126. return newpos
  127. def RotMove_init_linear(pos):
  128. """
  129. Performs a random rotation for a linear molecule like CO2.
  130. pos = position matrix of the linear molecule
  131. MAXANG = max angle to rotate through
  132. returns the modified positions
  133. """
  134. # Generate two random angles
  135. randf = np.random.rand(2)
  136. theta = 2 * np.pi * randf[0] # Full rotation around Z-axis
  137. phi = np.arccos(2 * randf[1] - 1) # Random tilt for linear axis
  138. # Generate rotation matrix for linear molecule
  139. ca, sa = np.cos(theta), np.sin(theta)
  140. cp, sp = np.cos(phi), np.sin(phi)
  141. # Rotation matrix specific for a linear molecule
  142. R = np.array([
  143. [cp, -sp * sa, sp * ca],
  144. [sp * sa, cp * ca, -sp * ca],
  145. [-sp, sp * sa, cp]
  146. ])
  147. # Reference position of the first atom
  148. refpos = pos[0, :]
  149. # Shift positions to origin, rotate, and shift back
  150. newpos = (pos - refpos) @ R.T + refpos
  151. return newpos
  152. def RotMove_shift_linear(pos):
  153. """
  154. Performs a random rotation of a linear molecule like CO2, then shifts.
  155. Ensures uniform sampling of orientations on a sphere using quaternions.
  156. pos = position matrix of the linear molecule (shape: Nx3)
  157. returns the modified positions (shape: Nx3)
  158. """
  159. # Step 1: Sample a random quaternion and convert to a rotation matrix
  160. q = sample_random_quaternion()
  161. R = quaternion_to_rotation_matrix(q)
  162. # Step 2: Rotate and shift the molecule
  163. refpos = pos[0, :] # Center the molecule at the origin
  164. shifted_pos = pos - refpos
  165. rotated_pos = shifted_pos @ R.T # Apply the rotation
  166. shift_vector = np.array([10.0, 10.0, 10.0]) # Arbitrary shift vector
  167. newpos = rotated_pos + refpos + shift_vector
  168. return newpos
  169. def RotMove_shift_non_linear(pos):
  170. """
  171. Applies a random rotation to a non-linear molecule and shifts it.
  172. Uses quaternion-based rotations for uniform sampling.
  173. pos = position matrix of the molecule (shape: Nx3)
  174. Returns the modified positions (shape: Nx3).
  175. """
  176. # Step 1: Sample a random quaternion
  177. q = sample_random_quaternion()
  178. # Step 2: Rotate each atom using the quaternion
  179. refpos = np.mean(pos, axis=0) # Geometric center of the molecule
  180. shifted_pos = pos - refpos # Shift to center
  181. rotated_pos = np.array([quaternion_rotate_vector(q, atom) for atom in shifted_pos])
  182. # Step 3: Shift the molecule to a new location
  183. shift_vector = np.array([10.0, 10.0, 10.0]) # Arbitrary shift vector
  184. newpos = rotated_pos + refpos + shift_vector
  185. return newpos
  186. # Random Molecule Generation
  187. def generate_random_linear_triatomic(bond_length):
  188. """
  189. Generates random positions for a linear CO2 molecule centered at the origin
  190. with the specified bond length and uniformly distributed orientation.
  191. Parameters:
  192. bond_length (float): Distance between the carbon and each oxygen atom.
  193. Returns:
  194. np.ndarray: A 3x3 array with positions of C, C, and O atoms.
  195. """
  196. # Generate a random orientation vector on the sphere
  197. z = 2 * np.random.rand() - 1 # Random z component in range [-1, 1]
  198. theta = 2 * np.pi * np.random.rand() # Azimuthal angle in range [0, 2*pi]
  199. r = np.sqrt(1 - z**2) # Radius in the xy-plane for a unit vector
  200. # Orientation vector components
  201. orientation_vec = np.array([r * np.cos(theta), r * np.sin(theta), z])
  202. # Define positions based on the bond length
  203. # Carbon atom is at the origin
  204. carbon_pos = np.array([2.0, 2.0, 2.0])
  205. # Oxygen atoms positioned along the orientation vector
  206. oxygen_pos1 = carbon_pos + bond_length * orientation_vec
  207. oxygen_pos2 = carbon_pos - bond_length * orientation_vec
  208. # Step 3: Combine positions into a single array
  209. molecule_pos = np.vstack([carbon_pos, oxygen_pos1, oxygen_pos2])
  210. return molecule_pos

tools.py at commit f55b313, under GPL-3.0 · at the source

Overview

  1. Yusuf Hamied Department of Chemistry, University of Cambridge, Cambridge CB2 1EW, United Kingdom
  2. Department of Chemistry, Durham University, Durham DH1 3LE, United Kingdom
Institutions: Durham University (United Kingdom); University of Cambridge (United Kingdom)
Dates: received 20 March 2026; accepted 24 June 2026; published online 24 July 2026; in print 28 July 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1073/pnas.2610049123 · PMID 42497203 · PMCID PMC13416084 · OpenAlex W7170505220
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: computational (subfield)
Keywords: machine-learned interatomic potentials, classical density functional theory, first-principles modeling, phase transition, supercritical fluids
Topic: Machine Learning in Materials Science (Materials Chemistry, Materials Science), according to OpenAlex
Funding: UKRI | Engineering and Physical Sciences Research Council (SRC) (EP/X035859, EP/F036884/1); Royal Society (The Royal Society) (URF\R1\211144)
Citations: cited by 2 papers (Europe PMC); 138 references in the paper

Abstract

Understanding and predicting the behavior of liquid matter across length scales—using only the microscopic interactions encoded in the Schrödinger equation—remains a central challenge in the physical sciences. Achieving this goal requires not only an accurate and efficient description of intermolecular forces but also a consistent framework that bridges the micro-, meso-, and macroscales. Here, by combining machine-learned interatomic potentials (MLIPs) with neural classical density functional theory (cDFT), we present such a framework. MLIPs trained on quantum-mechanical energies and forces are used to generate inhomogeneous density profiles, which then serve as the training data for neural cDFT. The resulting ab initio neural cDFT is more computationally efficient than molecular simulations and provides a conceptually transparent route to the thermodynamics of both homogeneous and planar inhomogeneous systems. We demonstrate the approach for both water and carbon dioxide using several exchange–correlation functionals. Beyond accurately reproducing—at the level of the underlying approximate electronic structure—bulk equations of state and liquid–vapor phase diagrams, ab initio neural cDFT predicts, from first principles, how confinement modifies liquid–vapor coexistence in water. It also captures complex behavior in supercritical carbon dioxide such as the Fisher–Widom and Widom lines. While current applications are limited to bulk fluids and planar geometries, this approach establishes a general first-principles route to multiscale modeling of fluids by unifying two independently developed machine-learning paradigms. This work represents an important step toward generalizing cDFT beyond simple empirical potentials to chemically complex systems.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 4 matches between paragraphs and lines of code.

annatbui/mlip-neuraldft

License: GPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 9e759ff4e82b20f9dd1475e5037c4ca9482cd1ec, 13 August 2026
Languages: Python (5), Jupyter (1)
Size: 25 files, 6 scripts
Software Heritage: not archived
Found in: “Data, Materials, and Software Availability”
Holds: README, license file, 1 notebook
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (6 files), Matplotlib (3 files), SciPy (3 files), TensorFlow (3 files), Keras (2 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
8 files

annatbui/GCMC

License: GPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: f55b31350e67a976f28f19313a907cae4a220eda, 26 January 2026
Languages: Python (14)
Size: 26 files, 14 scripts
Software Heritage: not archived
Found in: the references
Holds: README, license file, environment (dependencies/conda-env.yml)
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: NumPy (11 files), Matplotlib (3 files), SciPy (2 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
16 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 20 scripts, each with its path and the digest of its content;
  • 4 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data, Materials, and Software Availability

The code used to train the models and perform neural cDFT calculations in this study is available on Github https://github.com/annatbui/mlip-neuraldft (137). Example simulation inputs, the MLIP models, and the training data are available on Zenodo https://zenodo.org/records/21245362 (138).

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 2 authors, 5 keywords, 2 funders, 86 references.

Cite

This paper

Bui, A. T., & Cox, S. J. (2026). A unified machine-learning framework for ab initio multiscale modeling of liquids. Proceedings of the National Academy of Sciences of the United States of America, 123(30), e2610049123. https://doi.org/10.1073/pnas.2610049123

BibTeX

@article{bui2026unified,
author = {Bui, Anna T and Cox, Stephen J},
title = {{A unified machine-learning framework for ab initio multiscale modeling of liquids}},
journal = {Proceedings of the National Academy of Sciences of the United States of America},
year = {2026},
month = jul,
volume = {123},
number = {30},
pages = {e2610049123},
publisher = {National Academy of Sciences},
issn = {0027-8424},
doi = {10.1073/pnas.2610049123},
url = {https://doi.org/10.1073/pnas.2610049123},
pmid = {42497203},
pmcid = {PMC13416084}
}

RIS

TY - JOUR
AU - Bui, Anna T
AU - Cox, Stephen J
TI - A unified machine-learning framework for ab initio multiscale modeling of liquids
T2 - Proceedings of the National Academy of Sciences of the United States of America
J2 - Proc Natl Acad Sci U S A
PY - 2026
DA - 2026/07/24
VL - 123
IS - 30
SP - e2610049123
SN - 0027-8424
PB - National Academy of Sciences
DO - 10.1073/pnas.2610049123
UR - https://doi.org/10.1073/pnas.2610049123
LA - en
ER -

CSL-JSON

{
"id": "10.1073/pnas.2610049123",
"type": "article-journal",
"title": "A unified machine-learning framework for ab initio multiscale modeling of liquids",
"container-title": "Proceedings of the National Academy of Sciences of the United States of America",
"author": [
{
"family": "Bui",
"given": "Anna T"
},
{
"family": "Cox",
"given": "Stephen J"
}
],
"container-title-short": "Proc Natl Acad Sci U S A",
"volume": "123",
"issue": "30",
"page": "e2610049123",
"DOI": "10.1073/pnas.2610049123",
"PMID": "42497203",
"PMCID": "PMC13416084",
"ISSN": "0027-8424",
"publisher": "National Academy of Sciences",
"URL": "https://doi.org/10.1073/pnas.2610049123",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
24
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1021/acs.jpcb.6c01662 [code]
Metadensity Functional Learning for Classical Fluids: Regularizing with Pair Correlations.
Journal: The journal of physical chemistry. B
In common: 15 references
[2] doi:10.1021/acs.jctc.6c00146
qNEP: A Highly Efficient Neuroevolution Potential with Dynamic Charges for Large-Scale Atomistic Simulations.
Journal: Journal of chemical theory and computation
In common: computational, 8 references
[3] doi: [code]
Going deeper with morphologically detailed neural networks by simulation-based gradient propagation
Journal: Frontiers in computational neuroscience
In common: Keras, TensorFlow, SciPy, 2 other tools, computational
[4] doi:10.1038/s41467-026-73347-y [code]
A week in the life of the human brain reveals stable states punctuated by chaotic-like transitions.
Journal: Nature communications
In common: Keras, TensorFlow, SciPy, 2 other tools, computational
[5] doi:10.1038/s41598-026-51212-8 [code]
Uncertainty aware machine learning for bridging simulation and experiment in high throughput materials characterization.
Journal: Scientific reports
In common: Keras, TensorFlow, Matplotlib, 1 other tool, computational
[6] doi: [code]
Real-time closed-loop feedback system for mouse mesoscale cortical signal and movement control
Journal: eLife
In common: Keras, TensorFlow, SciPy, 2 other tools
[7] doi:10.1371/journal.pone.0356243 [code]
Functional organization and natural scene responses across mouse visual cortical areas revealed with encoding manifolds.
Journal: PloS one
In common: Keras, TensorFlow, SciPy, 2 other tools
[8] doi:10.1038/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: Keras, TensorFlow, SciPy, 2 other tools
[9] doi:10.1162/imag.a.1366 [code]
MICAFlow: Fast and robust MRI preprocessing bridging research neuroimaging and clinical practice.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Keras, TensorFlow, SciPy, 2 other tools
[10] doi:10.1126/sciadv.aee6952 [code]
Wafer-scale SOT-MRAM for analog crossbar array applications.
Journal: Science advances
In common: Keras, TensorFlow, SciPy, 2 other tools

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.