Skip to content
Snippets Groups Projects
neigh_list.cpp 8.47 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"
#include "pair.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
sjplimp's avatar
sjplimp committed

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

NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp)
sjplimp's avatar
sjplimp committed
{
  // initializations

  maxatom = 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;

  // defaults, but may be reset by post_constructor()

  occasional = 0;
  ghost = 0;
  ssa = 0;
  copy = 0;
sjplimp's avatar
 
sjplimp committed
  dnum = 0;

  // ptrs
sjplimp's avatar
 
sjplimp committed

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

  listcopy = NULL;
  listskip = NULL;
  listfull = NULL;

  listhistory = NULL;
sjplimp's avatar
sjplimp committed
  fix_history = NULL;

  respamiddle = 0;
  listinner = NULL;
  listmiddle = NULL;

  fix_bond = NULL;
sjplimp's avatar
sjplimp committed

  ipage = NULL;
  dpage = NULL;

Stan Moore's avatar
Stan Moore committed
  // Kokkos package

  kokkos = 0;
  execution_space = Host;

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

sjplimp's avatar
 
sjplimp committed
  ndxAIR_ssa = NULL;
sjplimp's avatar
sjplimp committed
}

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

NeighList::~NeighList()
{
  if (!copy) {
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;
    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

  if (ssa) {
    memory->sfree(ndxAIR_ssa);
sjplimp's avatar
 
sjplimp committed
  }
sjplimp's avatar
 
sjplimp committed

/* ----------------------------------------------------------------------
   adjust settings to match corresponding NeighRequest
   cannot do this in constructor b/c not all NeighLists are allocated yet
   copy -> set listcopy for list to copy from
   skip -> set listskip for list to skip from, create copy of itype,ijtype
   halffull -> set listfull for full list to derive from
   history -> set LH and FH ptrs in partner list that uses the history info
   respaouter -> set listinner/listmiddle for other rRESPA lists
   bond -> set fix_bond to Fix that made the request
------------------------------------------------------------------------- */

void NeighList::post_constructor(NeighRequest *nq)
{
  // copy request settings used by list itself
  
  occasional = nq->occasional;
  ghost = nq->ghost;
  ssa = nq->ssa;
  copy = nq->copy;
  dnum = nq->dnum;

  if (nq->copy)
    listcopy = neighbor->lists[nq->copylist];

  if (nq->skip) {
    listskip = neighbor->lists[nq->skiplist];
    int ntypes = atom->ntypes;
    iskip = new int[ntypes+1];
    memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip");
    int i,j;
    for (i = 1; i <= ntypes; i++) iskip[i] = nq->iskip[i];
    for (i = 1; i <= ntypes; i++)
      for (j = 1; j <= ntypes; j++)
        ijskip[i][j] = nq->ijskip[i][j];
  }

  if (nq->halffull)
    listfull = neighbor->lists[nq->halffulllist];
  if (nq->history) {
    neighbor->lists[nq->historylist]->listhistory = this;
    int tmp;
    neighbor->lists[nq->historylist]->fix_history = 
      (Fix *) ((Pair *) nq->requestor)->extract("history",tmp);
  }
  
  if (nq->respaouter) {
    if (nq->respamiddlelist < 0) {
      respamiddle = 0;
      listinner = neighbor->lists[nq->respainnerlist];
    } else {
      respamiddle = 1;
      listmiddle = neighbor->lists[nq->respamiddlelist];
      listinner = neighbor->lists[nq->respainnerlist];
    }
sjplimp's avatar
sjplimp committed
  }

  if (nq->bond) fix_bond = (Fix *) nq->requestor;
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
{
  pgsize = pgsize_caller;
  oneatom = oneatom_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
}

sjplimp's avatar
sjplimp committed
/* ----------------------------------------------------------------------
   grow per-atom data to allow for nlocal/nall atoms
   for parent lists:
     also trigger grow in child list(s) which are not built themselves
     history calls grow() in listhistory
     respaouter calls grow() in respainner, respamiddle
   triggered by neighbor list build
sjplimp's avatar
sjplimp committed
------------------------------------------------------------------------- */

void NeighList::grow(int nlocal, int nall)
sjplimp's avatar
sjplimp committed
{
  // trigger grow() in children before possible return

  if (listhistory) listhistory->grow(nlocal,nall);
  if (listinner) listinner->grow(nlocal,nall);
  if (listmiddle) listmiddle->grow(nlocal,nall);
sjplimp's avatar
 
sjplimp committed

  // skip if data structs are already big enough

  if (ghost) {
    if (nall <= maxatom) return;
  } else {
    if (nlocal <= maxatom) return;
  }

  maxatom = atom->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);
  memory->create(ilist,maxatom,"neighlist:ilist");
  memory->create(numneigh,maxatom,"neighlist:numneigh");
  firstneigh = (int **) memory->smalloc(maxatom*sizeof(int *),
sjplimp's avatar
 
sjplimp committed
                                        "neighlist:firstneigh");
  if (dnum) {
    memory->sfree(firstdouble);
    firstdouble = (double **) memory->smalloc(maxatom*sizeof(double *),
sjplimp's avatar
 
sjplimp committed
                                              "neighlist:firstdouble");
sjplimp's avatar
 
sjplimp committed
  }
sjplimp's avatar
sjplimp committed

  if (ssa) {
    if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa);
    ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatom,
      "neighlist:ndxAIR_ssa");
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 = pair\n",rq->pair);
  printf("  %d = fix\n",rq->fix);
  printf("  %d = compute\n",rq->compute);
  printf("  %d = command\n",rq->command);
  printf("  %d = neigh\n",rq->neigh);
sjplimp's avatar
sjplimp committed
  printf("\n");
  printf("  %d = half\n",rq->half);
  printf("  %d = full\n",rq->full);
  printf("\n");
  printf("  %d = occasional\n",occasional);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = newton\n",rq->newton);
  printf("  %d = ghost flag\n",ghost);
  printf("  %d = size\n",rq->size);
  printf("  %d = history\n",rq->history);
sjplimp's avatar
 
sjplimp committed
  printf("  %d = granonesided\n",rq->granonesided);
  printf("  %d = respainner\n",rq->respainner);
  printf("  %d = respamiddle\n",rq->respamiddle);
  printf("  %d = respaouter\n",rq->respaouter);
  printf("  %d = bond\n",rq->bond);
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 flag\n",ssa);
  printf("  %d = dnum\n",dnum);
  printf("\n");
  printf("  %d = skip flag\n",rq->skip);
  printf("  %d = off2on\n",rq->off2on);
  printf("  %d = copy flag\n",rq->copy);
  printf("  %d = half/full\n",rq->halffull);
  printf("  %d = history/partner\n",rq->history_partner);
sjplimp's avatar
sjplimp committed
  printf("\n");
}

/* ----------------------------------------------------------------------
   return # of bytes of allocated memory
   if growflag = 0, maxatom & 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;
  bytes += memory->usage(ilist,maxatom);
  bytes += memory->usage(numneigh,maxatom);
  bytes += maxatom * 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 += maxatom * sizeof(double *);
sjplimp's avatar
 
sjplimp committed
      bytes += dpage[i].size();
    }
sjplimp's avatar
sjplimp committed
  }

  if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatom;
sjplimp's avatar
 
sjplimp committed

sjplimp's avatar
sjplimp committed
  return bytes;
}