A unified machine-learning framework for ab initio multiscale modeling of liquids.
The 4 matches
- [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] § Materials and Methods › Training Neural cDFT. ↔ cdft-training/train_latent.py, lines 160–208 · score 0.61 · TensorFlow, Keras, activation, softplus, errors, batch
- [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] § 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
- '''
- GCMC simulation for fluids with short-ranged potentials
- Copyright (C) 2024 Anna Bui
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- '''
- import numpy as np
- # Origin Positions for Molecules
- SPCE_origin = np.array([
- [1.000000, 0.000000, 0.000000],
- [0.000000, 0.000000, 0.000000],
- [1.33331324756823743627, 0.9428161427317179, 0.000000]
- ])
- CO2_origin = np.array([
- [1.0000, 1.000000, 1.160000],
- [1.000000, 1.000000, 0.000000],
- [1.000000, 1.000000, 2.320000]
- ])
- ABC_origin = np.array([
- [0.0000, 1.0000, 0.000000],
- [0.000000, 1.050, 0.000000],
- [0.000000, 0.950, 0.00000]
- ])
- AB_origin = np.array([
- [0.0000, 1.0000, 0.000000],
- [0.000000, 1.000, 0.250000],
- ])
- EMI_origin = np.array([
- [0.000, -0.527, 1.365],
- [0.000, 1.641, 2.987],
- [0.000, 0.187, -2.389]
- ])
- # Rotation Utilities
- def genrot(alpha,beta,gamma):
- '''
- Rotates a 3D vector by the angles alpha, beta, and gamma
- '''
- # Precompute sin and cos values
- ca, sa = np.cos(alpha), np.sin(alpha)
- cb, sb = np.cos(beta), np.sin(beta)
- cg, sg = np.cos(gamma), np.sin(gamma)
- # Directly compute the combined rotation matrix
- R = np.array([
- [ca * cb, ca * sb * sg - sa * cg, ca * sb * cg + sa * sg],
- [sa * cb, sa * sb * sg + ca * cg, sa * sb * cg - ca * sg],
- [-sb, cb * sg, cb * cg]
- ])
- return R
- def quaternion_to_rotation_matrix(q):
- """
- Converts a quaternion to a 3x3 rotation matrix.
- """
- w, x, y, z = q
- return np.array([
- [1 - 2 * (y**2 + z**2), 2 * (x*y - z*w), 2 * (x*z + y*w)],
- [2 * (x*y + z*w), 1 - 2 * (x**2 + z**2), 2 * (y*z - x*w)],
- [2 * (x*z - y*w), 2 * (y*z + x*w), 1 - 2 * (x**2 + y**2)]
- ])
- def quaternion_multiply(q1, q2):
- """
- Multiplies two quaternions q1 and q2.
- q1, q2 = [w, x, y, z]
- Returns the product quaternion.
- """
- w1, x1, y1, z1 = q1
- w2, x2, y2, z2 = q2
- return np.array([
- w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2, # w
- w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2, # x
- w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2, # y
- w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2 # z
- ])
- def quaternion_rotate_vector(q, v):
- """
- Rotates a vector v using quaternion q.
- q = [w, x, y, z]
- v = [vx, vy, vz]
- Returns the rotated vector.
- """
- w, x, y, z = q
- v_q = np.array([0, *v]) # Represent vector as a pure quaternion
- q_conj = np.array([w, -x, -y, -z]) # Conjugate of quaternion q
- # Perform quaternion multiplication: q * v_q * q_conj
- rotated_v = quaternion_multiply(
- quaternion_multiply(q, v_q),
- q_conj
- )
- return rotated_v[1:] # Return the vector part
- def sample_random_quaternion():
- """
- Samples a random quaternion uniformly on the 4D hypersphere.
- """
- u1, u2, u3 = np.random.rand(3)
- w = np.sqrt(1 - u1) * np.sin(2 * np.pi * u2)
- x = np.sqrt(1 - u1) * np.cos(2 * np.pi * u2)
- y = np.sqrt(u1) * np.sin(2 * np.pi * u3)
- z = np.sqrt(u1) * np.cos(2 * np.pi * u3)
- return np.array([w, x, y, z])
- # Rotation Functions
- def RotMove_init(pos, MAXANG=np.pi, MAXCOS=1):
- """
- Performs a random rotation of the water molecule
- pos = position matrix of water molecule
- MAXANG = max angle to rotate through
- returns the modified positions
- """
- randf = np.random.rand(3)
- alpha = (2*randf[0]-1) * MAXANG
- cosbeta = (2*randf[1]-1) * MAXCOS
- gamma = (2*randf[2]-1) * MAXANG
- beta = np.arccos(cosbeta)
- # Generate rotation matrix
- Rot = genrot(alpha, beta, gamma)
- # Reference position of the first atom
- refpos = pos[0,:]
- # Shift positions to origin, rotate, and shift back
- newpos = (pos - refpos) @ Rot.T + refpos
- return newpos
- def RotMove_init_linear(pos):
- """
- Performs a random rotation for a linear molecule like CO2.
- pos = position matrix of the linear molecule
- MAXANG = max angle to rotate through
- returns the modified positions
- """
- # Generate two random angles
- randf = np.random.rand(2)
- theta = 2 * np.pi * randf[0] # Full rotation around Z-axis
- phi = np.arccos(2 * randf[1] - 1) # Random tilt for linear axis
- # Generate rotation matrix for linear molecule
- ca, sa = np.cos(theta), np.sin(theta)
- cp, sp = np.cos(phi), np.sin(phi)
- # Rotation matrix specific for a linear molecule
- R = np.array([
- [cp, -sp * sa, sp * ca],
- [sp * sa, cp * ca, -sp * ca],
- [-sp, sp * sa, cp]
- ])
- # Reference position of the first atom
- refpos = pos[0, :]
- # Shift positions to origin, rotate, and shift back
- newpos = (pos - refpos) @ R.T + refpos
- return newpos
- def RotMove_shift_linear(pos):
- """
- Performs a random rotation of a linear molecule like CO2, then shifts.
- Ensures uniform sampling of orientations on a sphere using quaternions.
- pos = position matrix of the linear molecule (shape: Nx3)
- returns the modified positions (shape: Nx3)
- """
- # Step 1: Sample a random quaternion and convert to a rotation matrix
- q = sample_random_quaternion()
- R = quaternion_to_rotation_matrix(q)
- # Step 2: Rotate and shift the molecule
- refpos = pos[0, :] # Center the molecule at the origin
- shifted_pos = pos - refpos
- rotated_pos = shifted_pos @ R.T # Apply the rotation
- shift_vector = np.array([10.0, 10.0, 10.0]) # Arbitrary shift vector
- newpos = rotated_pos + refpos + shift_vector
- return newpos
- def RotMove_shift_non_linear(pos):
- """
- Applies a random rotation to a non-linear molecule and shifts it.
- Uses quaternion-based rotations for uniform sampling.
- pos = position matrix of the molecule (shape: Nx3)
- Returns the modified positions (shape: Nx3).
- """
- # Step 1: Sample a random quaternion
- q = sample_random_quaternion()
- # Step 2: Rotate each atom using the quaternion
- refpos = np.mean(pos, axis=0) # Geometric center of the molecule
- shifted_pos = pos - refpos # Shift to center
- rotated_pos = np.array([quaternion_rotate_vector(q, atom) for atom in shifted_pos])
- # Step 3: Shift the molecule to a new location
- shift_vector = np.array([10.0, 10.0, 10.0]) # Arbitrary shift vector
- newpos = rotated_pos + refpos + shift_vector
- return newpos
- # Random Molecule Generation
- def generate_random_linear_triatomic(bond_length):
- """
- Generates random positions for a linear CO2 molecule centered at the origin
- with the specified bond length and uniformly distributed orientation.
- Parameters:
- bond_length (float): Distance between the carbon and each oxygen atom.
- Returns:
- np.ndarray: A 3x3 array with positions of C, C, and O atoms.
- """
- # Generate a random orientation vector on the sphere
- z = 2 * np.random.rand() - 1 # Random z component in range [-1, 1]
- theta = 2 * np.pi * np.random.rand() # Azimuthal angle in range [0, 2*pi]
- r = np.sqrt(1 - z**2) # Radius in the xy-plane for a unit vector
- # Orientation vector components
- orientation_vec = np.array([r * np.cos(theta), r * np.sin(theta), z])
- # Define positions based on the bond length
- # Carbon atom is at the origin
- carbon_pos = np.array([2.0, 2.0, 2.0])
- # Oxygen atoms positioned along the orientation vector
- oxygen_pos1 = carbon_pos + bond_length * orientation_vec
- oxygen_pos2 = carbon_pos - bond_length * orientation_vec
- # Step 3: Combine positions into a single array
- molecule_pos = np.vstack([carbon_pos, oxygen_pos1, oxygen_pos2])
- return molecule_pos
tools.py at commit f55b313, under GPL-3.0 · at the source
Overview
- Yusuf Hamied Department of Chemistry, University of Cambridge, Cambridge CB2 1EW, United Kingdom
- Department of Chemistry, Durham University, Durham DH1 3LE, United Kingdom
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
9e759ff4e82b20f9dd1475e5037c4ca9482cd1ec, 13 August 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
8 files
- cdft-analysis/
energy_utils.py — Python, 169 lines - cdft-analysis/
minimise.py — Python, 188 lines, 1 match - cdft-analysis/
minimise_slit.ipynb — Jupyter, 224 lines - cdft-analysis/
neural_utils.py — Python, 604 lines, 1 match - cdft-analysis/
plot_utils.py — Python, 52 lines - cdft-training/
train_latent.py — Python, 421 lines, 1 match - LICENSE — License, 674 lines
- README.md — Text, 52 lines
annatbui/GCMC
f55b31350e67a976f28f19313a907cae4a220eda, 26 January 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
16 files
- src/
constants.py — Python, 25 lines - src/
external_potentials.py — Python, 1,320 lines - src/
gcmc_ff.py — Python, 1,145 lines - src/
gcmc_ff_molecule.py — Python, 801 lines - src/
gcmc_re.py — Python, 325 lines - src/
main.py — Python, 76 lines - src/
molecule_base.py — Python, 170 lines - src/
potentials.py — Python, 130 lines - src/
read_input.py — Python, 28 lines - src/
tools.py — Python, 273 lines, 1 match - src/
utils/ — Python, 156 linesget_density_profile.py - src/
utils/ — Python, 240 linesget_profiles.py - src/
utils/ — Python, 61 linesplot_Vext.py - src/
utils/ — Python, 52 linesplot_potential.py - LICENSE — License, 674 lines
- README.md — Text, 62 lines
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
- zenodo:21245362 — at Zenodo; found in “Data, Materials, and Software Availability”
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://
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://
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/
url = {https://
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/
VL - 123
IS - 30
SP - e2610049123
SN - 0027-8424
PB - National Academy of Sciences
DO - 10.1073/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1073/
"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":
"volume": "123",
"issue": "30",
"page": "e2610049123",
"DOI": "10.1073/
"PMID": "42497203",
"PMCID": "PMC13416084",
"ISSN": "0027-8424",
"publisher": "National Academy of Sciences",
"URL": "https://
"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. BIn 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 computationIn common: computational, 8 references
- [3] doi: [code]
- Going deeper with morphologically detailed neural networks by simulation-based gradient propagationJournal: Frontiers in computational neuroscienceIn 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 communicationsIn 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 reportsIn common: Keras, TensorFlow, Matplotlib, 1 other tool, computational
- [6] doi: [code]
- Real-time closed-loop feedback system for mouse mesoscale cortical signal and movement controlJournal: eLifeIn 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 oneIn 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 biologyIn 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 advancesIn 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.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 2 repositories of the authors' code, each at its verified commit and with its license, 20 scripts, and 4 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:adb3991a632c2b6d…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
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.
