Dear fellow LAMMPS users,
I am trying to reverse engineer compute_pe_atom.cpp and
compute_group_group.cpp to implement a compute that calculates a
per-atom interaction energy of one group with another group.
I have a few question on the source code and will appreciate any assistance.
1. In the file compute_pe_atom.cpp, why do we need the functions
pack_reverse_comm and unpack_reverse_comm? I understand that, in each
processor, the potential energies of the owned and ghost atoms are
calculated. In that case, why do we need to communicate the calculated
PE of the atoms from the processor to its neighboring processors?
2. Under what circumstances are list->inum and nlocal different? In a
previous post to the mailing list, it was mentioned that they may be
different if pair_style hybrid is used? Why would that be so?
Regards,
Zhun-Yong Ong
University of Illinois at Urbana-Champaign
Answers below.
Steve
Dear fellow LAMMPS users,
I am trying to reverse engineer compute_pe_atom.cpp and
compute_group_group.cpp to implement a compute that calculates a
per-atom interaction energy of one group with another group.
I have a few question on the source code and will appreciate any assistance.
1. In the file compute_pe_atom.cpp, why do we need the functions
pack_reverse_comm and unpack_reverse_comm? I understand that, in each
processor, the potential energies of the owned and ghost atoms are
calculated. In that case, why do we need to communicate the calculated
PE of the atoms from the processor to its neighboring processors?
Because the total PE for a particular atom can be shared by
several procs.
2. Under what circumstances are list->inum and nlocal different? In a
previous post to the mailing list, it was mentioned that they may be
different if pair_style hybrid is used? Why would that be so?
Because a hybrid neighbor list for one potential will only have pair
interactions for
the atoms interacting thru that potentials, which can be a subset.
Hi Steve,
Thank you for your reply. I have another question for you.
1. In the file compute_pe_atom.cpp, why do we need the functions
pack_reverse_comm and unpack_reverse_comm? I understand that, in each
processor, the potential energies of the owned and ghost atoms are
calculated. In that case, why do we need to communicate the calculated
PE of the atoms from the processor to its neighboring processors?
Because the total PE for a particular atom can be shared by
several procs.
In compute_ke_atom.cpp, why do we not share the calculated KE of an
atom owned by the processor with other processors in which the atoms
is a ghost? More generally, why do some of the per-atom computes share
their data and some don't?
Regards,
Zhun-Yong
This just occurred to me.
1. In the file compute_pe_atom.cpp, why do we need the functions
pack_reverse_comm and unpack_reverse_comm? I understand that, in each
processor, the potential energies of the owned and ghost atoms are
calculated. In that case, why do we need to communicate the calculated
PE of the atoms from the processor to its neighboring processors?
Because the total PE for a particular atom can be shared by
several procs.
If I'm reading the source code correctly, isn't the total PE for a
particular atom (own and ghost) calculated independently by the
processor in compute_pe_atom.cpp? So, why does the total PE of that
atom be shared?
Regards,
Zhun-Yong
KE is a property of a single atom, so there is no need to communicate.
PE is typically a property of pairs of atoms. So only one of the atoms
will compute it, and store the result for the other atom (which might
be a ghost), so it needs to be communicated.
Steve
Again, b/c the contribution to the PE of an atom will have
been computed by multiple processors due to the pairwise
nature of the interactions.
Steve
Hi Steve,
Thanks for the reply. I have another couple of questions.
1. Doesn't the neighbor list take care of the situation that one of
atom resides on another processor?
2. Suppose atom A resides on processor 1, atom B resides on processor
2 and they interact via a pair-wise potential. B exists as a ghost on
proc. 1 and A a ghost on proc. 2. IF I'm reading the source code
correctly, then proc. 1 will compute the PE of A and B and split the
PE evenly between them. Similarly, proc 2 will do the same.
Afterwards, proc. 1 and proc. 2 pass their computed PE's to each other
via the buffer. The PE of A would include the pairwise interaction
calculated on proc 1 plus that calculated on proc. 2. Isn't there some
kind of double counting here (as well as redundant computations)? How
does LAMMPS take care of that? By half-neighboring the neighbor list?
I apologize if these are trivial questions and would appreciate it if
you can point me to the relevant literature that describes the
implementation of LAMMPS. I've already read your paper "Fast
Algorithms for Short-Range MD".
Regards,
Zhun-Yong
yes, the neighbor list takes care of this. If the newton
flag is set, then the I,J pair only is stored with atom I
or atom J, not both. Thus there is no double counting,
If the newton flag is not set, then the tabulation
of per-atom energy compensates.
Steve