-
|
Hello, I would like to use the external potential interface in eOn by setting potential = ext (or ext_pot) in my configuration file to link with a custom external calculator. However, I am unsure about the correct workflow and necessary steps to run eOn in this mode. Specifically: How should I prepare and structure the external potential program (e.g., the ext_pot executable or script)? How should the filenames from_eon_to_ext and from_ext_to_eon be handled, and what exact data should be read/written? Are there any example scripts or minimal working examples available for this interface? Any recommended environment setup or important caveats to be aware of? I tried to but eOn prints no any results. Thank you very much in advance for your help! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
|
Hi @wangsl613. Thanks for reaching out. DesignThe core idea is a simple loop:
The idea is simple and robust enough to work for NEB methods as well. External scriptFile format
The Basically:
ExampleSo this is what a nominal example will look like: [Main]
job = point
[Potential]
potential = ext
ext_pot_path = ./external_potential.pyFor this example I'll just demonstrate an ASE connection, but really anything will do. #!/usr/bin/env python3
import numpy as np
from ase import Atoms
from ase.calculators.lj import LennardJones
# --- These cannot change, they're hardcoded in EON (for now) ---
INPUT_FILE = "from_eon_to_extpot"
OUTPUT_FILE = "from_extpot_to_eon"
def main():
"""
Trivial main execution function.
1. Reads atomic structure from the input file.
2. Calculates energy and forces using an ASE calculator.
3. Writes the results to the output file.
"""
try:
# --- Read the input file written by EON ---
with open(INPUT_FILE, "r") as f:
lines = f.readlines()
# Parse the periodic box vectors (first 3 lines)
box = np.array([list(map(float, line.split())) for line in lines[0:3]])
# Parse the atomic numbers and positions
atomic_numbers = []
positions = []
for line in lines[3:]:
parts = line.split()
atomic_numbers.append(int(parts[0]))
positions.append([float(p) for p in parts[1:4]])
# --- Build the system in ASE and run the calculation ---
# Create the ASE Atoms object
atoms = Atoms(numbers=atomic_numbers, positions=positions, cell=box, pbc=True)
atoms.calc = LennardJones()
# Get the potential energy and forces
energy = atoms.get_potential_energy()
forces = atoms.get_forces()
# --- Write back for EON ---
with open(OUTPUT_FILE, "w") as f:
# Ordering matters here!!
# Write total energy on the first line
f.write(f"{energy}\n")
# Write forces for each atom on subsequent lines
for force_vector in forces:
f.write(
f"{force_vector[0]:.15f} {force_vector[1]:.15f} {force_vector[2]:.15f}\n"
)
except Exception as e:
with open("extpot_error.log", "w") as f_err:
f_err.write(f"An error occurred in external_potential.py:\n{str(e)}\n")
exit(1)
if __name__ == "__main__":
main()This can be used with a random system: To get: eonclient
EON Client
VERSION: d4c16168
BUILD DATE: Thu Jul 31 12:05:22 AM GMT 2025
OS: linux
Arch: x86_64
Hostname: rgx1gen11
PID: 53006
DIR: /eon_extpot
Loading parameter file config.ini
* [Main] job: point
* [Potential] potential: ext
* [Potential] ext_pot_path: ./external_potential.py
Energy: -16.856539034852
Max atom force: 27.553294641114
timing information:
real 0.262 seconds
user 0.226 seconds
sys 0.049 secondsSimilarly, the [Main]
job = point
[Potential]
potential = ext
ext_pot_path = ./external_potential.py
[Optimizer]
max_iterations = 200
opt_method = lbfgs
max_move = 0.05
converged_force = 0.01
[Debug]
write_movies = TrueSTDOUT Logeonclient
EON Client
VERSION: d4c16168
BUILD DATE: Thu Jul 31 12:05:22 AM GMT 2025
OS: linux
Arch: x86_64
Hostname: rgx1gen11
PID: 55113
DIR: /eon_extpot
Loading parameter file config.ini
* [Main] job: minimization
* [Potential] potential: ext
* [Potential] ext_pot_path: ./external_potential.py
* [Debug] write_movies: True
* [Optimizer] opt_method: lbfgs
* [Optimizer] converged_force: 0.01
* [Optimizer] max_iterations: 200
* [Optimizer] max_move: 0.05
Beginning minimization of pos.con
[Matter] Iter Step size ||Force|| Energy
[Matter] 0 0.00000e+00 7.79543e+01 -16.85654
[Matter] 1 4.15322e-02 2.20148e+01 -22.28107
[Matter] 2 1.64390e-02 9.45726e+00 -23.01723
[Matter] 3 1.43859e-02 2.74592e+00 -23.23933
[Matter] 4 7.39766e-03 1.84771e+00 -23.27610
[Matter] 5 1.38047e-02 2.51169e+00 -23.31275
[Matter] 6 9.17449e-03 2.02817e+00 -23.34426
[Matter] 7 3.34660e-02 3.91686e+00 -23.42580
[Matter] 8 5.31614e-03 2.85479e+00 -23.46282
[Matter] 9 2.50969e-02 3.54545e+00 -23.55450
[Matter] 10 9.22399e-03 3.10366e+00 -23.60418
[Matter] 11 1.02844e-02 3.25930e+00 -23.65208
[Matter] 12 5.00000e-02 4.33988e+00 -23.92723
[Matter] 13 5.00000e-02 5.46683e+00 -24.28135
[Matter] 14 5.00000e-02 5.45217e+00 -24.68712
[Matter] 15 2.77798e-02 3.36781e+00 -24.87176
[Matter] 16 3.56342e-02 6.63633e+00 -24.86025
[Matter] 17 2.18292e-02 1.26935e+00 -24.92660
[Matter] 18 3.79455e-03 6.54511e-01 -24.93282
[Matter] 19 3.84488e-03 4.06718e-01 -24.93625
[Matter] 20 1.77281e-03 2.02733e-01 -24.93730
[Matter] 21 1.78804e-03 1.39562e-01 -24.93766
[Matter] 22 1.10273e-03 1.55200e-01 -24.93768
[Matter] 23 4.17791e-04 2.49541e-02 -24.93774
[Matter] 24 8.16084e-05 1.36310e-02 -24.93774
[Matter] 25 1.35109e-04 8.56987e-03 -24.93774
Minimization converged within tolerence
Saving result to min.con
Final Energy: -24.937741941369072
timing information:
real 13.267 seconds
user 0.247 seconds
sys 0.049 secondsBTW, I'm converting this to a discussion (and will add documentation on this soon). Also it'd be great to hear what kind of systems you're working on. CaveatsOff the top of my head, these are some:
Let me know if there are any other questions! |
Beta Was this translation helpful? Give feedback.
Hi @wangsl613.
Thanks for reaching out.
Design
The core idea is a simple loop:
eOn writes the current atomic structure to a file (
from_eon_to_extpot).eOn executes your script specified by
ext_pot_path.Your script reads the structure, performs a calculation, and writes the resulting energy and forces to a second file (
from_extpot_to_eon).eOn reads this file and continues its work (e.g., minimization step, dynamics, etc.).
The idea is simple and robust enough to work for NEB methods as well.
External script
File format
from_eon_to_extpotis structured as follows: