# Computation normal vectors

Hi everybody,

I am a beginner with lammps and I am trying to implement a new potential. This one is particular because the normal vectors of each pair of atoms is required, in order to calculate the force between the pair. My problem is the following :

Consider a system with N atoms (own). I compute the normal of each atom with the position of the 3 nearest neighbors. After that, I am looping over all the atoms to apply the potential with their neighbors. Unfortunately, the firstneigh list of each atom contains ghost atoms, whose normal is not calculated. I could calculate the normal of all the atoms (ghost + own) but it would take a huge amount of time. Given that, and thanks to the periodicity of the system, I would like to know the atom (included in my primary cell, i.e one of the N declared) that correspond to ghost atom and then use the normal of this atom instead of the normal of the ghost one.

More easily, I am looking for a function : GetOwnFromGhost

Thank you very much

Kilian THOMAS

If you run in parallel, there will typically be no atom

that you own that is an image (in a periodic sense) of

It sounds like what you want is to acquire the normal

vectors that are computed and stored by the owner

of each of the ghost atoms. You can do that within

a pair style by calling comm->forward_comm_pair()

which updates ghost atoms with values stored by each

ghost’s owner.

You have to provide a pack and unpack function for the normal

vector. See pair_eam.cpp for how it does this.

And see in the constructor how it sets comm_forward = 1.

You will need 3 if you are packing a vector.

Steve

Dear Steve,

If I am not using parallelism, is there a way to find directly the own atom?

Up to now, I calculate the normal of each own atom from the 3 nearest neighbors and store them into a new attribut of the class Atom.

Unfortunately, I don’t understand the pack and unpack function.
For example, in the PairEAM, we pack the fp into the buffer?

int PairEAM::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
{
int i,j,m;

m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = fp[j];
}
return m;
}

Then, in my case, should I pack 3 vectors into the buffer ? :
atom[i].normal[0]

atom[i].normal[1]
atom[i].normal[2]

And for the unpack function, should I store the datas from the buffer into atom[i].normal?

best

Kilian

Dear Steve,

If I am not using parallelism, is there a way to find directly the own atom?

but *LAMMPS* is managing its simulation data always as if this was a
parallel run. moreover, LAMMPS doesn't apply minimum image conventions
but rather uses copies (aka ghosts) to represent them within the
cutoff.

Up to now, I calculate the normal of each own atom from the 3 nearest
neighbors and store them into a new attribut of the class Atom.
Unfortunately, I don't understand the pack and unpack function.
For example, in the PairEAM, we pack the fp into the buffer?

EAM does two communications. one is referred to as a forward
communication, the other as a reverse.
- forward communication transfers per atom properties from owned (aka
local) atoms to ghost atoms
- reverse communications transfers data from ghost atoms to local atoms.

the reverse communication is only needed if newton's 3rd law is used
for pairwise interactions, i.e. each pair that straddles the subdomain
boundaries is included in a neighbor list only once, even if one of
the atoms is a ghost. hence the subdomain, that holds this specific
ghost atom as a local atom needs to receive the additional data.

a reverse communication is also used to collect forces from ghost
atoms (also when newton's 3rd law is on for non-bonded pairs.
otherwise the pair is included twice and only the contribution to the
respective local atom is stored).

HTH,
axel.

Then, in my case, should I pack 3 vectors into the buffer ? :
atom[i].normal[0]

atom[i].normal[1]
atom[i].normal[2]

yes, that is the way to do it. Grep for pack_forward_comm in fixes

and pair styles and you will see many examples.

Steve

Dear Axel and Steve,

Thank you for all these explanations. I finally managed to solved my problem using the pack and unpack forward functions.