From 8c372f6c410dde1df5e4210c08dbbb877cb5de48 Mon Sep 17 00:00:00 2001 From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa> Date: Thu, 1 Dec 2011 17:21:19 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7266 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/GPU/pppm_gpu.cpp | 8 +- src/PERI/fix_peri_neigh.h | 4 +- src/USER-OMP/fix_peri_neigh_omp.h | 3 +- src/USER-OMP/pair_peri_lps_omp.cpp | 1 - src/USER-OMP/pair_peri_pmb_omp.cpp | 1 - src/angle.cpp | 2 + src/angle.h | 2 +- src/bond_hybrid.h | 7 +- src/comm.cpp | 4 +- src/input.cpp | 36 +++-- src/main.cpp | 9 ++ src/memory.cpp | 5 + src/min.cpp | 43 ++---- src/neigh_list.cpp | 5 +- src/neigh_list.h | 2 +- src/neighbor.cpp | 231 ++++++++++++++++++++--------- src/neighbor.h | 36 +++++ src/verlet.cpp | 43 ++---- 18 files changed, 272 insertions(+), 170 deletions(-) diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp index 0fa91a2518..13af9fcfbe 100644 --- a/src/GPU/pppm_gpu.cpp +++ b/src/GPU/pppm_gpu.cpp @@ -179,8 +179,8 @@ void PPPMGPU::compute(int eflag, int vflag) // calculate the force on my particles - FFT_SCALAR qqrd2e_scale=qqrd2e*scale; - PPPM_GPU_API(interp)(qqrd2e_scale); + FFT_SCALAR qscale = force->qqrd2e * scale; + PPPM_GPU_API(interp)(qscale); // sum energy across procs and add in volume-dependent term @@ -192,7 +192,7 @@ void PPPMGPU::compute(int eflag, int vflag) energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); - energy *= qqrd2e*scale; + energy *= qscale; } // sum virial across procs @@ -200,7 +200,7 @@ void PPPMGPU::compute(int eflag, int vflag) if (vflag) { double virial_all[6]; MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); - for (i = 0; i < 6; i++) virial[i] = 0.5*qqrd2e*scale*volume*virial_all[i]; + for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i]; } // 2d slab correction diff --git a/src/PERI/fix_peri_neigh.h b/src/PERI/fix_peri_neigh.h index 8a441f22cb..c823403a46 100644 --- a/src/PERI/fix_peri_neigh.h +++ b/src/PERI/fix_peri_neigh.h @@ -33,7 +33,7 @@ class FixPeriNeigh : public Fix { public: FixPeriNeigh(class LAMMPS *,int, char **); - ~FixPeriNeigh(); + virtual ~FixPeriNeigh(); int setmask(); void init(); void init_list(int, class NeighList *); @@ -55,7 +55,7 @@ class FixPeriNeigh : public Fix { void unpack_comm(int, int, double *); - private: + protected: int first; // flag for first time initialization int maxpartner; // max # of peridynamic neighs for any atom int *npartner; // # of neighbors for each atom diff --git a/src/USER-OMP/fix_peri_neigh_omp.h b/src/USER-OMP/fix_peri_neigh_omp.h index 605bbae5f4..11a383a2fe 100644 --- a/src/USER-OMP/fix_peri_neigh_omp.h +++ b/src/USER-OMP/fix_peri_neigh_omp.h @@ -27,7 +27,8 @@ namespace LAMMPS_NS { class FixPeriNeighOMP : public FixPeriNeigh { public: - FixPeriNeighOMP(class LAMMPS *lmp, int narg, char **argv) : FixPeriNeigh(lmp,narg,argv) {}; + FixPeriNeighOMP(class LAMMPS *lmp, int narg, char **argv) : + FixPeriNeigh(lmp,narg,argv) {}; virtual void init(); }; diff --git a/src/USER-OMP/pair_peri_lps_omp.cpp b/src/USER-OMP/pair_peri_lps_omp.cpp index e052271e4f..a4479180bf 100644 --- a/src/USER-OMP/pair_peri_lps_omp.cpp +++ b/src/USER-OMP/pair_peri_lps_omp.cpp @@ -37,7 +37,6 @@ PairPeriLPSOMP::PairPeriLPSOMP(LAMMPS *lmp) : PairPeriLPS(lmp), ThrOMP(lmp, THR_PAIR) { respa_enable = 0; - fix_name = "PERI_NEIGH_OMP"; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-OMP/pair_peri_pmb_omp.cpp b/src/USER-OMP/pair_peri_pmb_omp.cpp index 96e991bab6..de6387ae6b 100644 --- a/src/USER-OMP/pair_peri_pmb_omp.cpp +++ b/src/USER-OMP/pair_peri_pmb_omp.cpp @@ -35,7 +35,6 @@ PairPeriPMBOMP::PairPeriPMBOMP(LAMMPS *lmp) : PairPeriPMB(lmp), ThrOMP(lmp, THR_PAIR) { respa_enable = 0; - fix_name = "PERI_NEIGH_OMP"; } /* ---------------------------------------------------------------------- */ diff --git a/src/angle.cpp b/src/angle.cpp index 54a3a5d051..709ace1826 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -53,6 +53,8 @@ void Angle::init() if (!allocated) error->all(FLERR,"Angle coeffs are not set"); for (int i = 1; i <= atom->nangletypes; i++) if (setflag[i] == 0) error->all(FLERR,"All angle coeffs are not set"); + + init_style(); } /* ---------------------------------------------------------------------- diff --git a/src/angle.h b/src/angle.h index 7aa1fe85e2..95a35a5a5a 100644 --- a/src/angle.h +++ b/src/angle.h @@ -31,10 +31,10 @@ class Angle : protected Pointers { Angle(class LAMMPS *); virtual ~Angle(); virtual void init(); - virtual void init_style() {} virtual void compute(int, int) = 0; virtual void settings(int, char **) {} virtual void coeff(int, char **) = 0; + virtual void init_style() {}; virtual double equilibrium_angle(int) = 0; virtual void write_restart(FILE *) = 0; virtual void read_restart(FILE *) = 0; diff --git a/src/bond_hybrid.h b/src/bond_hybrid.h index acdee75063..6c607ec6c4 100644 --- a/src/bond_hybrid.h +++ b/src/bond_hybrid.h @@ -29,6 +29,10 @@ class BondHybrid : public Bond { friend class Force; public: + int nstyles; // # of different bond styles + Bond **styles; // class list for each Bond style + char **keywords; // keyword for each Bond style + BondHybrid(class LAMMPS *); ~BondHybrid(); void compute(int, int); @@ -42,9 +46,6 @@ class BondHybrid : public Bond { double memory_usage(); private: - int nstyles; // # of different bond styles - Bond **styles; // class list for each Bond style - char **keywords; // keyword for each Bond style int *map; // which style each bond type points to int *nbondlist; // # of bonds in sub-style bondlists diff --git a/src/comm.cpp b/src/comm.cpp index e28baab37f..1651e0dfd7 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -174,9 +174,9 @@ void Comm::set_procs() if (domain->triclinic) domain->set_lamda_box(); if (me == 0) { - if (screen) fprintf(screen," %d by %d by %d processor grid\n", + if (screen) fprintf(screen," %d by %d by %d MPI processor grid\n", procgrid[0],procgrid[1],procgrid[2]); - if (logfile) fprintf(logfile," %d by %d by %d processor grid\n", + if (logfile) fprintf(logfile," %d by %d by %d MPI processor grid\n", procgrid[0],procgrid[1],procgrid[2]); } } diff --git a/src/input.cpp b/src/input.cpp index 457faf4ac8..3af9062d05 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -509,6 +509,14 @@ void Input::clear() if (narg > 0) error->all(FLERR,"Illegal clear command"); lmp->destroy(); lmp->create(); + + // use of "omp" suffix implies using "package omp" + // re-create the effect of that package command which creates a fix + + if (lmp->suffix && lmp->suffix_enable) { + if (strcmp(lmp->suffix,"omp") == 0) + lmp->input->one("package omp *"); + } } /* ---------------------------------------------------------------------- */ @@ -1141,25 +1149,15 @@ void Input::package() delete [] fixarg; } else if (strcmp(arg[0],"omp") == 0) { - -#ifdef _OPENMP - if (narg != 2) error->all(FLERR,"Illegal package command"); - comm->nthreads = atoi(arg[1]); - if (comm->nthreads < 1) error->all(FLERR,"Illegal package command"); - - omp_set_num_threads(comm->nthreads); - if (me == 0) { - if (screen) - fprintf(screen," reset %d OpenMP thread(s) per MPI task\n", - comm->nthreads); - if (logfile) - fprintf(logfile," reset %d OpenMP thread(s) per MPI task\n", - comm->nthreads); - } -#else - error->all(FLERR,"Cannot use package omp command with no OpenMP support"); -#endif - + char **fixarg = new char*[2+narg]; + fixarg[0] = "package_omp"; + fixarg[1] = "all"; + fixarg[2] = "OMP"; + for (int i = 1; i < narg; i++) fixarg[i+2] = arg[i]; + modify->allow_early_fix = 1; + modify->add_fix(2+narg,fixarg,NULL); + modify->allow_early_fix = 0; + delete [] fixarg; } else error->all(FLERR,"Illegal package command"); } diff --git a/src/main.cpp b/src/main.cpp index a3764872ec..0776e7e977 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include "mpi.h" #include "lammps.h" #include "input.h" +#include "string.h" using namespace LAMMPS_NS; @@ -26,6 +27,14 @@ int main(int argc, char **argv) MPI_Init(&argc,&argv); LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD); + + // using /omp suffix implies running the "package omp" + // command with default settings. + if (lammps->suffix && lammps->suffix_enable) { + if (strcmp(lammps->suffix,"omp") == 0) + lammps->input->one("package omp *"); + } + lammps->input->file(); delete lammps; diff --git a/src/memory.cpp b/src/memory.cpp index 11e15f10e5..c98f40fd3f 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -32,7 +32,12 @@ void *Memory::smalloc(bigint nbytes, const char *name) { if (nbytes == 0) return NULL; +#if defined(LAMMPS_MEMALIGN) + void *ptr; + posix_memalign(&ptr, LAMMPS_MEMALIGN, nbytes); +#else void *ptr = malloc(nbytes); +#endif if (ptr == NULL) { char str[128]; sprintf(str,"Failed to allocate " BIGINT_FORMAT " bytes for array %s", diff --git a/src/min.cpp b/src/min.cpp index f380a103d5..6322b96f77 100644 --- a/src/min.cpp +++ b/src/min.cpp @@ -135,6 +135,11 @@ void Min::init() ev_setup(); + // detect if fix omp is present for clearing force arrays + + int ifix = modify->find_fix("package_omp"); + if (ifix >= 0) external_force_clear = 1; + // set flags for what arrays to clear in force_clear() // need to clear additionals arrays if they exist @@ -513,6 +518,8 @@ double Min::energy_force(int resetflag) void Min::force_clear() { + if (external_force_clear) return; + int i; if (external_force_clear) return; @@ -523,38 +530,14 @@ void Min::force_clear() int nall; if (force->newton) nall = atom->nlocal + atom->nghost; else nall = atom->nlocal; - int ntot = nall * comm->nthreads; - double **f = atom->f; - for (i = 0; i < ntot; i++) { - f[i][0] = 0.0; - f[i][1] = 0.0; - f[i][2] = 0.0; - } + size_t nbytes = sizeof(double) * nall; - if (torqueflag) { - double **torque = atom->torque; - for (i = 0; i < nall; i++) { - torque[i][0] = 0.0; - torque[i][1] = 0.0; - torque[i][2] = 0.0; - } - } - - if (erforceflag) { - double *erforce = atom->erforce; - for (i = 0; i < nall; i++) erforce[i] = 0.0; - } - - if (e_flag) { - double *de = atom->de; - for (i = 0; i < nall; i++) de[i] = 0.0; - } - - if (rho_flag) { - double *drho = atom->drho; - for (i = 0; i < nall; i++) drho[i] = 0.0; - } + memset(&(atom->f[0][0]),0,3*nbytes); + if (torqueflag) memset(&(atom->torque[0][0]),0,3*nbytes); + if (erforceflag) memset(&(atom->erforce[0]), 0, nbytes); + if (e_flag) memset(&(atom->de[0]), 0, nbytes); + if (rho_flag) memset(&(atom->drho[0]), 0, nbytes); } /* ---------------------------------------------------------------------- diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 13dc4a217f..963ee03cf5 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -181,10 +181,10 @@ void NeighList::stencil_allocate(int smax, int style) add PGDELTA pages to neighbor list ------------------------------------------------------------------------- */ -int **NeighList::add_pages() +int **NeighList::add_pages(int howmany) { int toppage = maxpage; - maxpage += PGDELTA; + maxpage += howmany*PGDELTA; pages = (int **) memory->srealloc(pages,maxpage*sizeof(int *),"neighlist:pages"); @@ -249,6 +249,7 @@ void NeighList::print_attributes() printf("\n"); printf(" %d = occasional\n",rq->occasional); printf(" %d = dnum\n",rq->dnum); + printf(" %d = omp\n",rq->omp); printf(" %d = ghost\n",rq->ghost); printf(" %d = cudable\n",rq->cudable); printf(" %d = omp\n",rq->omp); diff --git a/src/neigh_list.h b/src/neigh_list.h index 63675503cf..a8857811a3 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -79,7 +79,7 @@ class NeighList : protected Pointers { ~NeighList(); void grow(int); // grow maxlocal void stencil_allocate(int, int); // allocate stencil arrays - int **add_pages(); // add pages to neigh list + int **add_pages(int howmany=1); // add pages to neigh list void copy_skip_info(int *, int **); // copy skip info from a neigh request void print_attributes(); // debug routine int get_maxlocal() {return maxatoms;} diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 24e4285b50..46b0a1e0c8 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -808,85 +808,170 @@ void Neighbor::choose_build(int index, NeighRequest *rq) { PairPtr pb = NULL; - if (rq->copy) pb = &Neighbor::copy_from; + if (rq->omp == 0) { + + if (rq->copy) pb = &Neighbor::copy_from; + + else if (rq->skip) { + if (rq->gran && lists[index]->listgranhistory) + pb = &Neighbor::skip_from_granular; + else if (rq->respaouter) pb = &Neighbor::skip_from_respa; + else pb = &Neighbor::skip_from; + + } else if (rq->half_from_full) { + if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton; + else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton; + + } else if (rq->half) { + if (style == NSQ) { + if (rq->newton == 0) { + if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton; + else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton; + } else if (rq->newton == 1) { + pb = &Neighbor::half_nsq_newton; + } else if (rq->newton == 2) { + pb = &Neighbor::half_nsq_no_newton; + } + } else if (style == BIN) { + if (rq->newton == 0) { + if (newton_pair == 0) pb = &Neighbor::half_bin_no_newton; + else if (triclinic == 0) pb = &Neighbor::half_bin_newton; + else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri; + } else if (rq->newton == 1) { + if (triclinic == 0) pb = &Neighbor::half_bin_newton; + else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri; + } else if (rq->newton == 2) pb = &Neighbor::half_bin_no_newton; + } else if (style == MULTI) { + if (rq->newton == 0) { + if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton; + else if (triclinic == 0) pb = &Neighbor::half_multi_newton; + else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri; + } else if (rq->newton == 1) { + if (triclinic == 0) pb = &Neighbor::half_multi_newton; + else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri; + } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton; + } - else if (rq->skip) { - if (rq->gran && lists[index]->listgranhistory) - pb = &Neighbor::skip_from_granular; - else if (rq->respaouter) pb = &Neighbor::skip_from_respa; - else pb = &Neighbor::skip_from; + } else if (rq->full) { + if (style == NSQ) { + if (rq->ghost == 0) pb = &Neighbor::full_nsq; + else if (includegroup) + error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); + else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost; + } else if (style == BIN) { + if (rq->ghost == 0) pb = &Neighbor::full_bin; + else if (includegroup) + error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); + else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost; + } else if (style == MULTI) { + if (rq->ghost == 0) pb = &Neighbor::full_multi; + else error->all(FLERR,"Neighbor multi not yet enabled for ghost neighbors"); + } - } else if (rq->half_from_full) { - if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton; - else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton; + } else if (rq->gran) { + if (style == NSQ) { + if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton; + else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton; + } else if (style == BIN) { + if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton; + else if (triclinic == 0) pb = &Neighbor::granular_bin_newton; + else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri; + } else if (style == MULTI) + error->all(FLERR,"Neighbor multi not yet enabled for granular"); + + } else if (rq->respaouter) { + if (style == NSQ) { + if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton; + else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton; + } else if (style == BIN) { + if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton; + else if (triclinic == 0) pb = &Neighbor::respa_bin_newton; + else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri; + } else if (style == MULTI) + error->all(FLERR,"Neighbor multi not yet enabled for rRESPA"); + } + } else { - } else if (rq->half) { - if (style == NSQ) { - if (rq->newton == 0) { - if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton; - else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton; - } else if (rq->newton == 1) { - pb = &Neighbor::half_nsq_newton; - } else if (rq->newton == 2) { - pb = &Neighbor::half_nsq_no_newton; + if (rq->copy) pb = &Neighbor::copy_from; + + else if (rq->skip) { + if (rq->gran && lists[index]->listgranhistory) + pb = &Neighbor::skip_from_granular; + else if (rq->respaouter) pb = &Neighbor::skip_from_respa; + else pb = &Neighbor::skip_from; + + } else if (rq->half_from_full) { + if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton_omp; + else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton_omp; + + } else if (rq->half) { + if (style == NSQ) { + if (rq->newton == 0) { + if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton_omp; + else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton_omp; + } else if (rq->newton == 1) { + pb = &Neighbor::half_nsq_newton_omp; + } else if (rq->newton == 2) { + pb = &Neighbor::half_nsq_no_newton_omp; + } + } else if (style == BIN) { + if (rq->newton == 0) { + if (newton_pair == 0) pb = &Neighbor::half_bin_no_newton_omp; + else if (triclinic == 0) pb = &Neighbor::half_bin_newton_omp; + else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri_omp; + } else if (rq->newton == 1) { + if (triclinic == 0) pb = &Neighbor::half_bin_newton_omp; + else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri_omp; + } else if (rq->newton == 2) pb = &Neighbor::half_bin_no_newton_omp; + } else if (style == MULTI) { + if (rq->newton == 0) { + if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton_omp; + else if (triclinic == 0) pb = &Neighbor::half_multi_newton_omp; + else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri_omp; + } else if (rq->newton == 1) { + if (triclinic == 0) pb = &Neighbor::half_multi_newton_omp; + else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri_omp; + } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton_omp; } - } else if (style == BIN) { - if (rq->newton == 0) { - if (newton_pair == 0) pb = &Neighbor::half_bin_no_newton; - else if (triclinic == 0) pb = &Neighbor::half_bin_newton; - else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri; - } else if (rq->newton == 1) { - if (triclinic == 0) pb = &Neighbor::half_bin_newton; - else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri; - } else if (rq->newton == 2) pb = &Neighbor::half_bin_no_newton; - } else if (style == MULTI) { - if (rq->newton == 0) { - if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton; - else if (triclinic == 0) pb = &Neighbor::half_multi_newton; - else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri; - } else if (rq->newton == 1) { - if (triclinic == 0) pb = &Neighbor::half_multi_newton; - else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri; - } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton; - } - } else if (rq->full) { - if (style == NSQ) { - if (rq->ghost == 0) pb = &Neighbor::full_nsq; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); - else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost; - } else if (style == BIN) { - if (rq->ghost == 0) pb = &Neighbor::full_bin; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); - else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost; - } else if (style == MULTI) { - if (rq->ghost == 0) pb = &Neighbor::full_multi; - else error->all(FLERR,"Neighbor multi not yet enabled for ghost neighbors"); - } + } else if (rq->full) { + if (style == NSQ) { + if (rq->ghost == 0) pb = &Neighbor::full_nsq_omp; + else if (includegroup) + error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); + else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost_omp; + } else if (style == BIN) { + if (rq->ghost == 0) pb = &Neighbor::full_bin_omp; + else if (includegroup) + error->all(FLERR,"Neighbor include group not allowed with ghost neighbors"); + else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost_omp; + } else if (style == MULTI) { + if (rq->ghost == 0) pb = &Neighbor::full_multi_omp; + else error->all(FLERR,"Neighbor multi not yet enabled for ghost neighbors"); + } - } else if (rq->gran) { - if (style == NSQ) { - if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton; - else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton; - } else if (style == BIN) { - if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton; - else if (triclinic == 0) pb = &Neighbor::granular_bin_newton; - else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri; - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for granular"); - - } else if (rq->respaouter) { - if (style == NSQ) { - if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton; - else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton; - } else if (style == BIN) { - if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton; - else if (triclinic == 0) pb = &Neighbor::respa_bin_newton; - else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri; - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for rRESPA"); + } else if (rq->gran) { + if (style == NSQ) { + if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton_omp; + else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton_omp; + } else if (style == BIN) { + if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton_omp; + else if (triclinic == 0) pb = &Neighbor::granular_bin_newton_omp; + else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri_omp; + } else if (style == MULTI) + error->all(FLERR,"Neighbor multi not yet enabled for granular"); + + } else if (rq->respaouter) { + if (style == NSQ) { + if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton_omp; + else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton_omp; + } else if (style == BIN) { + if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton_omp; + else if (triclinic == 0) pb = &Neighbor::respa_bin_newton_omp; + else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri_omp; + } else if (style == MULTI) + error->all(FLERR,"Neighbor multi not yet enabled for rRESPA"); + } } // general error check diff --git a/src/neighbor.h b/src/neighbor.h index 5248c0bd6e..aa2fcbcba1 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -75,6 +75,8 @@ class Neighbor : protected Pointers { void set(int, char **); // set neighbor style and skin distance void modify_params(int, char**); // modify parameters that control builds bigint memory_usage(); + + inline int exclude_setting() { return exclude; } protected: int me,nprocs; @@ -209,6 +211,40 @@ class Neighbor : protected Pointers { void respa_bin_newton(class NeighList *); void respa_bin_newton_tri(class NeighList *); + // OpenMP multi-threaded neighbor list build versions + + void half_nsq_no_newton_omp(class NeighList *); + void half_nsq_newton_omp(class NeighList *); + + void half_bin_no_newton_omp(class NeighList *); + void half_bin_newton_omp(class NeighList *); + void half_bin_newton_tri_omp(class NeighList *); + + void half_multi_no_newton_omp(class NeighList *); + void half_multi_newton_omp(class NeighList *); + void half_multi_newton_tri_omp(class NeighList *); + + void full_nsq_omp(class NeighList *); + void full_nsq_ghost_omp(class NeighList *); + void full_bin_omp(class NeighList *); + void full_bin_ghost_omp(class NeighList *); + void full_multi_omp(class NeighList *); + + void half_from_full_no_newton_omp(class NeighList *); + void half_from_full_newton_omp(class NeighList *); + + void granular_nsq_no_newton_omp(class NeighList *); + void granular_nsq_newton_omp(class NeighList *); + void granular_bin_no_newton_omp(class NeighList *); + void granular_bin_newton_omp(class NeighList *); + void granular_bin_newton_tri_omp(class NeighList *); + + void respa_nsq_no_newton_omp(class NeighList *); + void respa_nsq_newton_omp(class NeighList *); + void respa_bin_no_newton_omp(class NeighList *); + void respa_bin_newton_omp(class NeighList *); + void respa_bin_newton_tri_omp(class NeighList *); + // pairwise stencil creation functions typedef void (Neighbor::*StencilPtr)(class NeighList *, int, int, int); diff --git a/src/verlet.cpp b/src/verlet.cpp index c6d53e5240..284f9726a4 100644 --- a/src/verlet.cpp +++ b/src/verlet.cpp @@ -62,6 +62,11 @@ void Verlet::init() ev_setup(); + // detect if fix omp is present for clearing force arrays + + int ifix = modify->find_fix("package_omp"); + if (ifix >= 0) external_force_clear = 1; + // set flags for what arrays to clear in force_clear() // need to clear additionals arrays if they exist @@ -306,49 +311,27 @@ void Verlet::cleanup() void Verlet::force_clear() { + if (external_force_clear) return; int i; if (external_force_clear) return; // clear force on all particles // if either newton flag is set, also include ghosts + // when using threads always clear all forces. if (neighbor->includegroup == 0) { int nall; if (force->newton) nall = atom->nlocal + atom->nghost; else nall = atom->nlocal; - int ntot = nall * comm->nthreads; - double **f = atom->f; - for (i = 0; i < ntot; i++) { - f[i][0] = 0.0; - f[i][1] = 0.0; - f[i][2] = 0.0; - } - - if (torqueflag) { - double **torque = atom->torque; - for (i = 0; i < nall; i++) { - torque[i][0] = 0.0; - torque[i][1] = 0.0; - torque[i][2] = 0.0; - } - } - - if (erforceflag) { - double *erforce = atom->erforce; - for (i = 0; i < nall; i++) erforce[i] = 0.0; - } + size_t nbytes = sizeof(double) * nall; - if (e_flag) { - double *de = atom->de; - for (i = 0; i < nall; i++) de[i] = 0.0; - } - - if (rho_flag) { - double *drho = atom->drho; - for (i = 0; i < nall; i++) drho[i] = 0.0; - } + memset(&(atom->f[0][0]),0,3*nbytes); + if (torqueflag) memset(&(atom->torque[0][0]),0,3*nbytes); + if (erforceflag) memset(&(atom->erforce[0]), 0, nbytes); + if (e_flag) memset(&(atom->de[0]), 0, nbytes); + if (rho_flag) memset(&(atom->drho[0]), 0, nbytes); // neighbor includegroup flag is set // clear force only on initial nfirst particles -- GitLab