Skip to content
Snippets Groups Projects
neigh_list.cpp 9.3 KiB
Newer Older
sjplimp's avatar
sjplimp committed
/* ----------------------------------------------------------------------
   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
   http://lammps.sandia.gov, Sandia National Laboratories
   Steve Plimpton, sjplimp@sandia.gov

   Copyright (2003) Sandia Corporation.  Under the terms of Contract
   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
sjplimp's avatar
 
sjplimp committed
   certain rights in this software.  This software is distributed under
sjplimp's avatar
sjplimp committed
   the GNU General Public License.

   See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */

#include "neigh_list.h"
#include "atom.h"
#include "comm.h"
sjplimp's avatar
 
sjplimp committed
#include "update.h"
sjplimp's avatar
sjplimp committed
#include "neighbor.h"
#include "neigh_request.h"
sjplimp's avatar
 
sjplimp committed
#include "my_page.h"
sjplimp's avatar
sjplimp committed
#include "memory.h"
#include "error.h"

using namespace LAMMPS_NS;

#define PGDELTA 1

enum{NSQ,BIN,MULTI};     // also in neighbor.cpp

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

sjplimp's avatar
 
sjplimp committed
NeighList::NeighList(LAMMPS *lmp) :
  Pointers(lmp)
sjplimp's avatar
sjplimp committed
{
sjplimp's avatar
 
sjplimp committed
  maxatoms = 0;
sjplimp's avatar
sjplimp committed

sjplimp's avatar
 
sjplimp committed
  inum = gnum = 0;
sjplimp's avatar
sjplimp committed
  ilist = NULL;
  numneigh = NULL;
  firstneigh = NULL;
  firstdouble = NULL;

sjplimp's avatar
 
sjplimp committed
  dnum = 0;

sjplimp's avatar
 
sjplimp committed
  last_build = -1;

sjplimp's avatar
sjplimp committed
  iskip = NULL;
  ijskip = NULL;

  listgranhistory = NULL;
  fix_history = NULL;

  respamiddle = 0;
  listinner = NULL;
  listmiddle = NULL;
  listfull = NULL;
  listcopy = NULL;
  listskip = NULL;

sjplimp's avatar
 
sjplimp committed
  // USER-DPD package
sjplimp's avatar
 
sjplimp committed

  ssaflag = 0;
sjplimp's avatar
 
sjplimp committed
  ndxAIR_ssa = NULL;
  maxbin_ssa = 0;
  bins_ssa = NULL;
  maxhead_ssa = 0;
  binhead_ssa = NULL;
  gbinhead_ssa = NULL;

sjplimp's avatar
 
sjplimp committed
  maxstencil = ghostflag = 0;
sjplimp's avatar
sjplimp committed
  stencil = NULL;
sjplimp's avatar
 
sjplimp committed
  stencilxyz = NULL;
sjplimp's avatar
sjplimp committed

  maxstencil_multi = 0;
  nstencil_multi = NULL;
  stencil_multi = NULL;
  distsq_multi = NULL;
sjplimp's avatar
 
sjplimp committed

  ipage = NULL;
  dpage = NULL;
sjplimp's avatar
sjplimp committed
}

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

NeighList::~NeighList()
{
  if (!listcopy) {
sjplimp's avatar
 
sjplimp committed
    memory->destroy(ilist);
    memory->destroy(numneigh);
sjplimp's avatar
sjplimp committed
    memory->sfree(firstneigh);
    memory->sfree(firstdouble);

sjplimp's avatar
 
sjplimp committed
    delete [] ipage;
    if (dnum) delete [] dpage;
sjplimp's avatar
sjplimp committed
  }

sjplimp's avatar
 
sjplimp committed
  delete [] iskip;
sjplimp's avatar
 
sjplimp committed
  memory->destroy(ijskip);
sjplimp's avatar
 
sjplimp committed

sjplimp's avatar
 
sjplimp committed
  if (maxstencil) memory->destroy(stencil);
sjplimp's avatar
 
sjplimp committed
  if (ghostflag) memory->destroy(stencilxyz);
sjplimp's avatar
 
sjplimp committed
  if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa);
  if (maxbin_ssa) memory->destroy(bins_ssa);
  if (maxhead_ssa) {
    memory->destroy(binhead_ssa);
    memory->destroy(gbinhead_ssa);
  }
sjplimp's avatar
 
sjplimp committed

sjplimp's avatar
sjplimp committed
  if (maxstencil_multi) {
    for (int i = 1; i <= atom->ntypes; i++) {
sjplimp's avatar
 
sjplimp committed
      memory->destroy(stencil_multi[i]);
      memory->destroy(distsq_multi[i]);
sjplimp's avatar
sjplimp committed
    }
    delete [] nstencil_multi;
    delete [] stencil_multi;
    delete [] distsq_multi;
  }
}

sjplimp's avatar
 
sjplimp committed
/* ---------------------------------------------------------------------- */

sjplimp's avatar
 
sjplimp committed
void NeighList::setup_pages(int pgsize_caller, int oneatom_caller,
sjplimp's avatar
 
sjplimp committed
                            int dnum_caller)
{
  pgsize = pgsize_caller;
  oneatom = oneatom_caller;
  dnum = dnum_caller;

  int nmypage = comm->nthreads;
  ipage = new MyPage<int>[nmypage];
  for (int i = 0; i < nmypage; i++)
    ipage[i].init(oneatom,pgsize,PGDELTA);

  if (dnum) {
    dpage = new MyPage<double>[nmypage];
    for (int i = 0; i < nmypage; i++)
      dpage[i].init(dnum*oneatom,dnum*pgsize,PGDELTA);
  }
  else dpage = NULL;
}

sjplimp's avatar
sjplimp committed
/* ----------------------------------------------------------------------
   grow atom arrays to allow for nmax atoms
   triggered by more atoms on a processor
sjplimp's avatar
 
sjplimp committed
   caller knows if this list stores neighs of local atoms or local+ghost
sjplimp's avatar
sjplimp committed
------------------------------------------------------------------------- */

void NeighList::grow(int nmax)
{
sjplimp's avatar
 
sjplimp committed
  // skip if this list is already long enough to store nmax atoms

  if (nmax <= maxatoms) return;
sjplimp's avatar
 
sjplimp committed
  maxatoms = nmax;
sjplimp's avatar
sjplimp committed

sjplimp's avatar
 
sjplimp committed
  memory->destroy(ilist);
  memory->destroy(numneigh);
sjplimp's avatar
 
sjplimp committed
  memory->sfree(firstneigh);
sjplimp's avatar
 
sjplimp committed
  memory->sfree(firstdouble);
sjplimp's avatar
 
sjplimp committed

sjplimp's avatar
 
sjplimp committed
  memory->create(ilist,maxatoms,"neighlist:ilist");
  memory->create(numneigh,maxatoms,"neighlist:numneigh");
sjplimp's avatar
 
sjplimp committed
  firstneigh = (int **) memory->smalloc(maxatoms*sizeof(int *),
sjplimp's avatar
 
sjplimp committed
                                        "neighlist:firstneigh");
  if (dnum)
sjplimp's avatar
 
sjplimp committed
    firstdouble = (double **) memory->smalloc(maxatoms*sizeof(double *),
sjplimp's avatar
 
sjplimp committed
                                              "neighlist:firstdouble");
sjplimp's avatar
 
sjplimp committed
  if (ssaflag) {
    if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa);
    ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatoms,
      "neighlist:ndxAIR_ssa");
  }
sjplimp's avatar
sjplimp committed
}

/* ----------------------------------------------------------------------
   insure stencils are large enough for smax bins
   style = BIN or MULTI
------------------------------------------------------------------------- */

void NeighList::stencil_allocate(int smax, int style)
{
  int i;

  if (style == BIN) {
    if (smax > maxstencil) {
      maxstencil = smax;
sjplimp's avatar
 
sjplimp committed
      memory->destroy(stencil);
sjplimp's avatar
 
sjplimp committed
      memory->create(stencil,maxstencil,"neighlist:stencil");
sjplimp's avatar
 
sjplimp committed
      if (ghostflag) {
sjplimp's avatar
 
sjplimp committed
        memory->destroy(stencilxyz);
        memory->create(stencilxyz,maxstencil,3,"neighlist:stencilxyz");
sjplimp's avatar
 
sjplimp committed
      }
sjplimp's avatar
sjplimp committed
    }

  } else {
    int n = atom->ntypes;
    if (maxstencil_multi == 0) {
      nstencil_multi = new int[n+1];
      stencil_multi = new int*[n+1];
      distsq_multi = new double*[n+1];
      for (i = 1; i <= n; i++) {
sjplimp's avatar
 
sjplimp committed
        nstencil_multi[i] = 0;
        stencil_multi[i] = NULL;
        distsq_multi[i] = NULL;
sjplimp's avatar
sjplimp committed
      }
    }
    if (smax > maxstencil_multi) {
      maxstencil_multi = smax;
      for (i = 1; i <= n; i++) {
sjplimp's avatar
 
sjplimp committed
        memory->destroy(stencil_multi[i]);
        memory->destroy(distsq_multi[i]);
        memory->create(stencil_multi[i],maxstencil_multi,
                       "neighlist:stencil_multi");
        memory->create(distsq_multi[i],maxstencil_multi,
                       "neighlist:distsq_multi");
sjplimp's avatar
sjplimp committed
      }
    }
  }
}

sjplimp's avatar
 
sjplimp committed
/* ----------------------------------------------------------------------
   copy skip info from request rq into list's iskip,ijskip
------------------------------------------------------------------------- */

void NeighList::copy_skip_info(int *rq_iskip, int **rq_ijskip)
{
  int ntypes = atom->ntypes;
  iskip = new int[ntypes+1];
sjplimp's avatar
 
sjplimp committed
  memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip");
sjplimp's avatar
 
sjplimp committed
  int i,j;
  for (i = 1; i <= ntypes; i++) iskip[i] = rq_iskip[i];
  for (i = 1; i <= ntypes; i++)
    for (j = 1; j <= ntypes; j++)
      ijskip[i][j] = rq_ijskip[i][j];
}

sjplimp's avatar
sjplimp committed
/* ----------------------------------------------------------------------
   print attributes of this list and associated request
------------------------------------------------------------------------- */

void NeighList::print_attributes()
{
  if (comm->me != 0) return;

  NeighRequest *rq = neighbor->requests[index];

  printf("Neighbor list/request %d:\n",index);
sjplimp's avatar
 
sjplimp committed
  printf("  %p = requestor ptr (instance %d id %d)\n",
         rq->requestor,rq->requestor_instance,rq->id);
sjplimp's avatar
sjplimp committed
  printf("  %d = build flag\n",buildflag);
  printf("  %d = grow flag\n",growflag);
  printf("  %d = stencil flag\n",stencilflag);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = ghost flag\n",ghostflag);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = ssa flag\n",ssaflag);
sjplimp's avatar
sjplimp committed
  printf("\n");
  printf("  %d = pair\n",rq->pair);
  printf("  %d = fix\n",rq->fix);
  printf("  %d = compute\n",rq->compute);
  printf("  %d = command\n",rq->command);
  printf("\n");
  printf("  %d = half\n",rq->half);
  printf("  %d = full\n",rq->full);
  printf("  %d = gran\n",rq->gran);
  printf("  %d = granhistory\n",rq->granhistory);
  printf("  %d = respainner\n",rq->respainner);
  printf("  %d = respamiddle\n",rq->respamiddle);
  printf("  %d = respaouter\n",rq->respaouter);
  printf("  %d = half_from_full\n",rq->half_from_full);
  printf("\n");
  printf("  %d = occasional\n",rq->occasional);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = newton\n",rq->newton);
  printf("  %d = granonesided\n",rq->granonesided);
sjplimp's avatar
sjplimp committed
  printf("  %d = dnum\n",rq->dnum);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = ghost\n",rq->ghost);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = omp\n",rq->omp);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = intel\n",rq->intel);
  printf("  %d = kokkos host\n",rq->kokkos_host);
  printf("  %d = kokkos device\n",rq->kokkos_device);
  printf("  %d = ssa\n",rq->ssa);
sjplimp's avatar
sjplimp committed
  printf("  %d = copy\n",rq->copy);
  printf("  %d = skip\n",rq->skip);
  printf("  %d = otherlist\n",rq->otherlist);
sjplimp's avatar
 
sjplimp committed
  printf("  %p = listskip\n",(void *)listskip);
sjplimp's avatar
sjplimp committed
  printf("\n");
}

/* ----------------------------------------------------------------------
   return # of bytes of allocated memory
sjplimp's avatar
 
sjplimp committed
   if growflag = 0, maxatoms & maxpage will also be 0
sjplimp's avatar
sjplimp committed
   if stencilflag = 0, maxstencil * maxstencil_multi will also be 0
------------------------------------------------------------------------- */

sjplimp's avatar
 
sjplimp committed
bigint NeighList::memory_usage()
sjplimp's avatar
sjplimp committed
{
sjplimp's avatar
 
sjplimp committed
  bigint bytes = 0;
sjplimp's avatar
 
sjplimp committed
  bytes += memory->usage(ilist,maxatoms);
  bytes += memory->usage(numneigh,maxatoms);
  bytes += maxatoms * sizeof(int *);
sjplimp's avatar
sjplimp committed

sjplimp's avatar
 
sjplimp committed
  int nmypage = comm->nthreads;
sjplimp's avatar
 
sjplimp committed

  if (ipage) {
    for (int i = 0; i < nmypage; i++)
      bytes += ipage[i].size();
  }

  if (dnum && dpage) {
sjplimp's avatar
 
sjplimp committed
    for (int i = 0; i < nmypage; i++) {
      bytes += maxatoms * sizeof(double *);
      bytes += dpage[i].size();
    }
sjplimp's avatar
sjplimp committed
  }

sjplimp's avatar
 
sjplimp committed
  if (maxstencil) bytes += memory->usage(stencil,maxstencil);
sjplimp's avatar
 
sjplimp committed
  if (ghostflag) bytes += memory->usage(stencilxyz,maxstencil,3);
sjplimp's avatar
 
sjplimp committed
  if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatoms;
  if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa);
  if (maxhead_ssa) {
    bytes += memory->usage(binhead_ssa,maxhead_ssa);
    bytes += memory->usage(gbinhead_ssa,maxhead_ssa);
  }
sjplimp's avatar
 
sjplimp committed

sjplimp's avatar
sjplimp committed
  if (maxstencil_multi) {
sjplimp's avatar
 
sjplimp committed
    bytes += memory->usage(stencil_multi,atom->ntypes,maxstencil_multi);
    bytes += memory->usage(distsq_multi,atom->ntypes,maxstencil_multi);
sjplimp's avatar
sjplimp committed
  }

  return bytes;
}