Question:fix_store

Hello, LAMMPS users & Developers:
In the pair_lj_cut.cpp, I use class fix_store to store the original coords of atoms:
double **xoriginal = fix_coord->astore;

for (int i = 0; i < nlocal; i++)
{
if (mask[i] & groupbit)
domain->unmap(x[i],image[i],xoriginal[i]);
else xoriginal[i][0] = xoriginal[i][1] = xoriginal[i][2] = 0.0;
}

I can get the right local atom's original coords. But I also want to **get the original coords of** **neighbor atoms**(but some of these atoms are ghost atoms) : for (ii = 0; ii < inum; ii++) { i = ilist[ii]; Xtmp = xoriginal[i][0]; Ytmp = xoriginal[i][1]; Ztmp = xoriginal[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; **xoriginal[j][0]** **// not always right!** } }

How can I do this?

Thank you
Young

Hello, LAMMPS users & Developers:
In the pair_lj_cut.cpp, I use class fix_store to store the original coords of atoms:
double **xoriginal = fix_coord->astore;

for (int i = 0; i < nlocal; i++)
{
if (mask[i] & groupbit)
domain->unmap(x[i],image[i],xoriginal[i]);
else xoriginal[i][0] = xoriginal[i][1] = xoriginal[i][2] = 0.0;
}

I can get the right local atom's original coords. But I also want to **get the original coords of** **neighbor atoms**(but some of these atoms are ghost atoms) : for (ii = 0; ii < inum; ii++) { i = ilist[ii]; Xtmp = xoriginal[i][0]; Ytmp = xoriginal[i][1]; Ztmp = xoriginal[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; **xoriginal[j][0]** **// not always right!** } }

How can I do this?

you need to define/allocate another per-atom as part of the class and with the dimension of atom->nmax (and grow it, if needed, there are examples in other pair styles for such storage. you copy over the data from fix store, since this is only of the dimension nlocal and does not include ghost atoms. finally, you need to enable a forward communication to send the data from 0 <= i < nlocal to nlocal <= i < nlocal+nghost and for that you need to add suitable pack_forward_comm() and unpack_forward_comm() functions and finally, call comm->forward_comm_pair(this) after having copied the stored data to the managed array dimensioned for local plus ghost.

you can find an example for forward communication in pair style EAM where some data is computed for local atoms only (into the fp[] array) and then sent to the corresponding ghost atoms via forward communication and then accessed also from ghost atoms.

axel.

Sorry, I’m still a little confused.

  1. Do I need to modify the fix_store.cpp?
  2. I have checked the pair_eam.cpp.
    int PairEAM::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
    this function is not used in the pair_eam.cpp. And where are parameters like int n come from?

在 2019-10-29 23:26:02,“Axel Kohlmeyer” <[email protected]…24…> 写道:

Sorry, I’m still a little confused.

  1. Do I need to modify the fix_store.cpp?

no. this is a modification of the pair style.

  1. I have checked the pair_eam.cpp.
    int PairEAM::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
    this function is not used in the pair_eam.cpp. And where are parameters like int n come from?

no, but is is called indirectly when you execute comm->forward_comm_pair(this). this is why you pass “this” as an argument, so that the comm class has a handle on which pair style is doing the packing of data into a communication buffer.
n is the number of (local) atoms, that need their data to be communicated in the forward communication, list are the indices, buf is a storage buffer.
the other two won’t be needed in your case.

since you need to send three items per atom, you also need to set
comm_forward = 3;

in the pair style constructor, so that the Comm class will allocate a large enough buffer for communication.

axel.

  1. So I need to create a array (eg.xoriginal_all)dimensioned for local + ghost and copy the data from _*_xoriginal to xoriginal_all.* Then execute comm->forward_comm_pair(this)?
  2. function pack_reverse_comm() and unpack_reverse_comm() are also needed ?

在 2019-10-31 18:56:39,“Axel Kohlmeyer” <[email protected]…24…> 写道:

  1. So I need to create a array (eg.xoriginal_all)dimensioned for local + ghost and copy the data from _*_xoriginal to xoriginal_all.* Then execute comm->forward_comm_pair(this)?

the best is to dimension and grow this array to atom->nmax. as mentioned before, you can look at pair style eam as an example. it uses the “fp” array in a forward communication.

  1. function pack_reverse_comm() and unpack_reverse_comm() are also needed ?

no. reverse communication is used to collect results stored with ghost atoms back to local atoms. this is not what you need. you need a forward communication.

axel.

I have created an array like “fp”:
if (atom->nmax > nmax) {
memory->destroy(fp);
nmax = atom->nmax;
memory->create(fp,nmax,3, “pair:fp”);
}
Since coords have 3 arguments, I need to create a (dimension = nmax*3)fp?

在 2019-10-31 19:54:50,“Axel Kohlmeyer” <[email protected]…24…> 写道:

there are plenty of examples in the LAMMPS code, where there are per-MPI rank per-atom 3-component properties managed with memory->create(), memory->destroy() or memory->grow().
please have a look around.
if you want to modify LAMMPS and use some of the low level features, you will also have to practice gathering information you need from reading and understanding the source code. and this is something that is easy enough to learn by yourself without having one of the developers spell it all out for you. I’ve been so far rather generous in explanations, since you were asking things that are not quite as obvious to learn from reading the source (unless you have a lot of practice reading source code), but please don’t assume that I have endless amounts of time to confirm every little details and every trivial piece of information.

axel.