compute_peratom()

Dear Lammps users,

I searched on the mailing list for a similar topic but I couldn't find anything. I hope it is not redundant.
I'd like to understand a bit more the structure of a typical "per atom-type" compute since I am trying to write one on my own.

Looking at the "compute_stress_atom.cpp" I was wondering on how the function pack_reverse_comm(n, first, *buf) works :

/* ---------------------------------------------------------------------- */

int ComputeStressAtom::pack_reverse_comm(int n, int first, double *buf)
{
int i,m,last;

m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = stress[i][0];
buf[m++] = stress[i][1];
buf[m++] = stress[i][2];
buf[m++] = stress[i][3];
buf[m++] = stress[i][4];
buf[m++] = stress[i][5];
}
return m;
}

/* ---------------------------------------------------------------------- */

For instance: what are the values of "n" and "first" that the function calls ?
Also: the array stress [i][j] is computed considering the local index i of the atoms in the compute_peratom().
How is then performed the link between local and global ID (since the output refers to the global ID) ?

All the best,
Gianluca

first off, in LAMMPS a “reverse” communication is an exchange of data between subdomain, where information stored with “ghost” atoms is summed on their corresponding local atoms. A “forward” communication is when data from local atoms is communicated to their “ghost” copies, either locally or on remote subdomains. the Comm class has the implementation of these communication patterns.

For stress/atom, the reverse communication is needed, in case any of the “newton” flags is on, which means, that forces between pairs of atoms (or bonds/angles/dihedrals/impropers) that straddle subdomain boundaries are computed only once and thus the results also stored on ghost atoms (with both newton flags off, each of these computations is done multiple times and then only the components of the local atom is stored and thus no reverse communication needed.

For stress, the per-atom stress data is tallied into the corresponding per atom tensor arrays during the force computation, and then summed into the local atoms with the reverse communication. the code in the Comm class “knows” how many ghost atoms exist between two subdomains and the “pack” functions are then used to collect data for them into communication buffers. the pack is done for each atom, thus you see the 6 tensor elements being added and the counter being incremented accordingly. you have to set how many items (6) are added per atom in the communication in the constructor.

Output is done by outputting the data of each subdomain consecutively, and since each atom carries the “tag” property, which contains the atom ID, it can easily be output. Extra effort (and memory) is therefore needed, if you want to output data in a dump in a sorted fashion.

Hope that answers your questions,
Axel.