Extracting per-atom potential energy with LAMMPS-Python interface

Hi LAMMPS users,

In my current project, I am using the python-LAMMPS interface from a python function embedded within my LAMMPS input script. This python function is called during each timestep and accesses/changes per-atom properties using the “lmp.gather_atoms()” and “lmp.scatter_atoms()” methods. I now want to access a per-atom potential energy variable (and corresponding per-atom id) in a similar fashion. I am accessing this atom style variable from within python via the “lmp.extract_variable()” method. However, I noticed that each processor seems to return a separate python list. Is there a way to retrieve the per-atom potential energy as a single list in python? If not, is there a way for me to combine these variables into a single variable? The python code is mpi4py enabled and I am running on LAMMPS version 20161117. Thanks for your help.

Ethan

Hi LAMMPS users,

In my current project, I am using the python-LAMMPS interface from a python
function embedded within my LAMMPS input script. This python function is
called during each timestep and accesses/changes per-atom properties using
the “lmp.gather_atoms()” and “lmp.scatter_atoms()” methods. I now want to
access a per-atom potential energy variable (and corresponding per-atom id)
in a similar fashion. I am accessing this atom style variable from within
python via the “lmp.extract_variable()” method. However, I noticed that
each processor seems to return a separate python list. Is there a way to
retrieve the per-atom potential energy as a single list in python? If not,
is there a way for me to combine these variables into a single variable?
The python code is mpi4py enabled and I am running on LAMMPS version
20161117. Thanks for your help.

two comments:

1) you should upgrade your LAMMPS version. there have been significant
improvements to the LAMMPS python interface over the last year.

2) you will have to do your own MPI communication in python to collect
the information into a properly ordered array. or extend the C library
interface and correspondingly the python wrapper.
  the procedure is straightforward: you get a suitable storage on rank
0 of size natoms ready for the data.
  then you loop over all ranks > 0 and receive a data chunk with all
atom tags and the property you are interested. those will be in
"local" order.
  then you loop over the received data (mind you, that each MPI rank
may have a different number of nlocal atoms)
  for (i=0; i < nlocal_rank; ++i) { data[tag[i]] = recv[i]; }
  now you have your data in order of the global atom id in the array
"data". this can be done more efficient (e.g. using MPI_Gatherv), but
this is the general principle.

axel.

If you read the doc headers for the extract_variable()

and gather_atoms() functions in src/library.cpp,

you will see that the former returns just a ptr to

the per-atom variable quantity, while the latter

does the gather operation Axel talked about. But

it is only for per-atom quantities that already

have a name, like x, v, charge, etc.

Depending on the application, both kinds of

returns are useful (raw ptr on each proc versus

gathered data into one big vector). Since

your Python driver is parallel, are you sure you

want one big vector on every proc?

It would not be hard to extend the interface for

gather_atoms() to enable it to work with per-atom

variables in addition to names like x,v. Possibly

just extending the atom->extract() method to

find/return the pointers for per-atom varaibles.

It would also be useful to enable this for

per-atom compute and fix info.

Steve