[lammps-users] ghost atoms

Dear LAMMPS developers,

This is likely the first of many questions so if I should direct them elsewhere please let me know.

We want to implement the LCBOPII empirical potential for Carbon [Los, PRB (2005)] in LAMMPS.
I hope you can help me understand some of the basic things about LAMMPS because I could not find a clear explanation in the documentation.

One of the things I don’t understand is the use of ghost atoms, which is somehow connected with the different lists, their indices and values.
1.) What is the purpose of these ghost atoms? (perhaps a reference to literature is enough here)
2.) Could you please explain to me what is stored in the ‘list’ object?

  • list->inum = total number of atoms?
  • list->ilist = list of atom and ghost indices?
  • list->numneigh = number of neighbors for (ghost or atom) index?? based on cutoff from init_one??
  • list->firstneigh = list of neighbours [o…numneigh-1] for every (ghost or atom) index??

For example, I am trying to define some array with indices running from 0 to natoms-1/inum-1/nlocal-1/whatever the appropriate name is-1. This should be a list some effective coordination number of every atom.
Right now, the definitions are like this

//pair_lcbopii.h

double* Ni;

*//pair_lcbopii.*cpp

PairLCBOPII

::~PairLCBOPII() {

delete[] Ni;

}

void PairLCBOPII*::allocate() {*

Ni = new double[atom->nlocal+atom->nghost];

}

3.) What is the correct way to do this allocation in LAMMPS?

  • perhaps they should be done with memory->create_1d_double_array?
  • I suppose nlocal is the num of atoms on this proc, however I want this to be a ‘global’ variable for all processors.
    Should the array size then still be nlocal+nghost or is it list->inum or yet something else?? what is the difference?
  • Its values are calculated every time compute is called, so I should loop only over the atoms on this proc, that is atom->nlocal?

That’s it for now, I hope you can help me with this.
Kind regards,

Jaap Kroes

Dear LAMMPS developers,

This is likely the first of many questions so if I should direct them elsewhere please let me know.

We want to implement the LCBOPII empirical potential for Carbon [Los, PRB (2005)] in LAMMPS.
I hope you can help me understand some of the basic things about LAMMPS because I could not find a clear explanation in the documentation.

One of the things I don’t understand is the use of ghost atoms, which is somehow connected with the different lists, their indices and values.
1.) What is the purpose of these ghost atoms? (perhaps a reference to literature is enough here)
2.) Could you please explain to me what is stored in the ‘list’ object?

  • list->inum = total number of atoms?
  • list->ilist = list of atom and ghost indices?
  • list->numneigh = number of neighbors for (ghost or atom) index?? based on cutoff from init_one??
  • list->firstneigh = list of neighbours [o…numneigh-1] for every (ghost or atom) index??

For example, I am trying to define some array with indices running from 0 to natoms-1/inum-1/nlocal-1/whatever the appropriate name is-1. This should be a list some effective coordination number of every atom.
Right now, the definitions are like this

//pair_lcbopii.h

double* Ni;

*//pair_lcbopii.*cpp

PairLCBOPII

::~PairLCBOPII() {

delete[] Ni;

}

void PairLCBOPII*::allocate() {*

Ni = new double[atom->nlocal+atom->nghost];

}

3.) What is the correct way to do this allocation in LAMMPS?

  • perhaps they should be done with memory->create_1d_double_array?
  • I suppose nlocal is the num of atoms on this proc, however I want this to be a ‘global’ variable for all processors.
    Should the array size then still be nlocal+nghost or is it list->inum or yet something else?? what is the difference?
  • Its values are calculated every time compute is called, so I should loop only over the atoms on this proc, that is atom->nlocal?

That’s it for now, I hope you can help me with this.
Kind regards,

Jaap Kroes

Dear LAMMPS developers,

dear jaap,

This is likely the first of many questions so if I should direct them
elsewhere please let me know.

i would recommend you first scavenge the lammps website
and the mailing list archives. there are likely a lot of
questions, that were similar to what you would want to ask,
and the corresponding answers or discussions.

also, there are a few publications on the fundamental
algorithms in LAMMPS, particularly
S.~J. Plimpton, {\em J. Comp Phys}, 117:1-19, 1995.
and references cited within.

We want to implement the LCBOPII empirical potential for Carbon [Los,
PRB (2005)] in LAMMPS.
I hope you can help me understand some of the basic things about
LAMMPS because I could not find a clear explanation in the
documentation.

the

One of the things I don't understand is the use of ghost atoms, which
is somehow connected with the different lists, their indices and
values.
1.) What is the purpose of these ghost atoms? (perhaps a reference to
literature is enough here)

see steve's paper. those are a consequence of the domain decomposition.
each processor "owns" the "local" atoms, but needs a "halo" of ghost
atoms, so it can compute all forces within the cutoff for the atoms
it owns.

2.) Could you please explain to me what is stored in the 'list'
object?
   - list->inum = total number of atoms?

no. the length of the neighborlists list.

   - list->ilist = list of atom and ghost indices?

no. list list of "i" atoms for which neighbor lists exist.

   - list->numneigh = number of neighbors for (ghost or atom) index??
based on cutoff from init_one??

no. the length of each these neigbor list.

   - list->firstneigh = list of neighbours [o..numneigh-1] for every
(ghost or atom) index??

no. the pointer to the list of neighbors of "i".

For example, I am trying to define some array with indices running
from 0 to natoms-1/inum-1/nlocal-1/whatever the appropriate name is-1.
This should be a list some effective coordination number of every
atom.

you should probably have a look at the pair_eam.cpp file.
in EAM you first compute the density of atoms "j" around
atoms "i" and then the forces based on that density. this
sounds to me somewhat similar in the code flow of what you
want to do. modeling your code of pair_lj_cut.cpp is probably
more complicated.

Right now, the definitions are like this

        //pair_lcbopii.h
         ..
         double* Ni;
        
        //pair_lcbopii.cpp
        PairLCBOPII
        ::~PairLCBOPII() {
          ..
          delete[] Ni;
        }
        void PairLCBOPII::allocate() {
         ..
         Ni = new double[atom->nlocal+atom->nghost];
        }

3.) What is the correct way to do this allocation in LAMMPS?
- perhaps they should be done with memory->create_1d_double_array?
- I suppose nlocal is the num of atoms on this proc, however I want
this to be a 'global' variable for all processors.

you cannot and should not do that. this will kill parallelization.
have a look at steve's papers and how EAM is implemented.
the number of local atoms will change. EAM (and others) have
measures for that implemented.

programming MD in parallel is not always that straightforward,
but if you spend the effort to first understand how the more
complex potentials are implemented, then you'll get rewarded
with superior parallelization and performance.

cheers,
    axel.