pyiron_atomistics
pyiron_atomistics copied to clipboard
Preserve identation in Lammps
Dear all,
in our weekly hackathon we use the PYTHON package of lammps to insert a post_force_callback in Lammps to modify the forces of the atoms.
To build a first prototype we wanted to load an existing control.inp file and use it:
job.input.control.read_input(file_name='control_mwe.inp')
which works fine on first sight.
To work properly in Lammps, the post_force_callback has to be a python string with correct indentation. Unfortunately in the pyiron-written control.inp the indentation is removed (which was fine in the original file we loaded) and so Lammps complains about the malformed python string on runtime and crashes. (I guess this might also happen if we modify the control.inp directly in pyiron, but this has to be checked tomorrow.)
Does anyone know if there is an easy way to preserve the indentation?
Best regards, Florian
Essentially the codeblock we want to insert into the pyiron-written control.inp looks like this:
python post_force_callback here """
from lammps import lammps
import numpy as np
L = lammps()
def force(x):
return np.zeros_like(x)
def post_force_callback(lammps_ptr, vflag):
lmp = lammps(ptr=lammps_ptr)
nlocal = lmp.extract_global("nlocal")
nghost = lmp.extract_global("nghost")
#mass = lmp.numpy.extract_atom("mass")
x = lmp.numpy.extract_atom("x", nelem=nlocal+nghost, dim=3)
f = lmp.numpy.extract_atom("f", nelem=nlocal+nghost, dim=3)
f[:, 2] += force(x)
#t = lmp.extract_global("ntimestep")
#print("### END OF FORCE ###", t)
# access LAMMPS state using Python interface
"""
fix pf all python/invoke 1 post_force post_force_callback
Likely the fix has to be applied
https://github.com/pyiron/pyiron_base/blob/ef4b49b17851d2a0975d3d6c39dd52ccd95ee3e4/pyiron_base/generic/parameters.py#L928
but I can't dig deeper right now.
We had a similar issue https://github.com/pyiron/pyiron_atomistics/issues/598 I guess the quickest way to fix this is job.input.control.load_string()
We had a similar issue #598 I guess the quickest way to fix this is
job.input.control.load_string()
load_string passes the lines through _lines_to_dict the same way as read_input, so it'll probably also comes out the same way.
It looks like it can be more easily done with fix_set_external, even though it works only for 1 core for now.