From 9be7620ace735ec8cec83be2ece8620083e7107b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Wed, 3 Oct 2007 16:22:30 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@937 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/Makefile | 60 +- src/Package.csh | 2 +- src/atom.cpp | 16 +- src/atom.h | 18 +- src/compute.cpp | 5 +- src/compute.h | 7 +- src/compute_centro_atom.cpp | 50 +- src/compute_centro_atom.h | 2 + src/compute_coord_atom.cpp | 49 +- src/compute_coord_atom.h | 2 + src/compute_ebond_atom.cpp | 13 +- src/compute_epair_atom.cpp | 54 +- src/compute_epair_atom.h | 2 + src/compute_etotal_atom.cpp | 127 -- src/compute_ke_atom.cpp | 5 +- src/compute_pressure.cpp | 11 +- src/compute_stress_atom.cpp | 87 +- src/compute_stress_atom.h | 3 +- src/delete_atoms.cpp | 93 +- src/domain.cpp | 6 +- src/domain.h | 2 +- src/dump_atom.cpp | 4 +- src/dump_custom.cpp | 593 +++------ src/dump_custom.h | 37 +- src/dump_dcd.cpp | 2 +- src/dump_dcd.h | 2 +- src/dump_xyz.cpp | 2 +- src/error.cpp | 10 +- src/error.h | 10 +- src/finish.cpp | 29 +- src/fix.cpp | 3 +- src/fix.h | 11 +- src/fix_ave_spatial.cpp | 186 +-- src/fix_ave_spatial.h | 12 +- src/fix_ave_time.cpp | 108 +- src/fix_ave_time.h | 7 +- src/fix_nph.cpp | 22 +- src/fix_npt.cpp | 25 +- src/fix_nvt.cpp | 6 +- src/fix_orient_fcc.cpp | 50 +- src/fix_orient_fcc.h | 2 + src/fix_rdf.cpp | 44 +- src/fix_rdf.h | 2 + src/fix_shear_history.cpp | 41 +- src/fix_shear_history.h | 3 + src/fix_temp_rescale.cpp | 18 +- src/force.cpp | 47 +- src/force.h | 24 +- src/group.cpp | 4 +- src/group.h | 2 +- src/memory.cpp | 32 +- src/memory.h | 28 +- src/min_cg.cpp | 46 +- src/modify.cpp | 12 +- src/modify.h | 4 +- src/neigh_full.cpp | 85 +- src/neigh_gran.cpp | 172 ++- src/neigh_half.cpp | 820 ------------- src/neigh_respa.cpp | 275 +++-- src/neigh_stencil.cpp | 517 ++++---- src/neighbor.cpp | 1085 ++++++++--------- src/neighbor.h | 252 ++-- src/output.cpp | 16 +- src/pair.cpp | 64 +- src/pair.h | 28 +- src/pair_buck.cpp | 27 +- src/pair_buck_coul_cut.cpp | 50 +- src/pair_buck_coul_cut.h | 2 +- src/pair_coul_cut.cpp | 313 +++++ ...{compute_etotal_atom.h => pair_coul_cut.h} | 32 +- src/pair_hybrid.cpp | 637 ++++------ src/pair_hybrid.h | 30 +- src/pair_lj_cut.cpp | 160 ++- src/pair_lj_cut.h | 2 + src/pair_lj_cut_coul_cut.cpp | 50 +- src/pair_lj_cut_coul_cut.h | 2 +- src/pair_lj_cut_coul_debye.cpp | 27 +- src/pair_lj_expand.cpp | 27 +- src/pair_lj_smooth.cpp | 33 +- src/pair_morse.cpp | 27 +- src/pair_soft.cpp | 26 +- src/pair_table.cpp | 27 +- src/pair_yukawa.cpp | 27 +- src/respa.cpp | 6 +- src/style.h | 19 +- src/style_kspace.h | 2 + src/style_user.h | 5 +- src/thermo.cpp | 85 +- src/thermo.h | 8 +- src/universe.cpp | 2 +- src/update.cpp | 13 +- src/update.h | 5 +- src/variable.cpp | 28 +- src/velocity.cpp | 10 +- src/verlet.cpp | 40 +- src/verlet.h | 4 +- 96 files changed, 3347 insertions(+), 3735 deletions(-) delete mode 100644 src/compute_etotal_atom.cpp delete mode 100644 src/neigh_half.cpp create mode 100644 src/pair_coul_cut.cpp rename src/{compute_etotal_atom.h => pair_coul_cut.h} (55%) diff --git a/src/Makefile b/src/Makefile index 6d21661b6c..b844cfad6b 100755 --- a/src/Makefile +++ b/src/Makefile @@ -15,7 +15,12 @@ OBJ = $(SRC:.cpp=.o) PACKAGE = asphere class2 colloid dipole dpd granular \ kspace manybody meam molecule opt poems xtc + +PACKUSER = user-ackland user-ewaldn + PACKUC = $(shell perl -e 'printf("%s", uc("$(PACKAGE)"));') +PACKUSERUC = $(shell perl -e 'printf("%s", uc("$(PACKUSER)"));') + YESDIR = $(shell perl -e 'printf("%s", uc("$(@:yes-%=%)"));') NODIR = $(shell perl -e 'printf("%s", uc("$(@:no-%=%)"));') @@ -31,10 +36,15 @@ help: @echo '' @echo 'make package list available packages' @echo 'make package-status status of all packages' - @echo 'make yes-package install a package in src dir' - @echo 'make no-package remove package files from src dir' + @echo 'make yes-package install a single package in src dir' + @echo 'make no-package remove a single package from src dir' @echo 'make yes-all install all packages in src dir' - @echo 'make no-all remove all package files from src dir' + @echo 'make no-all remove all packages from src dir' + @echo 'make yes-standard install all standard packages' + @echo 'make no-standard remove all standard packages' + @echo 'make yes-user install all user packages' + @echo 'make no-user remove all user packages' + @echo '' @echo 'make package-update replace src files with package files' @echo 'make package-overwrite replace package files with src files' @echo '' @@ -86,27 +96,45 @@ makelist: @csh Make.csh Makefile.list # Package management -# status = list differences between src and package files -# update = replace src files with newer package files -# overwrite = overwrite package files with newer src files package: - @echo 'Available packages:' - @echo $(PACKAGE) + @echo 'Standard packages:' $(PACKAGE) @echo '' + @echo 'User-contributed packages:' $(PACKUSER) + @echo '' + @echo 'make package list available packages' @echo 'make package-status status of all packages' - @echo 'make yes-package install a package in src dir' - @echo 'make no-package remove package files from src dir' + @echo 'make yes-package install a single package in src dir' + @echo 'make no-package remove a single package from src dir' @echo 'make yes-all install all packages in src dir' - @echo 'make no-all remove all package files from src dir' + @echo 'make no-all remove all packages from src dir' + @echo 'make yes-standard install all standard packages' + @echo 'make no-standard remove all standard packages' + @echo 'make yes-user install all user packages' + @echo 'make no-user remove all user packages' + @echo '' @echo 'make package-update replace src files with package files' @echo 'make package-overwrite replace package files with src files' yes-all: @for p in $(PACKAGE); do $(MAKE) yes-$$p; done + @for p in $(PACKUSER); do $(MAKE) yes-$$p; done no-all: @for p in $(PACKAGE); do $(MAKE) no-$$p; done + @for p in $(PACKUSER); do $(MAKE) no-$$p; done + +yes-standard: + @for p in $(PACKAGE); do $(MAKE) yes-$$p; done + +no-standard: + @for p in $(PACKAGE); do $(MAKE) no-$$p; done + +yes-user: + @for p in $(PACKUSER); do $(MAKE) yes-$$p; done + +no-user: + @for p in $(PACKUSER); do $(MAKE) no-$$p; done yes-%: @if [ ! -e $(YESDIR) ]; then \ @@ -124,11 +152,21 @@ no-%: cd $(NODIR); csh -f Install.csh 0; cd ..; $(MAKE) clean-all; \ fi; +# status = list differences between src and package files +# update = replace src files with newer package files +# overwrite = overwrite package files with newer src files + package-status: @for p in $(PACKUC); do csh -f Package.csh $$p status; done + @echo '' + @for p in $(PACKUSERUC); do csh -f Package.csh $$p status; done package-update: @for p in $(PACKUC); do csh -f Package.csh $$p update; done + @echo '' + @for p in $(PACKUSERUC); do csh -f Package.csh $$p update; done package-overwrite: @for p in $(PACKUC); do csh -f Package.csh $$p overwrite; done + @echo '' + @for p in $(PACKUSERUC); do csh -f Package.csh $$p overwrite; done diff --git a/src/Package.csh b/src/Package.csh index 538572d413..0ab65a7752 100644 --- a/src/Package.csh +++ b/src/Package.csh @@ -27,7 +27,7 @@ # just longer than the other (has new stuff added) set glob -set style = `echo $1 | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` +set style = `echo $1 | sed 'y/-ABCDEFGHIJKLMNOPQRSTUVWXYZ/_abcdefghijklmnopqrstuvwxyz/'` cd $1 if ($2 == "status") then diff --git a/src/atom.cpp b/src/atom.cpp index 97cf66558e..943205b50a 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -212,7 +212,7 @@ Atom::~Atom() called from input script, restart file, replicate ------------------------------------------------------------------------- */ -void Atom::create_avec(char *style, int narg, char **arg) +void Atom::create_avec(const char *style, int narg, char **arg) { delete [] atom_style; if (avec) delete avec; @@ -232,7 +232,7 @@ void Atom::create_avec(char *style, int narg, char **arg) generate an AtomVec class ------------------------------------------------------------------------- */ -AtomVec *Atom::new_avec(char *style, int narg, char **arg) +AtomVec *Atom::new_avec(const char *style, int narg, char **arg) { if (0) return NULL; @@ -274,7 +274,7 @@ void Atom::init() else return 0 ------------------------------------------------------------------------- */ -int Atom::style_match(char *style) +int Atom::style_match(const char *style) { if (strcmp(atom_style,style) == 0) return 1; else if (strcmp(atom_style,"hybrid") == 0) { @@ -602,7 +602,7 @@ int Atom::tag_consecutive() trim anything from '#' onward ------------------------------------------------------------------------- */ -int Atom::count_words(char *line) +int Atom::count_words(const char *line) { int n = strlen(line) + 1; char *copy = (char *) memory->smalloc(n*sizeof(char),"copy"); @@ -991,7 +991,7 @@ void Atom::allocate_type_arrays() called from reading of data file ------------------------------------------------------------------------- */ -void Atom::set_mass(char *str) +void Atom::set_mass(const char *str) { if (mass == NULL) error->all("Cannot set mass for this atom style"); @@ -1067,7 +1067,7 @@ void Atom::check_mass() called from reading of data file ------------------------------------------------------------------------- */ -void Atom::set_shape(char *str) +void Atom::set_shape(const char *str) { if (shape == NULL) error->all("Cannot set shape for this atom style"); @@ -1140,7 +1140,7 @@ void Atom::check_shape() called from reading of data file ------------------------------------------------------------------------- */ -void Atom::set_dipole(char *str) +void Atom::set_dipole(const char *str) { if (dipole == NULL) error->all("Cannot set dipole for this atom style"); @@ -1244,7 +1244,7 @@ void Atom::add_callback(int flag) flag = 0 for grow, 1 for restart ------------------------------------------------------------------------- */ -void Atom::delete_callback(char *id, int flag) +void Atom::delete_callback(const char *id, int flag) { int ifix; for (ifix = 0; ifix < modify->nfix; ifix++) diff --git a/src/atom.h b/src/atom.h index 3f18c33c14..c2e1e0462b 100644 --- a/src/atom.h +++ b/src/atom.h @@ -97,17 +97,17 @@ class Atom : protected Pointers { Atom(class LAMMPS *); ~Atom(); - void create_avec(char *, int, char **); - class AtomVec *new_avec(char *, int, char **); + void create_avec(const char *, int, char **); + class AtomVec *new_avec(const char *, int, char **); void init(); - int style_match(char *); + int style_match(const char *); void modify_params(int, char **); void tag_extend(); int tag_consecutive(); - int parse_data(char *); - int count_words(char *); + int parse_data(const char *); + int count_words(const char *); void data_atoms(int, char *); void data_vels(int, char *); @@ -117,22 +117,22 @@ class Atom : protected Pointers { void data_impropers(int, char *); void allocate_type_arrays(); - void set_mass(char *); + void set_mass(const char *); void set_mass(int, double); void set_mass(int, char **); void set_mass(double *); void check_mass(); - void set_shape(char *); + void set_shape(const char *); void set_shape(int, char **); void set_shape(double **); void check_shape(); - void set_dipole(char *); + void set_dipole(const char *); void set_dipole(int, char **); void set_dipole(double *); void check_dipole(); void add_callback(int); - void delete_callback(char *, int); + void delete_callback(const char *, int); void update_callback(int); int memory_usage(); diff --git a/src/compute.cpp b/src/compute.cpp index 0a6312068e..1e0eee51f6 100644 --- a/src/compute.cpp +++ b/src/compute.cpp @@ -49,9 +49,9 @@ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) scalar_flag = vector_flag = peratom_flag = 0; tempflag = pressflag = 0; + npre = 0; id_pre = NULL; comm_forward = comm_reverse = 0; - neigh_half_once = neigh_full_once = 0; // set modify defaults @@ -65,6 +65,9 @@ Compute::~Compute() { delete [] id; delete [] style; + + for (int i = 0; i < npre; i++) delete [] id_pre[i]; + delete [] id_pre; } /* ---------------------------------------------------------------------- */ diff --git a/src/compute.h b/src/compute.h index bae6bc1ab6..a8f1b0f98f 100644 --- a/src/compute.h +++ b/src/compute.h @@ -39,18 +39,19 @@ class Compute : protected Pointers { // must have both compute_scalar, compute_vector int pressflag; // 1 if Compute can be used as pressure (uses virial) // must have both compute_scalar, compute_vector - char *id_pre; // ID of Compute that needs to be computed before this double dof; // degrees-of-freedom for temperature + int npre; // # of computes to compute before this one + char **id_pre; // IDs of Computes to compute before this one + int comm_forward; // size of forward communication (0 if none) int comm_reverse; // size of reverse communication (0 if none) - int neigh_half_once; // 1 if requires half neighbor lists - int neigh_full_once; // 1 if requires full neighbor lists Compute(class LAMMPS *, int, char **); virtual ~Compute(); void modify_params(int, char **); virtual void init() = 0; + virtual void init_list(int, class NeighList *) {} virtual double compute_scalar() {return 0.0;} virtual void compute_vector() {} virtual void compute_peratom() {} diff --git a/src/compute_centro_atom.cpp b/src/compute_centro_atom.cpp index 04b9383f32..3506cc8dce 100644 --- a/src/compute_centro_atom.cpp +++ b/src/compute_centro_atom.cpp @@ -17,6 +17,8 @@ #include "modify.h" #include "update.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "force.h" #include "pair.h" #include "comm.h" @@ -34,7 +36,6 @@ ComputeCentroAtom::ComputeCentroAtom(LAMMPS *lmp, int narg, char **arg) : peratom_flag = 1; size_peratom = 0; - neigh_full_once = 1; nmax = 0; centro = NULL; @@ -61,15 +62,31 @@ void ComputeCentroAtom::init() if (strcmp(modify->compute[i]->style,"centro/atom") == 0) count++; if (count > 1 && comm->me == 0) error->warning("More than one compute centro/atom"); + + // need an occasional full neighbor list + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->occasional = 1; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeCentroAtom::init_list(int id, NeighList *ptr) +{ + list = ptr; } /* ---------------------------------------------------------------------- */ void ComputeCentroAtom::compute_peratom() { - int j,k,jj,kk,n,numneigh; + int i,j,k,ii,jj,kk,n,inum,jnum; double xtmp,ytmp,ztmp,delx,dely,delz,rsq,value; - int *neighs; + int *ilist,*jlist,*numneigh,**firstneigh; double pairs[66]; // grow centro array if necessary @@ -82,9 +99,14 @@ void ComputeCentroAtom::compute_peratom() scalar_atom = centro; } - // if needed, build a full neighbor list + // invoke full neighbor list (will copy or build if necessary) - if (!neighbor->full_every) neighbor->build_full(); + neighbor->build_one(list->index); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; // compute centro-symmetry parameter for each atom in group // use full neighbor list @@ -95,20 +117,21 @@ void ComputeCentroAtom::compute_peratom() int nall = atom->nlocal + atom->nghost; double cutsq = force->pair->cutforce * force->pair->cutforce; - for (int i = 0; i < nlocal; i++) + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; if (mask[i] & groupbit) { xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; - neighs = neighbor->firstneigh_full[i]; - numneigh = neighbor->numneigh_full[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; // insure distsq and nearest arrays are long enough - if (numneigh > maxneigh) { + if (jnum > maxneigh) { memory->sfree(distsq); memory->sfree(nearest); - maxneigh = numneigh; + maxneigh = jnum; distsq = (double *) memory->smalloc(maxneigh*sizeof(double), "compute/centro/atom:distsq"); nearest = (int *) memory->smalloc(maxneigh*sizeof(int), @@ -120,8 +143,8 @@ void ComputeCentroAtom::compute_peratom() // nearest[] = atom indices of neighbors n = 0; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j >= nall) j %= nall; delx = xtmp - x[j][0]; @@ -169,7 +192,8 @@ void ComputeCentroAtom::compute_peratom() value = 0.0; for (j = 0; j < 6; j++) value += pairs[j]; centro[i] = value; - } + } else centro[i] = 0.0; + } } /* ---------------------------------------------------------------------- diff --git a/src/compute_centro_atom.h b/src/compute_centro_atom.h index 6a16d7c059..1aa47a1d52 100644 --- a/src/compute_centro_atom.h +++ b/src/compute_centro_atom.h @@ -23,6 +23,7 @@ class ComputeCentroAtom : public Compute { ComputeCentroAtom(class LAMMPS *, int, char **); ~ComputeCentroAtom(); void init(); + void init_list(int, class NeighList *); void compute_peratom(); int memory_usage(); @@ -31,6 +32,7 @@ class ComputeCentroAtom : public Compute { double *distsq; int *nearest; double *centro; + class NeighList *list; void select(int, int, double *); void select2(int, int, double *, int *); diff --git a/src/compute_coord_atom.cpp b/src/compute_coord_atom.cpp index 285ad1aa71..f2d70915c6 100644 --- a/src/compute_coord_atom.cpp +++ b/src/compute_coord_atom.cpp @@ -17,6 +17,8 @@ #include "atom.h" #include "modify.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "force.h" #include "pair.h" #include "comm.h" @@ -30,13 +32,12 @@ using namespace LAMMPS_NS; ComputeCoordAtom::ComputeCoordAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg != 4) error->all("Illegal compute centro/atom command"); + if (narg != 4) error->all("Illegal compute coord/atom command"); cutoff = atof(arg[3]); peratom_flag = 1; size_peratom = 0; - neigh_full_once = 1; nmax = 0; coordination = NULL; @@ -56,6 +57,15 @@ void ComputeCoordAtom::init() if (force->pair == NULL || cutoff > force->pair->cutforce) error->all("Compute coord/atom cutoff is longer than pairwise cutoff"); + // need an occasional full neighbor list + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->occasional = 1; + int count = 0; for (int i = 0; i < modify->ncompute; i++) if (strcmp(modify->compute[i]->style,"coord/atom") == 0) count++; @@ -65,11 +75,18 @@ void ComputeCoordAtom::init() /* ---------------------------------------------------------------------- */ +void ComputeCoordAtom::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + void ComputeCoordAtom::compute_peratom() { - int j,k,n,numneigh; + int i,j,ii,jj,inum,jnum,n; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighs; + int *ilist,*jlist,*numneigh,**firstneigh; // grow coordination array if necessary @@ -81,9 +98,14 @@ void ComputeCoordAtom::compute_peratom() scalar_atom = coordination; } - // if needed, build a full neighbor list + // invoke full neighbor list (will copy or build if necessary) - if (!neighbor->full_every) neighbor->build_full(); + neighbor->build_one(list->index); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; // compute coordination number for each atom in group // use full neighbor list to count atoms less than cutoff @@ -94,17 +116,18 @@ void ComputeCoordAtom::compute_peratom() int nall = atom->nlocal + atom->nghost; double cutsq = cutoff*cutoff; - for (int i = 0; i < nlocal; i++) + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; if (mask[i] & groupbit) { xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; - neighs = neighbor->firstneigh_full[i]; - numneigh = neighbor->numneigh_full[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; n = 0; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j >= nall) j %= nall; delx = xtmp - x[j][0]; @@ -115,8 +138,10 @@ void ComputeCoordAtom::compute_peratom() } coordination[i] = n; - } + } else coordination[i] = 0.0; + } } + /* ---------------------------------------------------------------------- memory usage of local atom-based array ------------------------------------------------------------------------- */ diff --git a/src/compute_coord_atom.h b/src/compute_coord_atom.h index 74ff941087..ca121c1914 100644 --- a/src/compute_coord_atom.h +++ b/src/compute_coord_atom.h @@ -23,6 +23,7 @@ class ComputeCoordAtom : public Compute { ComputeCoordAtom(class LAMMPS *, int, char **); ~ComputeCoordAtom(); void init(); + void init_list(int, class NeighList *); void compute_peratom(); int memory_usage(); @@ -30,6 +31,7 @@ class ComputeCoordAtom : public Compute { int nmax; double cutoff; double *coordination; + class NeighList *list; }; } diff --git a/src/compute_ebond_atom.cpp b/src/compute_ebond_atom.cpp index 664a036e0b..f3f902bc07 100644 --- a/src/compute_ebond_atom.cpp +++ b/src/compute_ebond_atom.cpp @@ -56,7 +56,7 @@ ComputeEbondAtom::~ComputeEbondAtom() void ComputeEbondAtom::init() { if (force->bond == NULL) - error->all("Bond style does not support computing per-atom energy"); + error->all("Bond style does not support computing per-atom bond energy"); int count = 0; for (int i = 0; i < modify->ncompute; i++) @@ -69,7 +69,7 @@ void ComputeEbondAtom::init() void ComputeEbondAtom::compute_peratom() { - int i,n,i1,i2,type; + int i,n,i1,i2,type,iflag,jflag; double delx,dely,delz,rsq,fforce,eng; // grow energy array if necessary @@ -95,6 +95,7 @@ void ComputeEbondAtom::compute_peratom() // compute bond energy for atoms via bond->single() // if neither atom is in compute group, skip that bond + // only add energy to atoms in group double **x = atom->x; int *mask = atom->mask; @@ -105,7 +106,9 @@ void ComputeEbondAtom::compute_peratom() i1 = bondlist[n][0]; i2 = bondlist[n][1]; type = bondlist[n][2]; - if ((mask[i1] & groupbit) == 0 && (mask[i2] & groupbit) == 0) continue; + iflag = mask[i1] & groupbit; + jflag = mask[i2] & groupbit; + if (iflag == 0 && jflag == 0) continue; delx = x[i1][0] - x[i2][0]; dely = x[i1][1] - x[i2][1]; @@ -114,8 +117,8 @@ void ComputeEbondAtom::compute_peratom() rsq = delx*delx + dely*dely + delz*delz; force->bond->single(type,rsq,i1,i2,0,fforce,eng); - energy[i] += eng; - if (newton_bond || i2 < nlocal) energy[i2] += eng; + if (iflag) energy[i1] += eng; + if (jflag && (newton_bond || i2 < nlocal)) energy[i2] += eng; } // communicate energy between neigchbor procs diff --git a/src/compute_epair_atom.cpp b/src/compute_epair_atom.cpp index 36a16d92be..f7b3a4b7eb 100644 --- a/src/compute_epair_atom.cpp +++ b/src/compute_epair_atom.cpp @@ -15,6 +15,8 @@ #include "compute_epair_atom.h" #include "atom.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "modify.h" #include "comm.h" #include "update.h" @@ -38,7 +40,6 @@ ComputeEpairAtom::ComputeEpairAtom(LAMMPS *lmp, int narg, char **arg) : peratom_flag = 1; size_peratom = 0; comm_reverse = 1; - neigh_half_once = 1; nmax = 0; energy = NULL; @@ -58,6 +59,13 @@ void ComputeEpairAtom::init() if (force->pair == NULL || force->pair->single_enable == 0) error->all("Pair style does not support computing per-atom energy"); + // need an occasional half neighbor list + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; + if (force->pair_match("eam")) eamstyle = 1; else eamstyle = 0; @@ -70,12 +78,19 @@ void ComputeEpairAtom::init() /* ---------------------------------------------------------------------- */ +void ComputeEpairAtom::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + void ComputeEpairAtom::compute_peratom() { - int i,j,k,n,itype,jtype,numneigh,iflag; + int i,j,ii,jj,n,inum,jnum,itype,jtype,iflag,jflag; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double factor_coul,factor_lj,eng; - int *neighs; + int *ilist,*jlist,*numneigh,**firstneigh; Pair::One one; // grow energy array if necessary @@ -99,12 +114,18 @@ void ComputeEpairAtom::compute_peratom() for (i = 0; i < n; i++) energy[i] = 0.0; - // if needed, build a half neighbor list + // invoke half neighbor list (will copy or build if necessary) - if (!neighbor->half_every) neighbor->build_half(); + neighbor->build_one(list->index); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; // compute pairwise energy for atoms via pair->single() // if neither atom is in compute group, skip that pair + // only add energy to atoms in group double *special_coul = force->special_coul; double *special_lj = force->special_lj; @@ -115,18 +136,20 @@ void ComputeEpairAtom::compute_peratom() int *type = atom->type; int nall = nlocal + atom->nghost; - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; iflag = mask[i] & groupbit; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; - - for (k = 0; k < numneigh; k++) { - j = neighs[k]; - if (iflag == 0 && (mask[j] & groupbit) == 0) continue; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + jflag = mask[j] & groupbit; + if (iflag == 0 && jflag == 0) continue; if (j < nall) factor_coul = factor_lj = 1.0; else { @@ -144,8 +167,8 @@ void ComputeEpairAtom::compute_peratom() if (rsq < cutsq[itype][jtype]) { force->pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,1,one); eng = one.eng_coul + one.eng_vdwl; - energy[i] += eng; - if (newton_pair || j < nlocal) energy[j] += eng; + if (iflag) energy[i] += eng; + if (jflag && (newton_pair || j < nlocal)) energy[j] += eng; } } } @@ -162,7 +185,8 @@ void ComputeEpairAtom::compute_peratom() // only for atoms in compute group if (eamstyle) { - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; if (mask[i] & groupbit) { force->pair->single_embed(i,type[i],eng); energy[i] += eng; diff --git a/src/compute_epair_atom.h b/src/compute_epair_atom.h index 6ead5058f5..6ab6160b5b 100644 --- a/src/compute_epair_atom.h +++ b/src/compute_epair_atom.h @@ -23,6 +23,7 @@ class ComputeEpairAtom : public Compute { ComputeEpairAtom(class LAMMPS *, int, char **); ~ComputeEpairAtom(); void init(); + void init_list(int, class NeighList *); void compute_peratom(); int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); @@ -30,6 +31,7 @@ class ComputeEpairAtom : public Compute { private: int nmax,eamstyle; + class NeighList *list; double *energy; }; diff --git a/src/compute_etotal_atom.cpp b/src/compute_etotal_atom.cpp deleted file mode 100644 index e287cdd6f9..0000000000 --- a/src/compute_etotal_atom.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "string.h" -#include "compute_etotal_atom.h" -#include "atom.h" -#include "modify.h" -#include "force.h" -#include "comm.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -ComputeEtotalAtom::ComputeEtotalAtom(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg) -{ - if (narg != 4) error->all("Illegal compute etotal/atom command"); - - // store epair ID used by energy computation - - int n = strlen(arg[3]) + 1; - id_pre = new char[n]; - strcpy(id_pre,arg[3]); - - peratom_flag = 1; - size_peratom = 0; - - nmax = 0; - etotal = NULL; -} - -/* ---------------------------------------------------------------------- */ - -ComputeEtotalAtom::~ComputeEtotalAtom() -{ - delete [] id_pre; - memory->sfree(etotal); -} - -/* ---------------------------------------------------------------------- */ - -void ComputeEtotalAtom::init() -{ - int count = 0; - for (int i = 0; i < modify->ncompute; i++) - if (strcmp(modify->compute[i]->style,"etotal/atom") == 0) count++; - if (count > 1 && comm->me == 0) - error->warning("More than one compute etotal/atom"); - - // set epair Compute used by this compute - - int icompute = modify->find_compute(id_pre); - if (icompute < 0) - error->all("Could not find compute etotal/atom pre-compute ID"); - compute_epair = modify->compute[icompute]; - - if (groupbit != compute_epair->groupbit && comm->me == 0) - error->warning("Group for compute etotal and its epair are not the same"); -} - -/* ---------------------------------------------------------------------- */ - -void ComputeEtotalAtom::compute_peratom() -{ - // grow etotal array if necessary - - if (atom->nlocal > nmax) { - memory->sfree(etotal); - nmax = atom->nmax; - etotal = (double *) - memory->smalloc(nmax*sizeof(double),"compute/etotal/atom:etotal"); - scalar_atom = etotal; - } - - // compute total energy for each atom in group - - double *epair = compute_epair->scalar_atom; - double mvv2e = force->mvv2e; - double **v = atom->v; - double *mass = atom->mass; - double *rmass = atom->rmass; - int *mask = atom->mask; - int *type = atom->type; - int nlocal = atom->nlocal; - - double ke; - - if (mass) - for (int i = 0; i < nlocal; i++) { - if (mask[i] & groupbit) { - ke = 0.5 * mvv2e * mass[type[i]] * - (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]); - etotal[i] = ke + epair[i]; - } - } - else - for (int i = 0; i < nlocal; i++) { - if (mask[i] & groupbit) { - ke = 0.5 * mvv2e * rmass[i] * - (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]); - etotal[i] = ke + epair[i]; - } - } -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based array -------------------------------------------------------------------------- */ - -int ComputeEtotalAtom::memory_usage() -{ - int bytes = nmax * sizeof(double); - return bytes; -} diff --git a/src/compute_ke_atom.cpp b/src/compute_ke_atom.cpp index 9734594165..27d123bd5d 100644 --- a/src/compute_ke_atom.cpp +++ b/src/compute_ke_atom.cpp @@ -82,14 +82,15 @@ void ComputeKEAtom::compute_peratom() if (mask[i] & groupbit) { ke[i] = 0.5 * mvv2e * mass[type[i]] * (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]); - } + } else ke[i] = 0.0; } + else for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { ke[i] = 0.5 * mvv2e * rmass[i] * (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]); - } + } else ke[i] = 0.0; } } diff --git a/src/compute_pressure.cpp b/src/compute_pressure.cpp index d32f16230d..554fb57837 100644 --- a/src/compute_pressure.cpp +++ b/src/compute_pressure.cpp @@ -42,11 +42,13 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : // store temperature ID used by pressure computation // insure it is valid for temperature computation + npre = 1; + id_pre = new char*[1]; int n = strlen(arg[3]) + 1; - id_pre = new char[n]; - strcpy(id_pre,arg[3]); + id_pre[0] = new char[n]; + strcpy(id_pre[0],arg[3]); - int icompute = modify->find_compute(id_pre); + int icompute = modify->find_compute(id_pre[0]); if (icompute < 0) error->all("Could not find compute pressure temp ID"); if (modify->compute[icompute]->tempflag == 0) @@ -66,7 +68,6 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : ComputePressure::~ComputePressure() { - delete [] id_pre; delete [] vector; delete [] vptr; } @@ -81,7 +82,7 @@ void ComputePressure::init() // set temperature used by pressure - int icompute = modify->find_compute(id_pre); + int icompute = modify->find_compute(id_pre[0]); if (icompute < 0) error->all("Could not find compute pressure temp ID"); temperature = modify->compute[icompute]; diff --git a/src/compute_stress_atom.cpp b/src/compute_stress_atom.cpp index 1ff7541124..eb113fec27 100644 --- a/src/compute_stress_atom.cpp +++ b/src/compute_stress_atom.cpp @@ -15,6 +15,8 @@ #include "compute_stress_atom.h" #include "atom.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "modify.h" #include "comm.h" #include "update.h" @@ -40,7 +42,6 @@ ComputeStressAtom::ComputeStressAtom(LAMMPS *lmp, int narg, char **arg) : peratom_flag = 1; size_peratom = 6; comm_reverse = 6; - neigh_half_once = 1; // process args @@ -85,6 +86,14 @@ void ComputeStressAtom::init() if (force->pair == NULL || force->pair->single_enable == 0) error->all("Pair style does not support computing per-atom stress"); pairflag = 1; + + // need an occasional half neighbor list + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->occasional = 1; + } else pairflag = 0; if (bondrequest && force->bond) bondflag = 1; @@ -99,12 +108,19 @@ void ComputeStressAtom::init() /* ---------------------------------------------------------------------- */ +void ComputeStressAtom::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + void ComputeStressAtom::compute_peratom() { - int i,j,k,n,i1,i2,itype,jtype,numneigh,iflag; + int i,j,ii,jj,n,i1,i2,inum,jnum,itype,jtype,iflag,jflag; double xtmp,ytmp,ztmp,delx,dely,delz,rsq,eng; double factor_coul,factor_lj,fforce,rmass; - int *neighs; + int *ilist,*jlist,*numneigh,**firstneigh; Pair::One one; // grow stress array if necessary @@ -136,12 +152,18 @@ void ComputeStressAtom::compute_peratom() // compute pairwise stress for atoms via pair->single() // if neither atom is in compute group, skip that pair + // only add stress to atoms in group if (pairflag) { - // if needed, build a half neighbor list + // invoke half neighbor list (will copy or build if necessary) - if (!neighbor->half_every) neighbor->build_half(); + neighbor->build_one(list->index); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; double *special_coul = force->special_coul; double *special_lj = force->special_lj; @@ -153,18 +175,20 @@ void ComputeStressAtom::compute_peratom() int *type = atom->type; int nall = nlocal + atom->nghost; - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; iflag = mask[i] & groupbit; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; - - for (k = 0; k < numneigh; k++) { - j = neighs[k]; - if (iflag == 0 && (mask[j] & groupbit) == 0) continue; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + jflag = mask[j] & groupbit; + if (iflag == 0 && jflag == 0) continue; if (j < nall) factor_coul = factor_lj = 1.0; else { @@ -183,13 +207,15 @@ void ComputeStressAtom::compute_peratom() force->pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,0,one); fforce = one.fforce; - stress[i][0] -= delx*delx*fforce; - stress[i][1] -= dely*dely*fforce; - stress[i][2] -= delz*delz*fforce; - stress[i][3] -= delx*dely*fforce; - stress[i][4] -= delx*delz*fforce; - stress[i][5] -= dely*delz*fforce; - if (newton_pair || j < nlocal) { + if (iflag) { + stress[i][0] -= delx*delx*fforce; + stress[i][1] -= dely*dely*fforce; + stress[i][2] -= delz*delz*fforce; + stress[i][3] -= delx*dely*fforce; + stress[i][4] -= delx*delz*fforce; + stress[i][5] -= dely*delz*fforce; + } + if (jflag && (newton_pair || j < nlocal)) { stress[j][0] -= delx*delx*fforce; stress[j][1] -= dely*dely*fforce; stress[j][2] -= delz*delz*fforce; @@ -205,6 +231,7 @@ void ComputeStressAtom::compute_peratom() // compute bond stress for atoms via bond->single() // if neither atom is in compute group, skip that bond + // only add stress to atoms in group if (bondflag) { double **x = atom->x; @@ -218,7 +245,9 @@ void ComputeStressAtom::compute_peratom() i1 = bondlist[n][0]; i2 = bondlist[n][1]; type = bondlist[n][2]; - if ((mask[i1] & groupbit) == 0 && (mask[i2] & groupbit) == 0) continue; + iflag = mask[i1] & groupbit; + jflag = mask[i2] & groupbit; + if (iflag == 0 && jflag == 0) continue; delx = x[i1][0] - x[i2][0]; dely = x[i1][1] - x[i2][1]; @@ -228,14 +257,16 @@ void ComputeStressAtom::compute_peratom() rsq = delx*delx + dely*dely + delz*delz; force->bond->single(type,rsq,i1,i2,0,fforce,eng); - stress[i1][0] -= delx*delx*fforce; - stress[i1][1] -= dely*dely*fforce; - stress[i1][2] -= delz*delz*fforce; - stress[i1][3] -= delx*dely*fforce; - stress[i1][4] -= delx*delz*fforce; - stress[i1][5] -= dely*delz*fforce; - - if (newton_bond || i2 < nlocal) { + if (iflag) { + stress[i1][0] -= delx*delx*fforce; + stress[i1][1] -= dely*dely*fforce; + stress[i1][2] -= delz*delz*fforce; + stress[i1][3] -= delx*dely*fforce; + stress[i1][4] -= delx*delz*fforce; + stress[i1][5] -= dely*delz*fforce; + } + + if (jflag && (newton_bond || i2 < nlocal)) { stress[i2][0] -= delx*delx*fforce; stress[i2][1] -= dely*dely*fforce; stress[i2][2] -= delz*delz*fforce; diff --git a/src/compute_stress_atom.h b/src/compute_stress_atom.h index 469fc331e3..b936be8041 100644 --- a/src/compute_stress_atom.h +++ b/src/compute_stress_atom.h @@ -24,6 +24,7 @@ class ComputeStressAtom : public Compute { ComputeStressAtom(class LAMMPS *, int, char **); ~ComputeStressAtom(); void init(); + void init_list(int, class NeighList *); void compute_peratom(); int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); @@ -33,7 +34,7 @@ class ComputeStressAtom : public Compute { int pairrequest,bondrequest,kerequest; int pairflag,bondflag; int nmax; - + class NeighList *list; double **stress; }; diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index 081741541a..4fcc982956 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -22,6 +22,8 @@ #include "group.h" #include "region.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "comm.h" #include "force.h" #include "error.h" @@ -53,15 +55,15 @@ void DeleteAtoms::command(int narg, char **arg) // allocate and initialize deletion list int nlocal = atom->nlocal; - int *list = new int[nlocal]; + int *dlist = new int[nlocal]; - for (int i = 0; i < nlocal; i++) list[i] = 0; + for (int i = 0; i < nlocal; i++) dlist[i] = 0; // delete the atoms - if (strcmp(arg[0],"group") == 0) delete_group(narg,arg,list); - else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg,list); - else if (strcmp(arg[0],"overlap") == 0) delete_overlap(narg,arg,list); + if (strcmp(arg[0],"group") == 0) delete_group(narg,arg,dlist); + else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg,dlist); + else if (strcmp(arg[0],"overlap") == 0) delete_overlap(narg,arg,dlist); else error->all("Illegal delete_atoms command"); // delete local atoms in list @@ -71,14 +73,14 @@ void DeleteAtoms::command(int narg, char **arg) int i = 0; while (i < nlocal) { - if (list[i]) { + if (dlist[i]) { avec->copy(nlocal-1,i); - list[i] = list[nlocal-1]; + dlist[i] = dlist[nlocal-1]; nlocal--; } else i++; } atom->nlocal = nlocal; - delete [] list; + delete [] dlist; // if non-molecular system, reset atom tags to be contiguous // set all atom IDs to 0, call tag_extend() @@ -120,7 +122,7 @@ void DeleteAtoms::command(int narg, char **arg) group will still exist ------------------------------------------------------------------------- */ -void DeleteAtoms::delete_group(int narg, char **arg, int *list) +void DeleteAtoms::delete_group(int narg, char **arg, int *dlist) { if (narg != 2) error->all("Illegal delete_atoms command"); @@ -132,14 +134,14 @@ void DeleteAtoms::delete_group(int narg, char **arg, int *list) int groupbit = group->bitmask[igroup]; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) list[i] = 1; + if (mask[i] & groupbit) dlist[i] = 1; } /* ---------------------------------------------------------------------- delete all atoms in region ------------------------------------------------------------------------- */ -void DeleteAtoms::delete_region(int narg, char **arg, int *list) +void DeleteAtoms::delete_region(int narg, char **arg, int *dlist) { if (narg != 2) error->all("Illegal delete_atoms command"); @@ -150,7 +152,7 @@ void DeleteAtoms::delete_region(int narg, char **arg, int *list) int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) list[i] = 1; + if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) dlist[i] = 1; } /* ---------------------------------------------------------------------- @@ -160,7 +162,7 @@ void DeleteAtoms::delete_region(int narg, char **arg, int *list) no guarantee that minimium number of atoms will be deleted ------------------------------------------------------------------------- */ -void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) +void DeleteAtoms::delete_overlap(int narg, char **arg, int *dlist) { if (narg < 2) error->all("Illegal delete_atoms command"); @@ -180,19 +182,29 @@ void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) type2 = atoi(arg[3]); } else error->all("Illegal delete_atoms command"); - // init entire system since comm->borders and neighbor->build is done - // comm::init needs neighbor::init needs pair::init needs kspace::init, etc - // set half_command since will require half neigh list even if - // neighbor would otherwise not create one, then unset it - if (comm->me == 0 && screen) fprintf(screen,"System init for delete_atoms ...\n"); - neighbor->half_command = 1; + + // request a half neighbor list for use by this command + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->command = 1; + neighbor->requests[irequest]->occasional = 1; + + // init entire system since comm->borders and neighbor->build is done + // comm::init needs neighbor::init needs pair::init needs kspace::init, etc + lmp->init(); - neighbor->half_command = 0; + + // error check on cutoff + + if (cut > neighbor->cutghost) + error->all("Delete_atoms cutoff > ghost cutoff"); // setup domain, communication and neighboring // acquire ghosts + // build neighbor list based on earlier request if (domain->triclinic) domain->x2lamda(atom->nlocal); domain->pbc(); @@ -203,16 +215,8 @@ void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) comm->borders(); if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost); - // call to build() forces memory allocation for neighbor lists - // build half list explicitly if build() doesn't do it - - neighbor->build(); - if (!neighbor->half_every) neighbor->build_half(); - - // error check on cutoff - - if (cut > neighbor->cutghost) - error->all("Delete_atoms cutoff > ghost cutoff"); + NeighList *list = neighbor->lists[irequest]; + neighbor->build_one(irequest); // create an atom map if one doesn't exist already @@ -245,30 +249,37 @@ void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) double *special_lj = force->special_lj; int newton_pair = force->newton_pair; - int i,j,k,m,itype,jtype,numneigh; + int i,j,ii,jj,m,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighs; + int *ilist,*jlist,*numneigh,**firstneigh; - for (i = 0; i < nlocal; i++) { + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; - - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + if (j >= nall) { if (special_coul[j/nall] == 0.0 && special_lj[j/nall] == 0.0) continue; j %= nall; } if (j < nlocal) { - if (list[j]) continue; + if (dlist[j]) continue; } else { m = atom->map(tag[j]); - if (m < nlocal && list[m]) continue; + if (m < nlocal && dlist[m]) continue; } delx = xtmp - x[j][0]; @@ -286,7 +297,7 @@ void DeleteAtoms::delete_overlap(int narg, char **arg, int *list) if (j >= nlocal && newton_pair == 0 && tag[j] < tag[i]) continue; - list[i] = 1; + dlist[i] = 1; break; } } diff --git a/src/domain.cpp b/src/domain.cpp index c4a69443eb..cece653486 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -811,7 +811,7 @@ void Domain::set_boundary(int narg, char **arg) print box info, orthogonal or triclinic ------------------------------------------------------------------------- */ -void Domain::print_box(char *str) +void Domain::print_box(const char *str) { if (comm->me == 0) { if (screen) { @@ -819,7 +819,7 @@ void Domain::print_box(char *str) fprintf(screen,"%sorthogonal box = (%g %g %g) to (%g %g %g)\n", str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2]); else { - char *format = + char *format = (char *) "%striclinic box = (%g %g %g) to (%g %g %g) with tilt (%g %g %g)\n"; fprintf(screen,format, str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2], @@ -831,7 +831,7 @@ void Domain::print_box(char *str) fprintf(logfile,"%sorthogonal box = (%g %g %g) to (%g %g %g)\n", str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2]); else { - char *format = + char *format = (char *) "%striclinic box = (%g %g %g) to (%g %g %g) with tilt (%g %g %g)\n"; fprintf(logfile,format, str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2], diff --git a/src/domain.h b/src/domain.h index 07b4d13594..a0bd61eec5 100644 --- a/src/domain.h +++ b/src/domain.h @@ -97,7 +97,7 @@ class Domain : protected Pointers { void add_region(int, char **); int find_region(char *); void set_boundary(int, char **); - void print_box(char *); + void print_box(const char *); void lamda2x(int); void x2lamda(int); diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp index 02bcd0836c..50aea9be29 100644 --- a/src/dump_atom.cpp +++ b/src/dump_atom.cpp @@ -59,8 +59,8 @@ void DumpAtom::init() strcat(format,"\n"); } else { char *str; - if (image_flag == 0) str = "%d %d %g %g %g"; - else str = "%d %d %g %g %g %d %d %d"; + if (image_flag == 0) str = (char *) "%d %d %g %g %g"; + else str = (char *) "%d %d %g %g %g %d %d %d"; int n = strlen(str) + 2; format = new char[n]; strcpy(format,str); diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 3561aea034..a167a5e3ce 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -22,6 +22,7 @@ #include "update.h" #include "modify.h" #include "compute.h" +#include "fix.h" #include "memory.h" #include "error.h" @@ -33,8 +34,7 @@ enum{TAG,MOL,TYPE,X,Y,Z,XS,YS,ZS,XU,YU,ZU,IX,IY,IZ, VX,VY,VZ,FX,FY,FZ, Q,MUX,MUY,MUZ, QUATW,QUATI,QUATJ,QUATK,TQX,TQY,TQZ, - EPAIR,EBOND,KE,ETOTAL,CENTRO,SXX,SYY,SZZ,SXY,SXZ,SYZ, - COMPUTE}; + COMPUTE,FIX}; enum{LT,LE,GT,GE,EQ,NEQ}; enum{INT,DOUBLE}; @@ -45,6 +45,8 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : { if (narg == 5) error->all("No dump custom arguments specified"); + nevery = atoi(arg[3]); + size_one = nfield = narg-5; pack_choice = new FnPtrPack[nfield]; vtype = new int[nfield]; @@ -55,17 +57,7 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : thresh_op = NULL; thresh_value = NULL; - // flags, IDs, and memory for compute objects dump may create - - index_epair = index_ebond = index_ke = - index_etotal = index_centro = index_stress = -1; - - style_epair = "epair/atom"; - style_ebond = "ebond/atom"; - style_ke = "ke/atom"; - style_etotal = "etotal/atom"; - style_centro = "centro/atom"; - style_stress = "stress/atom"; + // compute and fix objects dump may create ncompute = 0; id_compute = NULL; @@ -74,19 +66,16 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : "dump:field2compute"); arg_compute = (int *) memory->smalloc(nfield*sizeof(int),"dump:arg_compute"); + nfix = 0; + id_fix = NULL; + fix = NULL; + field2fix = (int *) memory->smalloc(nfield*sizeof(int),"dump:field2fix"); + arg_fix = (int *) memory->smalloc(nfield*sizeof(int),"dump:arg_fix"); + // process keywords parse_fields(narg,arg); - // create the requested Computes - - if (index_epair >= 0) create_compute(style_epair,NULL); - if (index_ebond >= 0) create_compute(style_ebond,NULL); - if (index_ke >= 0) create_compute(style_ke,NULL); - if (index_etotal >= 0) create_compute(style_etotal,style_epair); - if (index_centro >= 0) create_compute(style_centro,NULL); - if (index_stress >= 0) create_compute(style_stress,NULL); - // atom selection arrays maxlocal = 0; @@ -122,21 +111,18 @@ DumpCustom::~DumpCustom() memory->sfree(thresh_op); memory->sfree(thresh_value); - // delete Compute classes if dump custom created them - - if (index_epair >= 0) modify->delete_compute(id_compute[index_epair]); - if (index_ebond >= 0) modify->delete_compute(id_compute[index_ebond]); - if (index_ke >= 0) modify->delete_compute(id_compute[index_ke]); - if (index_etotal >= 0) modify->delete_compute(id_compute[index_etotal]); - if (index_centro >= 0) modify->delete_compute(id_compute[index_centro]); - if (index_stress >= 0) modify->delete_compute(id_compute[index_stress]); - for (int i = 0; i < ncompute; i++) delete [] id_compute[i]; memory->sfree(id_compute); memory->sfree(compute); memory->sfree(field2compute); memory->sfree(arg_compute); + for (int i = 0; i < nfix; i++) delete [] id_fix[i]; + memory->sfree(id_fix); + memory->sfree(fix); + memory->sfree(field2fix); + memory->sfree(arg_fix); + delete [] choose; delete [] dchoose; @@ -177,7 +163,8 @@ void DumpCustom::init() if (binary) write_choice = &DumpCustom::write_binary; else write_choice = &DumpCustom::write_text; - // find current ptr for each Compute ID + // find current ptr for each compute and fix ID + // check that fix frequency is acceptable int icompute; for (int i = 0; i < ncompute; i++) { @@ -185,6 +172,15 @@ void DumpCustom::init() if (icompute < 0) error->all("Could not find dump custom compute ID"); compute[i] = modify->compute[icompute]; } + + int ifix; + for (int i = 0; i < nfix; i++) { + ifix = modify->find_fix(id_fix[i]); + if (ifix < 0) error->all("Could not find dump custom fix ID"); + fix[i] = modify->fix[ifix]; + if (nevery % modify->fix[ifix]->peratom_freq) + error->all("Dump custom and fix not computed at compatible times"); + } } /* ---------------------------------------------------------------------- */ @@ -431,39 +427,7 @@ int DumpCustom::count() } else if (thresh_array[ithresh] == TQZ) { ptr = &atom->torque[0][2]; nstride = 3; - } else if (thresh_array[ithresh] == EPAIR) { - ptr = compute[index_epair]->scalar_atom; - nstride = 1; - } else if (thresh_array[ithresh] == EBOND) { - ptr = compute[index_ebond]->scalar_atom; - nstride = 1; - } else if (thresh_array[ithresh] == KE) { - ptr = compute[index_ke]->scalar_atom; - nstride = 1; - } else if (thresh_array[ithresh] == ETOTAL) { - ptr = compute[index_etotal]->scalar_atom; - nstride = 1; - } else if (thresh_array[ithresh] == CENTRO) { - ptr = compute[index_centro]->scalar_atom; - nstride = 1; - } else if (thresh_array[ithresh] == SXX) { - ptr = &compute[index_stress]->vector_atom[0][0]; - nstride = 6; - } else if (thresh_array[ithresh] == SYY) { - ptr = &compute[index_stress]->vector_atom[0][1]; - nstride = 6; - } else if (thresh_array[ithresh] == SZZ) { - ptr = &compute[index_stress]->vector_atom[0][2]; - nstride = 6; - } else if (thresh_array[ithresh] == SXY) { - ptr = &compute[index_stress]->vector_atom[0][3]; - nstride = 6; - } else if (thresh_array[ithresh] == SXZ) { - ptr = &compute[index_stress]->vector_atom[0][4]; - nstride = 6; - } else if (thresh_array[ithresh] == SYZ) { - ptr = &compute[index_stress]->vector_atom[0][5]; - nstride = 6; + } else if (thresh_array[ithresh] == COMPUTE) { i = nfield + ithresh; if (arg_compute[i] == 0) { @@ -473,6 +437,16 @@ int DumpCustom::count() ptr = &compute[field2compute[i]]->vector_atom[0][arg_compute[i]-1]; nstride = compute[field2compute[i]]->size_peratom; } + + } else if (thresh_array[ithresh] == FIX) { + i = nfield + ithresh; + if (arg_fix[i] == 0) { + ptr = fix[field2fix[i]]->scalar_atom; + nstride = 1; + } else { + ptr = &fix[field2fix[i]]->vector_atom[0][arg_fix[i]-1]; + nstride = fix[field2fix[i]]->size_peratom; + } } // unselect atoms that don't meet threshhold criterion @@ -704,56 +678,9 @@ void DumpCustom::parse_fields(int narg, char **arg) pack_choice[i] = &DumpCustom::pack_tqz; vtype[i] = DOUBLE; - } else if (strcmp(arg[iarg],"epair") == 0) { - pack_choice[i] = &DumpCustom::pack_epair; - vtype[i] = DOUBLE; - index_epair = add_compute(style_epair,1); - } else if (strcmp(arg[iarg],"ebond") == 0) { - pack_choice[i] = &DumpCustom::pack_ebond; - vtype[i] = DOUBLE; - index_ebond = add_compute(style_ebond,1); - } else if (strcmp(arg[iarg],"ke") == 0) { - pack_choice[i] = &DumpCustom::pack_ke; - vtype[i] = DOUBLE; - index_ke = add_compute(style_ke,1); - } else if (strcmp(arg[iarg],"etotal") == 0) { - pack_choice[i] = &DumpCustom::pack_etotal; - vtype[i] = DOUBLE; - index_epair = add_compute(style_epair,1); - index_etotal = add_compute(style_etotal,1); - } else if (strcmp(arg[iarg],"centro") == 0) { - pack_choice[i] = &DumpCustom::pack_centro; - vtype[i] = DOUBLE; - index_centro = add_compute(style_centro,1); - - } else if (strcmp(arg[iarg],"sxx") == 0) { - pack_choice[i] = &DumpCustom::pack_sxx; - vtype[i] = DOUBLE; - index_stress = add_compute(style_stress,1); - } else if (strcmp(arg[iarg],"syy") == 0) { - pack_choice[i] = &DumpCustom::pack_syy; - vtype[i] = DOUBLE; - index_stress = add_compute(style_stress,1); - } else if (strcmp(arg[iarg],"szz") == 0) { - pack_choice[i] = &DumpCustom::pack_szz; - vtype[i] = DOUBLE; - index_stress = add_compute(style_stress,1); - } else if (strcmp(arg[iarg],"sxy") == 0) { - pack_choice[i] = &DumpCustom::pack_sxy; - vtype[i] = DOUBLE; - index_stress = add_compute(style_stress,1); - } else if (strcmp(arg[iarg],"sxz") == 0) { - pack_choice[i] = &DumpCustom::pack_sxz; - vtype[i] = DOUBLE; - index_stress = add_compute(style_stress,1); - } else if (strcmp(arg[iarg],"syz") == 0) { - pack_choice[i] = &DumpCustom::pack_syz; - vtype[i] = DOUBLE; - index_stress = add_compute(style_stress,1); - // compute value = c_ID // if no trailing [], then arg is set to 0, else arg is between [] - // if Compute has pre-compute, first add it to list + // if Compute has pre-computes, first add them to list } else if (strncmp(arg[iarg],"c_",2) == 0) { pack_choice[i] = &DumpCustom::pack_compute; @@ -782,9 +709,43 @@ void DumpCustom::parse_fields(int narg, char **arg) if (arg_compute[i] > 0 && arg_compute[i] > modify->compute[n]->size_peratom) error->all("Dump custom compute ID vector is not large enough"); - if (modify->compute[n]->id_pre) - int tmp = add_compute(modify->compute[n]->id_pre,0); - field2compute[i] = add_compute(suffix,0); + if (modify->compute[n]->npre) + for (int ic = 0; ic < modify->compute[n]->npre; ic++) + int tmp = add_compute(modify->compute[n]->id_pre[ic]); + field2compute[i] = add_compute(suffix); + delete [] suffix; + + // fix value = f_ID + // if no trailing [], then arg is set to 0, else arg is between [] + + } else if (strncmp(arg[iarg],"f_",2) == 0) { + pack_choice[i] = &DumpCustom::pack_fix; + vtype[i] = DOUBLE; + + int n = strlen(arg[iarg]); + char *suffix = new char[n]; + strcpy(suffix,&arg[iarg][2]); + + char *ptr = strchr(suffix,'['); + if (ptr) { + if (suffix[strlen(suffix)-1] != ']') + error->all("Invalid keyword in dump custom command"); + arg_fix[i] = atoi(ptr+1); + *ptr = '\0'; + } else arg_fix[i] = 0; + + n = modify->find_fix(suffix); + if (n < 0) error->all("Could not find dump custom fix ID"); + if (modify->fix[n]->peratom_flag == 0) + error->all("Dump custom fix ID does not compute peratom info"); + if (arg_fix[i] == 0 && modify->fix[n]->size_peratom > 0) + error->all("Dump custom fix ID does not compute scalar per atom"); + if (arg_fix[i] > 0 && modify->fix[n]->size_peratom == 0) + error->all("Dump custom fix ID does not compute vector per atom"); + if (arg_fix[i] > 0 && + arg_fix[i] > modify->fix[n]->size_peratom) + error->all("Dump custom fix ID vector is not large enough"); + field2fix[i] = add_fix(suffix); delete [] suffix; } else error->all("Invalid keyword in dump custom command"); @@ -792,76 +753,53 @@ void DumpCustom::parse_fields(int narg, char **arg) } /* ---------------------------------------------------------------------- - add Compute to list of Compute objects to call - return index of where this Compute is in call list - compute ID = dump-ID + "_" + keyword if appendflag is set, else just keyword - if already in call list, do not add, just return index, else add to list + add Compute to list of Compute objects used by dump + return index of where this Compute is in list + if already in list, do not add, just return index, else add to list ------------------------------------------------------------------------- */ -int DumpCustom::add_compute(char *keyword, int appendflag) +int DumpCustom::add_compute(char *id) { - int n = strlen(id) + strlen(keyword) + 2; - char *name = new char[n]; - if (appendflag) { - strcpy(name,id); - strcat(name,"_"); - strcat(name,keyword); - } else strcpy(name,keyword); - int icompute; for (icompute = 0; icompute < ncompute; icompute++) - if (strcmp(name,id_compute[icompute]) == 0) break; - if (icompute < ncompute) { - delete [] name; - return icompute; - } + if (strcmp(id,id_compute[icompute]) == 0) break; + if (icompute < ncompute) return icompute; id_compute = (char **) memory->srealloc(id_compute,(ncompute+1)*sizeof(char *),"dump:id_compute"); compute = (Compute **) memory->srealloc(compute,(ncompute+1)*sizeof(Compute *),"dump:compute"); - n = strlen(name) + 1; + int n = strlen(id) + 1; id_compute[ncompute] = new char[n]; - strcpy(id_compute[ncompute],name); - delete [] name; + strcpy(id_compute[ncompute],id); ncompute++; return ncompute-1; } /* ---------------------------------------------------------------------- - create a compute - compute ID = dump-ID + "_" + keyword, compute style = keyword - pass additional extra arg to Modify::add_compute() if defined + add Fix to list of Fix objects used by dump + return index of where this Fix is in list + if already in list, do not add, just return index, else add to list ------------------------------------------------------------------------- */ -void DumpCustom::create_compute(char *keyword, char *extra) +int DumpCustom::add_fix(char *id) { - int n = strlen(id) + strlen(keyword) + 2; - char *name = new char[n]; - strcpy(name,id); - strcat(name,"_"); - strcat(name,keyword); + int ifix; + for (ifix = 0; ifix < nfix; ifix++) + if (strcmp(id,id_fix[ifix]) == 0) break; + if (ifix < nfix) return ifix; + + id_fix = (char **) + memory->srealloc(id_fix,(nfix+1)*sizeof(char *),"dump:id_fix"); + fix = (Fix **) + memory->srealloc(fix,(nfix+1)*sizeof(Fix *),"dump:fix"); - char **newarg = new char*[4]; - newarg[0] = name; - newarg[1] = group->names[igroup]; - newarg[2] = keyword; - - if (extra) { - n = strlen(id) + strlen(extra) + 2; - newarg[3] = new char[n]; - strcpy(newarg[3],id); - strcat(newarg[3],"_"); - strcat(newarg[3],extra); - } else newarg[3] = NULL; - - if (extra) modify->add_compute(4,newarg); - else modify->add_compute(3,newarg); - - delete [] name; - delete [] newarg[3]; - delete [] newarg; + int n = strlen(id) + 1; + id_fix[nfix] = new char[n]; + strcpy(id_fix[nfix],id); + nfix++; + return nfix-1; } /* ---------------------------------------------------------------------- */ @@ -948,84 +886,14 @@ int DumpCustom::modify_param(int narg, char **arg) else if (strcmp(arg[1],"tqx") == 0) thresh_array[nthresh] = TQX; else if (strcmp(arg[1],"tqy") == 0) thresh_array[nthresh] = TQY; else if (strcmp(arg[1],"tqz") == 0) thresh_array[nthresh] = TQZ; - else if (strcmp(arg[1],"epair") == 0) { - thresh_array[nthresh] = EPAIR; - if (index_epair < 0) { - index_epair = add_compute(style_epair,1); - create_compute(style_epair,NULL); - } - } else if (strcmp(arg[1],"ebond") == 0) { - thresh_array[nthresh] = EBOND; - if (index_ebond < 0) { - index_ebond = add_compute(style_ebond,1); - create_compute(style_ebond,NULL); - } - } else if (strcmp(arg[1],"ke") == 0) { - thresh_array[nthresh] = KE; - if (index_ke < 0) { - index_ke = add_compute(style_ke,1); - create_compute(style_ke,NULL); - } - } else if (strcmp(arg[1],"etotal") == 0) { - thresh_array[nthresh] = ETOTAL; - if (index_etotal < 0) { - if (index_epair < 0) { - index_epair = add_compute(style_epair,1); - create_compute(style_epair,NULL); - } - index_etotal = add_compute(style_etotal,1); - create_compute(style_etotal,style_epair); - } - } else if (strcmp(arg[1],"centro") == 0) { - thresh_array[nthresh] = CENTRO; - if (index_centro < 0) { - index_centro = add_compute(style_centro,1); - create_compute(style_centro,NULL); - } - } else if (strcmp(arg[1],"sxx") == 0) { - thresh_array[nthresh] = SXX; - if (index_stress < 0) { - index_stress = add_compute(style_stress,1); - create_compute(style_stress,NULL); - } - } else if (strcmp(arg[1],"syy") == 0) { - thresh_array[nthresh] = SYY; - if (index_stress < 0) { - index_stress = add_compute(style_stress,1); - create_compute(style_stress,NULL); - } - } else if (strcmp(arg[1],"szz") == 0) { - thresh_array[nthresh] = SZZ; - if (index_stress < 0) { - index_stress = add_compute(style_stress,1); - create_compute(style_stress,NULL); - } - } else if (strcmp(arg[1],"sxy") == 0) { - thresh_array[nthresh] = SXY; - if (index_stress < 0) { - index_stress = add_compute(style_stress,1); - create_compute(style_stress,NULL); - } - } else if (strcmp(arg[1],"sxz") == 0) { - thresh_array[nthresh] = SXZ; - if (index_stress < 0) { - index_stress = add_compute(style_stress,1); - create_compute(style_stress,NULL); - } - } else if (strcmp(arg[1],"syz") == 0) { - thresh_array[nthresh] = SYZ; - if (index_stress < 0) { - index_stress = add_compute(style_stress,1); - create_compute(style_stress,NULL); - } // compute value = c_ID // if no trailing [], then arg is set to 0, else arg is between [] // must grow field2compute and arg_compute arrays, // since access is beyond nfield - // if Compute has pre-compute, first add it to list + // if Compute has pre-computes, first add them to list - } else if (strncmp(arg[1],"c_",2) == 0) { + else if (strncmp(arg[1],"c_",2) == 0) { thresh_array[nthresh] = COMPUTE; field2compute = (int *) memory->srealloc(field2compute, (nfield+nthresh+1)*sizeof(int), @@ -1059,9 +927,52 @@ int DumpCustom::modify_param(int narg, char **arg) if (arg_compute[nfield+nthresh] > 0 && arg_compute[nfield+nthresh] > modify->compute[n]->size_peratom) error->all("Dump custom compute ID vector is not large enough"); - if (modify->compute[n]->id_pre) - int tmp = add_compute(modify->compute[n]->id_pre,0); - field2compute[nfield+nthresh] = add_compute(suffix,0); + if (modify->compute[n]->npre) + for (int ic = 0; ic < modify->compute[n]->npre; ic++) + int tmp = add_compute(modify->compute[n]->id_pre[ic]); + field2compute[nfield+nthresh] = add_compute(suffix); + delete [] suffix; + + // fix value = f_ID + // if no trailing [], then arg is set to 0, else arg is between [] + // must grow field2compute and arg_compute arrays, + // since access is beyond nfield + + } else if (strncmp(arg[1],"f_",2) == 0) { + thresh_array[nthresh] = FIX; + field2fix = (int *) memory->srealloc(field2fix, + (nfield+nthresh+1)*sizeof(int), + "dump:field2fix"); + arg_fix = (int *) memory->srealloc(arg_fix, + (nfield+nthresh+1)*sizeof(int), + "dump:arg_fix"); + int n = strlen(arg[1]); + char *suffix = new char[n]; + strcpy(suffix,&arg[1][2]); + + char *ptr = strchr(suffix,'['); + if (ptr) { + if (suffix[strlen(suffix)-1] != ']') + error->all("Invalid keyword in dump custom command"); + arg_fix[nfield+nthresh] = atoi(ptr+1); + *ptr = '\0'; + } else arg_fix[nfield+nthresh] = 0; + + n = modify->find_fix(suffix); + if (n < 0) error->all("Could not find dump custom fix ID"); + + if (modify->fix[n]->peratom_flag == 0) + error->all("Dump custom fix ID does not compute peratom info"); + if (arg_fix[nfield+nthresh] == 0 && + modify->fix[n]->size_peratom > 0) + error->all("Dump custom fix ID does not compute scalar per atom"); + if (arg_fix[nfield+nthresh] > 0 && + modify->fix[n]->size_peratom == 0) + error->all("Dump custom fix ID does not compute vector per atom"); + if (arg_fix[nfield+nthresh] > 0 && + arg_fix[nfield+nthresh] > modify->fix[n]->size_peratom) + error->all("Dump custom fix ID vector is not large enough"); + field2fix[nfield+nthresh] = add_fix(suffix); delete [] suffix; } else error->all("Invalid dump_modify threshhold operator"); @@ -1083,6 +994,7 @@ int DumpCustom::modify_param(int narg, char **arg) nthresh++; return 4; } + return 0; } @@ -1106,31 +1018,6 @@ int DumpCustom::memory_usage() /* ---------------------------------------------------------------------- */ -void DumpCustom::pack_compute(int n) -{ - double *vector = compute[field2compute[n]]->scalar_atom; - double **array = compute[field2compute[n]]->vector_atom; - int index = arg_compute[n]; - int nlocal = atom->nlocal; - - if (index == 0) { - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = vector[i]; - n += size_one; - } - } else { - index--; - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = array[i][index]; - n += size_one; - } - } -} - -/* ---------------------------------------------------------------------- */ - void DumpCustom::pack_tag(int n) { int *tag = atom->tag; @@ -1594,154 +1481,50 @@ void DumpCustom::pack_tqz(int n) /* ---------------------------------------------------------------------- */ -void DumpCustom::pack_epair(int n) +void DumpCustom::pack_compute(int n) { - double *epair = compute[index_epair]->scalar_atom; + double *vector = compute[field2compute[n]]->scalar_atom; + double **array = compute[field2compute[n]]->vector_atom; + int index = arg_compute[n]; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = epair[i]; - n += size_one; - } + if (index == 0) { + for (int i = 0; i < nlocal; i++) + if (choose[i]) { + buf[n] = vector[i]; + n += size_one; + } + } else { + index--; + for (int i = 0; i < nlocal; i++) + if (choose[i]) { + buf[n] = array[i][index]; + n += size_one; + } + } } /* ---------------------------------------------------------------------- */ -void DumpCustom::pack_ebond(int n) +void DumpCustom::pack_fix(int n) { - double *ebond = compute[index_ebond]->scalar_atom; + double *vector = fix[field2fix[n]]->scalar_atom; + double **array = fix[field2fix[n]]->vector_atom; + int index = arg_fix[n]; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = ebond[i]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_ke(int n) -{ - double *ke = compute[index_ke]->scalar_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = ke[i]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_etotal(int n) -{ - double *etotal = compute[index_etotal]->scalar_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = etotal[i]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_centro(int n) -{ - double *centro = compute[index_centro]->scalar_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = centro[i]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_sxx(int n) -{ - double **stress = compute[index_stress]->vector_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = stress[i][0]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_syy(int n) -{ - double **stress = compute[index_stress]->vector_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = stress[i][1]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_szz(int n) -{ - double **stress = compute[index_stress]->vector_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = stress[i][2]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_sxy(int n) -{ - double **stress = compute[index_stress]->vector_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = stress[i][3]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_sxz(int n) -{ - double **stress = compute[index_stress]->vector_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = stress[i][4]; - n += size_one; - } -} - -/* ---------------------------------------------------------------------- */ - -void DumpCustom::pack_syz(int n) -{ - double **stress = compute[index_stress]->vector_atom; - int nlocal = atom->nlocal; - - for (int i = 0; i < nlocal; i++) - if (choose[i]) { - buf[n] = stress[i][5]; - n += size_one; - } + if (index == 0) { + for (int i = 0; i < nlocal; i++) + if (choose[i]) { + buf[n] = vector[i]; + n += size_one; + } + } else { + index--; + for (int i = 0; i < nlocal; i++) + if (choose[i]) { + buf[n] = array[i][index]; + n += size_one; + } + } } diff --git a/src/dump_custom.h b/src/dump_custom.h index 501a9fa03e..878f7c6a45 100644 --- a/src/dump_custom.h +++ b/src/dump_custom.h @@ -26,6 +26,7 @@ class DumpCustom : public Dump { int memory_usage(); private: + int nevery; // dump frequency to check Fix against int iregion; // -1 if no region, else which region int nthresh; // # of defined threshholds int *thresh_array; // array to threshhhold on for each nthresh @@ -41,18 +42,20 @@ class DumpCustom : public Dump { double *dchoose; // value for each atom to threshhold against int nfield; // # of keywords listed by user - int ncompute; // # of Compute objects called by dump + + int ncompute; // # of Compute objects used by dump char **id_compute; // their IDs class Compute **compute; // list of ptrs to the Compute objects - int *field2compute; // which Compute computes this field + int *field2compute; // which Compute calculates this field int *arg_compute; // index into Compute scalar_atom,vector_atom // 0 for scalar_atom, 1-N for vector_atom values - // index = where keyword's Compute is in list - // style = style of Compute object - int index_epair,index_ebond,index_ke,index_etotal,index_centro,index_stress; - char *style_epair,*style_ebond,*style_ke,*style_etotal; - char *style_centro,*style_stress; + int nfix; // # of Fix objects used by dump + char **id_fix; // their IDs + class Fix **fix; // list of ptrs to the Fix objects + int *field2fix; // which Fix calculates this field + int *arg_fix; // index into Fix scalar_atom,vector_atom + // 0 for scalar_atom, 1-N for vector_atom values // private methods @@ -62,8 +65,8 @@ class DumpCustom : public Dump { void write_data(int, double *); void parse_fields(int, char **); - int add_compute(char *, int); - void create_compute(char *, char *); + int add_compute(char *); + int add_fix(char *); int modify_param(int, char **); typedef void (DumpCustom::*FnPtrHeader)(int); @@ -81,8 +84,6 @@ class DumpCustom : public Dump { typedef void (DumpCustom::*FnPtrPack)(int); FnPtrPack *pack_choice; // ptrs to pack functions - void pack_compute(int); - void pack_tag(int); void pack_molecule(int); void pack_type(int); @@ -115,17 +116,9 @@ class DumpCustom : public Dump { void pack_tqx(int); void pack_tqy(int); void pack_tqz(int); - void pack_etotal(int); - void pack_ke(int); - void pack_epair(int); - void pack_ebond(int); - void pack_centro(int); - void pack_sxx(int); - void pack_syy(int); - void pack_szz(int); - void pack_sxy(int); - void pack_sxz(int); - void pack_syz(int); + + void pack_compute(int); + void pack_fix(int); }; } diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp index 92c5a3382c..701cb050b0 100644 --- a/src/dump_dcd.cpp +++ b/src/dump_dcd.cpp @@ -245,7 +245,7 @@ void DumpDCD::write_frame() /* ---------------------------------------------------------------------- */ -void DumpDCD::write_dcd_header(char *remarks) +void DumpDCD::write_dcd_header(const char *remarks) { uint32_t out_integer; float out_float; diff --git a/src/dump_dcd.h b/src/dump_dcd.h index f190eb1432..defd52fc46 100644 --- a/src/dump_dcd.h +++ b/src/dump_dcd.h @@ -38,7 +38,7 @@ class DumpDCD : public Dump { void write_data(int, double *); void write_frame(); - void write_dcd_header(char *); + void write_dcd_header(const char *); void fwrite_int32(FILE *, uint32_t); }; diff --git a/src/dump_xyz.cpp b/src/dump_xyz.cpp index 5a5ba59974..4c8b9ab9ac 100644 --- a/src/dump_xyz.cpp +++ b/src/dump_xyz.cpp @@ -29,7 +29,7 @@ DumpXYZ::DumpXYZ(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg) size_one = 5; - char *str = "%d %g %g %g"; + char *str = (char *) "%d %g %g %g"; int n = strlen(str) + 1; format_default = new char[n]; strcpy(format_default,str); diff --git a/src/error.cpp b/src/error.cpp index 8307760aef..b63b8a895e 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -29,7 +29,7 @@ Error::Error(LAMMPS *lmp) : Pointers(lmp) {} close all output, screen, and log files in world and universe ------------------------------------------------------------------------- */ -void Error::universe_all(char *str) +void Error::universe_all(const char *str) { MPI_Barrier(universe->uworld); @@ -53,7 +53,7 @@ void Error::universe_all(char *str) called by one proc in universe ------------------------------------------------------------------------- */ -void Error::universe_one(char *str) +void Error::universe_one(const char *str) { if (universe->uscreen) fprintf(universe->uscreen,"ERROR on proc %d: %s\n",universe->me,str); @@ -65,7 +65,7 @@ void Error::universe_one(char *str) close all output, screen, and log files in world ------------------------------------------------------------------------- */ -void Error::all(char *str) +void Error::all(const char *str) { MPI_Barrier(world); @@ -91,7 +91,7 @@ void Error::all(char *str) always write to universe screen ------------------------------------------------------------------------- */ -void Error::one(char *str) +void Error::one(const char *str) { int me; MPI_Comm_rank(world,&me); @@ -106,7 +106,7 @@ void Error::one(char *str) only write to screen if non-NULL on this proc since could be file ------------------------------------------------------------------------- */ -void Error::warning(char *str) +void Error::warning(const char *str) { if (screen) fprintf(screen,"WARNING: %s\n",str); } diff --git a/src/error.h b/src/error.h index 248ecdd604..b6c1d53f80 100644 --- a/src/error.h +++ b/src/error.h @@ -22,12 +22,12 @@ class Error : protected Pointers { public: Error(class LAMMPS *); - void universe_all(char *); - void universe_one(char *); + void universe_all(const char *); + void universe_one(const char *); - void all(char *); - void one(char *); - void warning(char *); + void all(const char *); + void one(const char *); + void warning(const char *); }; } diff --git a/src/finish.cpp b/src/finish.cpp index 8af0f57743..09441d4ff4 100644 --- a/src/finish.cpp +++ b/src/finish.cpp @@ -23,6 +23,8 @@ #include "update.h" #include "min.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "output.h" #include "memory.h" @@ -36,7 +38,7 @@ Finish::Finish(LAMMPS *lmp) : Pointers(lmp) {} void Finish::end(int flag) { - int i; + int i,m; int histo[10]; double time,tmp,ave,max,min; @@ -291,11 +293,17 @@ void Finish::end(int flag) } } + // find a half non-skip neighbor list + + for (m = 0; m < neighbor->old_nrequest; m++) + if ((neighbor->old_requests[m]->half || + neighbor->old_requests[m]->half_from_full) && + neighbor->old_requests[m]->skip == 0) break; + int nneigh = 0; - if (neighbor->half_every) - for (i = 0; i < atom->nlocal; i++) nneigh += neighbor->numneigh[i]; - else if (neighbor->full_every) - for (i = 0; i < atom->nlocal; i++) nneigh += neighbor->numneigh_full[i]; + if (m < neighbor->old_nrequest) + for (i = 0; i < atom->nlocal; i++) + nneigh += neighbor->lists[m]->numneigh[i]; tmp = nneigh; stats(1,&tmp,&ave,&max,&min,10,histo); @@ -314,10 +322,17 @@ void Finish::end(int flag) } } - if (neighbor->half_every && neighbor->full_every) { + // find a full non-skip neighbor list + + for (m = 0; m < neighbor->old_nrequest; m++) + if (neighbor->old_requests[m]->full && + neighbor->old_requests[m]->skip == 0) break; + + if (m < neighbor->old_nrequest) { nneigh = 0; - for (i = 0; i < atom->nlocal; i++) nneigh += neighbor->numneigh_full[i]; + for (i = 0; i < atom->nlocal; i++) + nneigh += neighbor->lists[m]->numneigh[i]; tmp = nneigh; stats(1,&tmp,&ave,&max,&min,10,histo); diff --git a/src/fix.cpp b/src/fix.cpp index 1a50c86643..ae48cf4764 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -42,10 +42,9 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) rigid_flag = 0; virial_flag = 0; no_change_box = 0; + peratom_flag = 0; comm_forward = comm_reverse = 0; - neigh_half_once = neigh_half_every = 0; - neigh_full_once = neigh_full_every = 0; // mask settings - same as in modify.cpp diff --git a/src/fix.h b/src/fix.h index 9d1fc93cfd..e43ce3c72c 100644 --- a/src/fix.h +++ b/src/fix.h @@ -35,12 +35,14 @@ class Fix : protected Pointers { int virial_flag; // 1 if Fix contributes to virial, 0 if not int no_change_box; // 1 if cannot swap ortho <-> triclinic + int peratom_flag; // 0/1 if per-atom data is stored + int size_peratom; // 0 = scalar_atom, N = size of vector_atom + double *scalar_atom; // computed per-atom scalar + double **vector_atom; // computed per-atom vector + int peratom_freq; // frequency per-atom data is available at + int comm_forward; // size of forward communication (0 if none) int comm_reverse; // size of reverse communication (0 if none) - int neigh_half_once; // 0/1 if needs half neigh list occasionally - int neigh_half_every; // 0/1 if needs half neigh list every step - int neigh_full_once; // 0/1 if needs full neigh list occasionally - int neigh_full_every; // 0/1 if needs full neigh list every step double virial[6]; // fix contribution to pressure virial @@ -56,6 +58,7 @@ class Fix : protected Pointers { virtual int setmask() = 0; virtual void init() {} + virtual void init_list(int, class NeighList *) {} virtual void setup() {} virtual void min_setup() {} virtual void initial_integrate() {} diff --git a/src/fix_ave_spatial.cpp b/src/fix_ave_spatial.cpp index a7ef8d40e5..f9697c053b 100644 --- a/src/fix_ave_spatial.cpp +++ b/src/fix_ave_spatial.cpp @@ -31,7 +31,7 @@ using namespace LAMMPS_NS; enum{LOWER,CENTER,UPPER,COORD}; -enum{DENSITY_MASS,DENSITY_NUM,VX,VY,VZ,FX,FY,FZ,COMPUTE}; +enum{DENSITY_MASS,DENSITY_NUM,COMPUTE,FIX}; enum{SAMPLE,ALL}; enum{BOX,LATTICE,REDUCED}; @@ -40,56 +40,51 @@ enum{BOX,LATTICE,REDUCED}; FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg < 11) error->all("Illegal fix ave/spatial command"); + if (narg < 12) error->all("Illegal fix ave/spatial command"); no_change_box = 1; nevery = atoi(arg[3]); - nfreq = atoi(arg[4]); + nrepeat = atoi(arg[4]); + nfreq = atoi(arg[5]); - if (strcmp(arg[5],"x") == 0) dim = 0; - else if (strcmp(arg[5],"y") == 0) dim = 1; - else if (strcmp(arg[5],"z") == 0) dim = 2; + if (strcmp(arg[6],"x") == 0) dim = 0; + else if (strcmp(arg[6],"y") == 0) dim = 1; + else if (strcmp(arg[6],"z") == 0) dim = 2; else error->all("Illegal fix ave/spatial command"); - if (strcmp(arg[6],"lower") == 0) originflag = LOWER; - if (strcmp(arg[6],"center") == 0) originflag = CENTER; - if (strcmp(arg[6],"upper") == 0) originflag = UPPER; + if (strcmp(arg[7],"lower") == 0) originflag = LOWER; + if (strcmp(arg[7],"center") == 0) originflag = CENTER; + if (strcmp(arg[7],"upper") == 0) originflag = UPPER; else originflag = COORD; if (originflag == COORD) origin = atof(arg[6]); - delta = atof(arg[7]); + delta = atof(arg[8]); MPI_Comm_rank(world,&me); if (me == 0) { - fp = fopen(arg[8],"w"); + fp = fopen(arg[9],"w"); if (fp == NULL) { char str[128]; - sprintf(str,"Cannot open fix ave/spatial file %s",arg[8]); + sprintf(str,"Cannot open fix ave/spatial file %s",arg[9]); error->one(str); } } - if (strcmp(arg[9],"density") == 0) { - if (strcmp(arg[10],"mass") == 0) which = DENSITY_MASS; - else if (strcmp(arg[10],"number") == 0) which = DENSITY_NUM; + if (strcmp(arg[10],"density") == 0) { + if (strcmp(arg[11],"mass") == 0) which = DENSITY_MASS; + else if (strcmp(arg[11],"number") == 0) which = DENSITY_NUM; else error->all("Illegal fix ave/spatial command"); - - } else if (strcmp(arg[9],"atom") == 0) { - if (strcmp(arg[10],"vx") == 0) which = VX; - else if (strcmp(arg[10],"vy") == 0) which = VY; - else if (strcmp(arg[10],"vz") == 0) which = VZ; - else if (strcmp(arg[10],"fx") == 0) which = FX; - else if (strcmp(arg[10],"fy") == 0) which = FY; - else if (strcmp(arg[10],"fz") == 0) which = FZ; - else error->all("Illegal fix ave/spatial command"); - - } else if (strcmp(arg[9],"compute") == 0) { + } else if (strcmp(arg[10],"compute") == 0) { which = COMPUTE; - int n = strlen(arg[10]) + 1; + int n = strlen(arg[11]) + 1; id_compute = new char[n]; - strcpy(id_compute,arg[10]); - + strcpy(id_compute,arg[11]); + } else if (strcmp(arg[10],"fix") == 0) { + which = FIX; + int n = strlen(arg[11]) + 1; + id_fix = new char[n]; + strcpy(id_fix,arg[11]); } else error->all("Illegal fix ave/spatial command"); // parse optional args @@ -97,7 +92,7 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : normflag = ALL; scaleflag = BOX; - int iarg = 11; + int iarg = 12; while (iarg < narg) { if (strcmp(arg[iarg],"norm") == 0) { if (iarg+2 > narg) error->all("Illegal fix ave/spatial command"); @@ -149,34 +144,61 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : // setup and error check if (nevery <= 0) error->all("Illegal fix ave/spatial command"); - if (nfreq < nevery || nfreq % nevery) + if (nfreq < nevery || nfreq % nevery || (nrepeat-1)*nevery >= nfreq) error->all("Illegal fix ave/spatial command"); if (delta <= 0.0) error->all("Illegal fix ave/spatial command"); invdelta = 1.0/delta; + // nvalues = # of quantites per line of output file + // for COMPUTE, setup list of computes to call, including pre-computes + nvalues = 1; + compute = NULL; + if (which == COMPUTE) { int icompute = modify->find_compute(id_compute); if (icompute < 0) error->all("Compute ID for fix ave/spatial does not exist"); if (modify->compute[icompute]->peratom_flag == 0) error->all("Fix ave/spatial compute does not calculate per-atom info"); - nvalues = compute_size_peratom = modify->compute[icompute]->size_peratom; + nvalues = size_peratom = modify->compute[icompute]->size_peratom; + if (nvalues == 0) nvalues = 1; + ncompute = 1 + modify->compute[icompute]->npre; + compute = new Compute*[ncompute]; + } + + if (which == FIX) { + int ifix = modify->find_fix(id_fix); + if (ifix < 0) + error->all("Fix ID for fix ave/spatial does not exist"); + if (modify->fix[ifix]->peratom_flag == 0) + error->all("Fix ave/spatial fix does not calculate per-atom info"); + nvalues = size_peratom = modify->fix[ifix]->size_peratom; if (nvalues == 0) nvalues = 1; } + // print header into file + if (me == 0) { fprintf(fp,"Spatial-averaged data for fix %s, group %s, and %s %s\n", - id,group->names[igroup],arg[9],arg[10]); + id,group->names[igroup],arg[10],arg[11]); fprintf(fp,"TimeStep Number-of-layers (one per snapshot)\n"); fprintf(fp,"Layer Coord Atoms Value(s) (one per layer)\n"); } - nsum = nlayers = maxlayer = 0; + nlayers = maxlayer = 0; coord = NULL; count_one = count_many = count_total = NULL; values_one = values_many = values_total = NULL; + + // nvalid = next step on which end_of_step does something + + irepeat = 0; + nvalid = (update->ntimestep/nfreq)*nfreq + nfreq; + nvalid -= (nrepeat-1)*nevery; + if (nvalid <= update->ntimestep) + error->all("Fix ave/spatial cannot be started on this timestep"); } /* ---------------------------------------------------------------------- */ @@ -184,8 +206,11 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) : FixAveSpatial::~FixAveSpatial() { if (which == COMPUTE) delete [] id_compute; + if (which == FIX) delete [] id_fix; if (me == 0) fclose(fp); + delete [] compute; + memory->sfree(coord); memory->sfree(count_one); memory->sfree(count_many); @@ -208,21 +233,37 @@ int FixAveSpatial::setmask() void FixAveSpatial::init() { - // set ptrs to current compute and precompute + // set ptrs to one or more computes called each end-of-step if (which == COMPUTE) { int icompute = modify->find_compute(id_compute); - if (icompute < 0) + if (icompute < 0) error->all("Compute ID for fix ave/spatial does not exist"); - compute = modify->compute[icompute]; - if (compute->id_pre) { - icompute = modify->find_compute(compute->id_pre); - if (icompute < 0) - error->all("Precompute ID for fix ave/spatial does not exist"); - precompute = modify->compute[icompute]; - } else precompute = NULL; + ncompute = 0; + if (modify->compute[icompute]->npre) + for (int i = 0; i < modify->compute[icompute]->npre; i++) { + int ic = modify->find_compute(modify->compute[icompute]->id_pre[i]); + if (ic < 0) + error->all("Precompute ID for fix ave/spatial does not exist"); + compute[ncompute++] = modify->compute[ic]; + } + + compute[ncompute++] = modify->compute[icompute]; } + + // set ptr to fix ID + // check that fix frequency is acceptable + + if (which == FIX) { + int ifix = modify->find_fix(id_fix); + if (ifix < 0) + error->all("Fix ID for fix ave/spatial does not exist"); + fix = modify->fix[ifix]; + if (nevery % modify->fix[ifix]->peratom_freq) + error->all("Fix ave/spatial and fix not computed at compatible times"); + } + } /* ---------------------------------------------------------------------- */ @@ -232,13 +273,17 @@ void FixAveSpatial::end_of_step() int i,j,m,ilayer; double lo,hi; + // skip if not step which requires doing something + + if (update->ntimestep != nvalid) return; + // if computing the first sample, setup layers // compute current origin = boundary for some layer // lo = layer boundary immediately below boxlo // hi = layer boundary immediately above boxhi // allocate and initialize arrays based on new layer count - if (nsum == 0) { + if (irepeat == 0) { double *boxlo,*boxhi,*prd; if (scaleflag == REDUCED) { boxlo = domain->boxlo_lamda; @@ -306,7 +351,6 @@ void FixAveSpatial::end_of_step() // zero out arrays for one sample - nsum++; for (m = 0; m < nlayers; m++) { count_one[m] = 0.0; for (i = 0; i < nvalues; i++) values_one[m][i] = 0.0; @@ -361,17 +405,12 @@ void FixAveSpatial::end_of_step() if (scaleflag == REDUCED) domain->lamda2x(nlocal); - // ATOM (VX,FX,etc) adds atom attribute to values + // COMPUTE adds its scalar or vector quantity to values - } else if (which != COMPUTE) { - double *vector; - int nstride = 3; - if (which == VX) vector = &atom->v[0][0]; - else if (which == VY) vector = &atom->v[0][1]; - else if (which == VZ) vector = &atom->v[0][2]; - else if (which == FX) vector = &atom->f[0][0]; - else if (which == FY) vector = &atom->f[0][1]; - else if (which == FZ) vector = &atom->f[0][2]; + } else if (which == COMPUTE) { + for (i = 0; i < ncompute; i++) compute[i]->compute_peratom(); + double *scalar = compute[ncompute-1]->scalar_atom; + double **vector = compute[ncompute-1]->vector_atom; if (scaleflag == REDUCED) domain->x2lamda(nlocal); @@ -382,20 +421,20 @@ void FixAveSpatial::end_of_step() if (ilayer < 0) ilayer = 0; if (ilayer >= nlayers) ilayer = nlayers-1; count_one[ilayer] += 1.0; - values_one[ilayer][0] += vector[m]; + if (size_peratom == 0) values_one[ilayer][0] += scalar[i]; + else + for (j = 0; j < nvalues; j++) + values_one[ilayer][j] += vector[i][j]; } - m += nstride; } if (scaleflag == REDUCED) domain->lamda2x(nlocal); - // COMPUTE adds its compute scalar or vector quantity to values + // FIX adds its scalar or vector quantity to values - } else { - if (precompute) precompute->compute_peratom(); - compute->compute_peratom(); - double *scalar = compute->scalar_atom; - double **vector = compute->vector_atom; + } else if (which == FIX) { + double *scalar = fix->scalar_atom; + double **vector = fix->vector_atom; if (scaleflag == REDUCED) domain->x2lamda(nlocal); @@ -406,7 +445,7 @@ void FixAveSpatial::end_of_step() if (ilayer < 0) ilayer = 0; if (ilayer >= nlayers) ilayer = nlayers-1; count_one[ilayer] += 1.0; - if (compute_size_peratom == 0) values_one[ilayer][0] += scalar[i]; + if (size_peratom == 0) values_one[ilayer][0] += scalar[i]; else for (j = 0; j < nvalues; j++) values_one[ilayer][j] += vector[i][j]; @@ -434,11 +473,19 @@ void FixAveSpatial::end_of_step() } } + // update counters + + irepeat++; + nvalid += nevery; + // output the results // time average across samples // if density, also normalize by volume + // reset irepeat and nvalid + + if (irepeat == nrepeat) { + double repeat = nrepeat; - if (update->ntimestep % nfreq == 0) { if (normflag == ALL) { MPI_Allreduce(count_many,count_total,nlayers,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&values_many[0][0],&values_total[0][0],nlayers*nvalues, @@ -447,15 +494,15 @@ void FixAveSpatial::end_of_step() if (count_total[m] > 0.0) for (j = 0; j < nvalues; j++) values_total[m][j] /= count_total[m]; - count_total[m] /= nsum; + count_total[m] /= repeat; } } else { MPI_Allreduce(&values_many[0][0],&values_total[0][0],nlayers*nvalues, MPI_DOUBLE,MPI_SUM,world); for (m = 0; m < nlayers; m++) { for (j = 0; j < nvalues; j++) - values_total[m][j] /= nsum; - count_total[m] /= nsum; + values_total[m][j] /= repeat; + count_total[m] /= repeat; } } @@ -474,6 +521,7 @@ void FixAveSpatial::end_of_step() fflush(fp); } - nsum = 0; + irepeat = 0; + nvalid = update->ntimestep+nfreq - (nrepeat-1)*nevery; } } diff --git a/src/fix_ave_spatial.h b/src/fix_ave_spatial.h index 2e23ac7821..9c9cff604c 100644 --- a/src/fix_ave_spatial.h +++ b/src/fix_ave_spatial.h @@ -29,22 +29,22 @@ class FixAveSpatial : public Fix { private: int me; - int nfreq; + int nrepeat,nfreq,irepeat,nvalid; int dim,originflag,which,normflag; double origin,delta; - char *id_compute; + char *id_compute,*id_fix; FILE *fp; - int nlayers,nvalues,nsum,maxlayer,scaleflag; - int compute_size_peratom; + int nlayers,nvalues,maxlayer,scaleflag,size_peratom; double xscale,yscale,zscale; double layer_volume; double *coord; double *count_one,*count_many,*count_total; double **values_one,**values_many,**values_total; double offset,invdelta; - class Compute *compute; - class Compute *precompute; + int ncompute; + class Compute **compute; + class Fix *fix; }; } diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp index c0f1f15690..ac8f7b1adf 100644 --- a/src/fix_ave_time.cpp +++ b/src/fix_ave_time.cpp @@ -31,23 +31,24 @@ using namespace LAMMPS_NS; FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 8) error->all("Illegal fix ave/time command"); + if (narg != 9) error->all("Illegal fix ave/time command"); nevery = atoi(arg[3]); - nfreq = atoi(arg[4]); + nrepeat = atoi(arg[4]); + nfreq = atoi(arg[5]); - int n = strlen(arg[5]) + 1; + int n = strlen(arg[6]) + 1; id_compute = new char[n]; - strcpy(id_compute,arg[5]); + strcpy(id_compute,arg[6]); - int flag = atoi(arg[6]); + int flag = atoi(arg[7]); MPI_Comm_rank(world,&me); if (me == 0) { - fp = fopen(arg[7],"w"); + fp = fopen(arg[8],"w"); if (fp == NULL) { char str[128]; - sprintf(str,"Cannot open fix ave/time file %s",arg[7]); + sprintf(str,"Cannot open fix ave/time file %s",arg[8]); error->one(str); } } @@ -55,7 +56,7 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : // setup and error check if (nevery <= 0) error->all("Illegal fix ave/time command"); - if (nfreq < nevery || nfreq % nevery) + if (nfreq < nevery || nfreq % nevery || (nrepeat-1)*nevery >= nfreq) error->all("Illegal fix ave/time command"); int icompute = modify->find_compute(id_compute); @@ -73,6 +74,13 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : if (modify->compute[icompute]->pressflag) pressure_every = nevery; + // setup list of computes to call, including pre-computes + + ncompute = 1 + modify->compute[icompute]->npre; + compute = new Compute*[ncompute]; + + // print header into file + if (me == 0) { fprintf(fp,"Time-averaged data for fix %s, group %s, and compute %s\n", id,group->names[modify->compute[icompute]->igroup],id_compute); @@ -84,14 +92,19 @@ FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) : fprintf(fp,"TimeStep Scalar-value Vector-values\n"); } - nsum = 0; - scalar = 0.0; vector = NULL; if (vflag) { size_vector = modify->compute[icompute]->size_vector; vector = new double[size_vector]; - for (int i = 0; i < size_vector; i++) vector[i] = 0.0; } + + // nvalid = next step on which end_of_step does something + + irepeat = 0; + nvalid = (update->ntimestep/nfreq)*nfreq + nfreq; + nvalid -= (nrepeat-1)*nevery; + if (nvalid <= update->ntimestep) + error->all("Fix ave/time cannot be started on this timestep"); } /* ---------------------------------------------------------------------- */ @@ -100,6 +113,7 @@ FixAveTime::~FixAveTime() { delete [] id_compute; if (me == 0) fclose(fp); + delete [] compute; delete [] vector; } @@ -116,18 +130,22 @@ int FixAveTime::setmask() void FixAveTime::init() { - // set ptrs to current compute and precompute + // set ptrs to one or more computes called each end-of-step int icompute = modify->find_compute(id_compute); - if (icompute < 0) error->all("Compute ID for fix ave/time does not exist"); - compute = modify->compute[icompute]; - - if (compute->id_pre) { - icompute = modify->find_compute(compute->id_pre); - if (icompute < 0) - error->all("Precompute ID for fix ave/time does not exist"); - precompute = modify->compute[icompute]; - } else precompute = NULL; + if (icompute < 0) + error->all("Compute ID for fix ave/time does not exist"); + + ncompute = 0; + if (modify->compute[icompute]->npre) + for (int i = 0; i < modify->compute[icompute]->npre; i++) { + int ic = modify->find_compute(modify->compute[icompute]->id_pre[i]); + if (ic < 0) + error->all("Precompute ID for fix ave/time does not exist"); + compute[ncompute++] = modify->compute[ic]; + } + + compute[ncompute++] = modify->compute[icompute]; } /* ---------------------------------------------------------------------- */ @@ -136,32 +154,50 @@ void FixAveTime::end_of_step() { int i; - if (precompute) { - if (sflag) double tmp = precompute->compute_scalar(); - if (vflag) precompute->compute_vector(); + // skip if not step which requires doing something + + if (update->ntimestep != nvalid) return; + + // zero if first step + + if (irepeat == 0) { + scalar = 0.0; + if (vflag) + for (i = 0; i < size_vector; i++) vector[i] = 0.0; } - nsum++; - if (sflag) scalar += compute->compute_scalar(); + // accumulate results of compute to local copy + + if (sflag) { + double value; + for (i = 0; i < ncompute; i++) value = compute[i]->compute_scalar(); + scalar += value; + } if (vflag) { - compute->compute_vector(); - double *cvector = compute->vector; + for (i = 0; i < ncompute; i++) compute[i]->compute_vector(); + double *cvector = compute[ncompute-1]->vector; for (i = 0; i < size_vector; i++) vector[i] += cvector[i]; } - if (update->ntimestep % nfreq == 0) { + irepeat++; + nvalid += nevery; + + // output the results + // reset irepeat and nvalid + + if (irepeat == nrepeat) { + double repeat = nrepeat; + if (me == 0) { fprintf(fp,"%d",update->ntimestep); - if (sflag) fprintf(fp," %g",scalar/nsum); + if (sflag) fprintf(fp," %g",scalar/repeat); if (vflag) - for (i = 0; i < size_vector; i++) fprintf(fp," %g",vector[i]/nsum); + for (i = 0; i < size_vector; i++) fprintf(fp," %g",vector[i]/repeat); fprintf(fp,"\n"); fflush(fp); } - nsum = 0; - scalar = 0.0; - if (vflag) - for (i = 0; i < size_vector; i++) vector[i] = 0.0; - } + irepeat = 0; + nvalid = update->ntimestep+nfreq - (nrepeat-1)*nevery; + } } diff --git a/src/fix_ave_time.h b/src/fix_ave_time.h index 8c732064d9..01fb897c48 100644 --- a/src/fix_ave_time.h +++ b/src/fix_ave_time.h @@ -29,16 +29,15 @@ class FixAveTime : public Fix { private: int me; - - int nfreq; + int nrepeat,nfreq,nvalid,irepeat; char *id_compute; FILE *fp; int sflag,vflag; int size_vector,nsum; double scalar,*vector; - class Compute *compute; - class Compute *precompute; + int ncompute; + class Compute **compute; }; } diff --git a/src/fix_nph.cpp b/src/fix_nph.cpp index f9fc6e7087..d8b2076d88 100644 --- a/src/fix_nph.cpp +++ b/src/fix_nph.cpp @@ -162,8 +162,8 @@ FixNPH::FixNPH(LAMMPS *lmp, int narg, char **arg) : char **newarg = new char*[3]; newarg[0] = id_temp; - newarg[1] = "all"; - newarg[2] = "temp"; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "temp"; modify->add_compute(3,newarg); delete [] newarg; tflag = 1; @@ -179,8 +179,8 @@ FixNPH::FixNPH(LAMMPS *lmp, int narg, char **arg) : newarg = new char*[4]; newarg[0] = id_press; - newarg[1] = "all"; - newarg[2] = "pressure"; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "pressure"; newarg[3] = id_temp; modify->add_compute(4,newarg); delete [] newarg; @@ -231,7 +231,7 @@ void FixNPH::init() error->all("Cannot use fix nph without per-type mass defined"); // set temperature and pressure ptrs - // set ptemperature only if pressure's id_pre is not id_temp + // set ptemperature only if pressure's id_pre[0] is not id_temp int icompute = modify->find_compute(id_temp); if (icompute < 0) error->all("Temp ID for fix nph does not exist"); @@ -241,9 +241,9 @@ void FixNPH::init() if (icompute < 0) error->all("Press ID for fix nph does not exist"); pressure = modify->compute[icompute]; - if (strcmp(id_temp,pressure->id_pre) == 0) ptemperature = NULL; + if (strcmp(id_temp,pressure->id_pre[0]) == 0) ptemperature = NULL; else { - icompute = modify->find_compute(pressure->id_pre); + icompute = modify->find_compute(pressure->id_pre[0]); if (icompute < 0) error->all("Temp ID of press ID for fix nph does not exist"); ptemperature = modify->compute[icompute]; @@ -733,13 +733,13 @@ int FixNPH::modify_param(int narg, char **arg) if (temperature->igroup != 0 && comm->me == 0) error->warning("Temperature for NPH is not for group all"); - // reset id_pre of pressure to new temp ID + // reset id_pre[0] of pressure to new temp ID icompute = modify->find_compute(id_press); if (icompute < 0) error->all("Press ID for fix npt does not exist"); - delete [] modify->compute[icompute]->id_pre; - modify->compute[icompute]->id_pre = new char[n]; - strcpy(modify->compute[icompute]->id_pre,id_temp); + delete [] modify->compute[icompute]->id_pre[0]; + modify->compute[icompute]->id_pre[0] = new char[n]; + strcpy(modify->compute[icompute]->id_pre[0],id_temp); return 2; diff --git a/src/fix_npt.cpp b/src/fix_npt.cpp index 6b2c6f2b99..f57df6fc25 100644 --- a/src/fix_npt.cpp +++ b/src/fix_npt.cpp @@ -169,9 +169,10 @@ FixNPT::FixNPT(LAMMPS *lmp, int narg, char **arg) : char **newarg = new char*[3]; newarg[0] = id_temp; - newarg[1] = "all"; - if (strcmp(style,"npt") == 0) newarg[2] = "temp"; - else if (strcmp(style,"npt/asphere") == 0) newarg[2] = "temp/asphere"; + newarg[1] = (char *) "all"; + if (strcmp(style,"npt") == 0) newarg[2] = (char *) "temp"; + else if (strcmp(style,"npt/asphere") == 0) + newarg[2] = (char *) "temp/asphere"; modify->add_compute(3,newarg); delete [] newarg; tflag = 1; @@ -187,8 +188,8 @@ FixNPT::FixNPT(LAMMPS *lmp, int narg, char **arg) : newarg = new char*[4]; newarg[0] = id_press; - newarg[1] = "all"; - newarg[2] = "pressure"; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "pressure"; newarg[3] = id_temp; modify->add_compute(4,newarg); delete [] newarg; @@ -240,7 +241,7 @@ void FixNPT::init() error->all("Cannot use fix npt without per-type mass defined"); // set temperature and pressure ptrs - // set ptemperature only if pressure's id_pre is not id_temp + // set ptemperature only if pressure's id_pre[0] is not id_temp int icompute = modify->find_compute(id_temp); if (icompute < 0) error->all("Temp ID for fix npt does not exist"); @@ -250,9 +251,9 @@ void FixNPT::init() if (icompute < 0) error->all("Press ID for fix npt does not exist"); pressure = modify->compute[icompute]; - if (strcmp(id_temp,pressure->id_pre) == 0) ptemperature = NULL; + if (strcmp(id_temp,pressure->id_pre[0]) == 0) ptemperature = NULL; else { - icompute = modify->find_compute(pressure->id_pre); + icompute = modify->find_compute(pressure->id_pre[0]); if (icompute < 0) error->all("Temp ID of press ID for fix npt does not exist"); ptemperature = modify->compute[icompute]; @@ -761,13 +762,13 @@ int FixNPT::modify_param(int narg, char **arg) if (temperature->igroup != 0 && comm->me == 0) error->warning("Temperature for NPT is not for group all"); - // reset id_pre of pressure to new temp ID + // reset id_pre[0] of pressure to new temp ID icompute = modify->find_compute(id_press); if (icompute < 0) error->all("Press ID for fix npt does not exist"); - delete [] modify->compute[icompute]->id_pre; - modify->compute[icompute]->id_pre = new char[n]; - strcpy(modify->compute[icompute]->id_pre,id_temp); + delete [] modify->compute[icompute]->id_pre[0]; + modify->compute[icompute]->id_pre[0] = new char[n]; + strcpy(modify->compute[icompute]->id_pre[0],id_temp); return 2; diff --git a/src/fix_nvt.cpp b/src/fix_nvt.cpp index 1d0cb9a8ea..7a56cbd23b 100644 --- a/src/fix_nvt.cpp +++ b/src/fix_nvt.cpp @@ -69,9 +69,9 @@ FixNVT::FixNVT(LAMMPS *lmp, int narg, char **arg) : char **newarg = new char*[3]; newarg[0] = id_temp; newarg[1] = group->names[igroup]; - if (strcmp(style,"nvt") == 0) newarg[2] = "temp"; - else if (strcmp(style,"nvt/asphere") == 0) newarg[2] = "temp/asphere"; - else if (strcmp(style,"nvt/sllod") == 0) newarg[2] = "temp/deform"; + if (strcmp(style,"nvt") == 0) newarg[2] = (char *) "temp"; + else if (strcmp(style,"nvt/asphere") == 0) newarg[2] = (char *) "temp/asphere"; + else if (strcmp(style,"nvt/sllod") == 0) newarg[2] = (char *) "temp/deform"; modify->add_compute(3,newarg); delete [] newarg; tflag = 1; diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp index 73b9f3b895..c4b9246179 100644 --- a/src/fix_orient_fcc.cpp +++ b/src/fix_orient_fcc.cpp @@ -24,6 +24,8 @@ #include "update.h" #include "respa.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "comm.h" #include "output.h" #include "error.h" @@ -44,8 +46,6 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : if (narg != 11) error->all("Illegal fix orient/fcc command"); - neigh_full_every = 1; - nstats = atoi(arg[3]); direction_of_motion = atoi(arg[4]); a = atof(arg[5]); @@ -173,6 +173,21 @@ void FixOrientFCC::init() { if (strcmp(update->integrate_style,"respa") == 0) nlevels_respa = ((Respa *) update->integrate)->nlevels; + + // need a full neighbor list, built when ever re-neighboring occurs + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; +} + +/* ---------------------------------------------------------------------- */ + +void FixOrientFCC::init_list(int id, NeighList *ptr) +{ + list = ptr; } /* ---------------------------------------------------------------------- */ @@ -194,8 +209,8 @@ void FixOrientFCC::setup() void FixOrientFCC::post_force(int vflag) { - int i,j,k,m,n,nn,nsort,id_self; - int *neighs; + int i,j,k,ii,jj,inum,jnum,m,n,nn,nsort,id_self; + int *ilist,*jlist,*numneigh,**firstneigh; double edelta,added_energy,omega; double dx,dy,dz,rsq,xismooth,xi_sq,duxi,duxi_other; double dxi[3]; @@ -215,6 +230,11 @@ void FixOrientFCC::post_force(int vflag) int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // insure nbr data structure is adequate size if (nall > nmax) { @@ -231,15 +251,16 @@ void FixOrientFCC::post_force(int vflag) int mincount = BIG; int maxcount = 0; - for (i = 0; i < nlocal; i++) { - neighs = neighbor->firstneigh_full[i]; - n = neighbor->numneigh_full[i]; + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - if (n < mincount) mincount = n; - if (n > maxcount) { + if (jnum < mincount) mincount = jnum; + if (jnum > maxcount) { if (maxcount) delete [] sort; - sort = new Sort[n]; - maxcount = n; + sort = new Sort[jnum]; + maxcount = jnum; } // loop over all neighbors of atom i @@ -247,8 +268,8 @@ void FixOrientFCC::post_force(int vflag) // store local id, rsq, delta vector, xismooth (if included) nsort = 0; - for (k = 0; k < n; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; count++; dx = x[i][0] - x[j][0]; @@ -319,7 +340,8 @@ void FixOrientFCC::post_force(int vflag) // compute grain boundary force on each owned atom // skip atoms not in group - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; if (!(mask[i] & groupbit)) continue; n = nbr[i].n; duxi = nbr[i].duxi; diff --git a/src/fix_orient_fcc.h b/src/fix_orient_fcc.h index 9b34e41535..a28f618187 100644 --- a/src/fix_orient_fcc.h +++ b/src/fix_orient_fcc.h @@ -41,6 +41,7 @@ class FixOrientFCC : public Fix { ~FixOrientFCC(); int setmask(); void init(); + void init_list(int, class NeighList *); void setup(); void post_force(int); void post_force_respa(int, int, int); @@ -70,6 +71,7 @@ class FixOrientFCC : public Fix { Nbr *nbr; Sort *sort; + class NeighList *list; void find_best_ref(double *, int, double &, double *); static int compare(const void *, const void *); diff --git a/src/fix_rdf.cpp b/src/fix_rdf.cpp index f671687bae..f39081ce47 100644 --- a/src/fix_rdf.cpp +++ b/src/fix_rdf.cpp @@ -27,6 +27,8 @@ #include "group.h" #include "modify.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "pair.h" #include "force.h" #include "memory.h" @@ -41,8 +43,6 @@ FixRDF::FixRDF(LAMMPS *lmp, int narg, char **arg) : { if (narg < 8 || (narg-6) % 2) error->all("Illegal fix rdf command"); - neigh_half_once = 1; - nevery = atoi(arg[3]); if (nevery <= 0) error->all("Illegal fix rdf command"); first = 1; @@ -129,6 +129,13 @@ void FixRDF::init() if (force->pair) delr = force->pair->cutforce / maxbin; else error->all("Fix rdf requires a pair style be defined"); + // need an occasional half neighbor list + + int irequest = neighbor->request((void *) this); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->occasional = 1; + delrinv = 1.0/delr; nframes = 0; @@ -143,6 +150,14 @@ void FixRDF::init() for (bin = 0; bin < maxbin; bin++) gr_ave[irdf][bin] = ncoord_ave[irdf][bin] = 0.0; } + +} + +/* ---------------------------------------------------------------------- */ + +void FixRDF::init_list(int id, NeighList *ptr) +{ + list = ptr; } /* ---------------------------------------------------------------------- */ @@ -166,13 +181,18 @@ void FixRDF::end_of_step() int nall = atom->nlocal + atom->nghost; int newton_pair = force->newton_pair; - int i,j,k,numneigh,itype,jtype,ipair,jpair,bin; + int i,j,ii,jj,inum,jnum,itype,jtype,ipair,jpair,bin; double xtmp,ytmp,ztmp,delx,dely,delz,r; - int *neighs; + int *ilist,*jlist,*numneigh,**firstneigh; - // if needed, build a half neighbor list + // invoke half neighbor list (will copy or build if necessary) - if (!neighbor->half_every) neighbor->build_half(); + neighbor->build_one(list->index); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; // zero the histogram counts @@ -188,17 +208,19 @@ void FixRDF::end_of_step() // count the interaction once even if neighbor pair is stored on 2 procs // if itype = jtype, count the interaction twice - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; if (mask[i] & groupbit) { xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; if (j >= nall) { if (special_coul[j/nall] == 0.0 && special_lj[j/nall] == 0.0) continue; diff --git a/src/fix_rdf.h b/src/fix_rdf.h index 47a3f97fc4..4b2148402b 100644 --- a/src/fix_rdf.h +++ b/src/fix_rdf.h @@ -25,6 +25,7 @@ class FixRDF : public Fix { ~FixRDF(); int setmask(); void init(); + void init_list(int, class NeighList *); void setup(); void end_of_step(); @@ -39,6 +40,7 @@ class FixRDF : public Fix { int **hist,**hist_all; // histogram bins int *nrdfatoms; // # of atoms of each type in the group double **gr_ave,**ncoord_ave; // accumulators for average rdf statistics + class NeighList *list; // half neighbor list }; } diff --git a/src/fix_shear_history.cpp b/src/fix_shear_history.cpp index cde7edcdad..54956003ef 100644 --- a/src/fix_shear_history.cpp +++ b/src/fix_shear_history.cpp @@ -16,7 +16,9 @@ #include "fix_shear_history.h" #include "atom.h" #include "neighbor.h" +#include "neigh_list.h" #include "force.h" +#include "pair.h" #include "update.h" #include "modify.h" #include "memory.h" @@ -89,7 +91,10 @@ void FixShearHistory::init() void FixShearHistory::pre_exchange() { - int i,j,k,m; + int i,j,ii,jj,m,inum,jnum; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; // zero npartners for all current atoms @@ -97,24 +102,28 @@ void FixShearHistory::pre_exchange() for (i = 0; i < nlocal; i++) npartner[i] = 0; // copy shear info from neighbor list atoms to atom arrays - // nlocal = nlocal_neighbor = nlocal when neighbor list last built, - // which might be pre-insert on this step - int numneigh; - int *neighs,*touch; - double *firstshear,*shear; int *tag = atom->tag; - nlocal = neighbor->nlocal_neighbor; - for (i = 0; i < nlocal; i++) { - neighs = neighbor->firstneigh[i]; - touch = neighbor->firsttouch[i]; - firstshear = neighbor->firstshear[i]; - numneigh = neighbor->numneigh[i]; - for (k = 0; k < numneigh; k++) { - if (touch[k]) { - shear = &firstshear[3*k]; - j = neighs[k]; + NeighList *list = pair->list; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = list->listgranhistory->firstneigh; + firstshear = list->listgranhistory->firstdouble; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + jlist = firstneigh[i]; + allshear = firstshear[i]; + jnum = numneigh[i]; + touch = firsttouch[i]; + + for (jj = 0; jj < jnum; jj++) { + if (touch[jj]) { + shear = &allshear[3*jj]; + j = jlist[jj]; if (npartner[i] < MAXTOUCH) { m = npartner[i]; partner[i][m] = tag[j]; diff --git a/src/fix_shear_history.h b/src/fix_shear_history.h index 7b2d7346b5..054834f269 100644 --- a/src/fix_shear_history.h +++ b/src/fix_shear_history.h @@ -20,6 +20,7 @@ namespace LAMMPS_NS { class FixShearHistory : public Fix { friend class Neighbor; + friend class PairGranHistory; friend class FixPour; public: @@ -43,6 +44,8 @@ class FixShearHistory : public Fix { int *npartner; // # of touching partners of each atom int **partner; // tags for the partners double ***shearpartner; // 3 shear values with the partner + + class Pair *pair; }; } diff --git a/src/fix_temp_rescale.cpp b/src/fix_temp_rescale.cpp index 05ecfe836d..7d5f200030 100644 --- a/src/fix_temp_rescale.cpp +++ b/src/fix_temp_rescale.cpp @@ -86,20 +86,20 @@ FixTempRescale::FixTempRescale(LAMMPS *lmp, int narg, char **arg) : newarg[0] = id_temp; newarg[1] = group->names[igroup]; if (type == STANDARD) { - newarg[2] = "temp"; + newarg[2] = (char *) "temp"; modify->add_compute(3,newarg); } else if (type == REGION) { - newarg[2] = "temp/region"; + newarg[2] = (char *) "temp/region"; newarg[3] = domain->regions[iregion]->id; modify->add_compute(4,newarg); } else if (type == PARTIAL) { - newarg[2] = "temp/partial"; - if (xflag) newarg[3] = "1"; - else newarg[3] = "0"; - if (yflag) newarg[4] = "1"; - else newarg[4] = "0"; - if (zflag) newarg[5] = "1"; - else newarg[5] = "0"; + newarg[2] = (char *) "temp/partial"; + if (xflag) newarg[3] = (char *) "1"; + else newarg[3] = (char *) "0"; + if (yflag) newarg[4] = (char *) "1"; + else newarg[4] = (char *) "0"; + if (zflag) newarg[5] = (char *) "1"; + else newarg[5] = (char *) "0"; modify->add_compute(6,newarg); } delete [] newarg; diff --git a/src/force.cpp b/src/force.cpp index 802c1061d2..e7cf40ea41 100644 --- a/src/force.cpp +++ b/src/force.cpp @@ -65,7 +65,7 @@ Force::Force(LAMMPS *lmp) : Pointers(lmp) improper = NULL; kspace = NULL; - char *str = "none"; + char *str = (char *) "none"; int n = strlen(str) + 1; pair_style = new char[n]; strcpy(pair_style,str); @@ -120,7 +120,7 @@ void Force::init() create a pair style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_pair(char *style) +void Force::create_pair(const char *style) { delete [] pair_style; if (pair) delete pair; @@ -135,7 +135,7 @@ void Force::create_pair(char *style) generate a pair class ------------------------------------------------------------------------- */ -Pair *Force::new_pair(char *style) +Pair *Force::new_pair(const char *style) { if (strcmp(style,"none") == 0) return NULL; @@ -154,14 +154,21 @@ Pair *Force::new_pair(char *style) else return NULL ------------------------------------------------------------------------- */ -Pair *Force::pair_match(char *word) +Pair *Force::pair_match(const char *word) { if (strstr(pair_style,word)) return pair; else if (strcmp(pair_style,"hybrid") == 0) { - PairHybrid *pair_hybrid = (PairHybrid *) pair; - for (int i = 0; i < pair_hybrid->nstyles; i++) - if (strstr(pair_hybrid->keywords[i],word)) - return pair_hybrid->styles[i]; + PairHybrid *hybrid = (PairHybrid *) pair; + for (int i = 0; i < hybrid->nstyles; i++) { + if (strstr(hybrid->keywords[i],word)) + return hybrid->styles[i]; + } + } else if (strcmp(pair_style,"hybrid/overlay") == 0) { + PairHybridOverlay *hybrid = (PairHybridOverlay *) pair; + for (int i = 0; i < hybrid->nstyles; i++) { + if (strstr(hybrid->keywords[i],word)) + return hybrid->styles[i]; + } } return NULL; } @@ -170,7 +177,7 @@ Pair *Force::pair_match(char *word) create a bond style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_bond(char *style) +void Force::create_bond(const char *style) { delete [] bond_style; if (bond) delete bond; @@ -185,7 +192,7 @@ void Force::create_bond(char *style) generate a bond class ------------------------------------------------------------------------- */ -Bond *Force::new_bond(char *style) +Bond *Force::new_bond(const char *style) { if (strcmp(style,"none") == 0) return NULL; @@ -203,13 +210,13 @@ Bond *Force::new_bond(char *style) return ptr to current bond class or hybrid sub-class if matches style ------------------------------------------------------------------------- */ -Bond *Force::bond_match(char *style) +Bond *Force::bond_match(const char *style) { if (strcmp(bond_style,style) == 0) return bond; else if (strcmp(bond_style,"hybrid") == 0) { - BondHybrid *hbond = (BondHybrid *) bond; - for (int i = 0; i < hbond->nstyles; i++) - if (strcmp(hbond->keywords[i],style) == 0) return hbond->styles[i]; + BondHybrid *hybrid = (BondHybrid *) bond; + for (int i = 0; i < hybrid->nstyles; i++) + if (strcmp(hybrid->keywords[i],style) == 0) return hybrid->styles[i]; } return NULL; } @@ -218,7 +225,7 @@ Bond *Force::bond_match(char *style) create an angle style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_angle(char *style) +void Force::create_angle(const char *style) { delete [] angle_style; if (angle) delete angle; @@ -233,7 +240,7 @@ void Force::create_angle(char *style) generate an angle class ------------------------------------------------------------------------- */ -Angle *Force::new_angle(char *style) +Angle *Force::new_angle(const char *style) { if (strcmp(style,"none") == 0) return NULL; @@ -251,7 +258,7 @@ Angle *Force::new_angle(char *style) create a dihedral style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_dihedral(char *style) +void Force::create_dihedral(const char *style) { delete [] dihedral_style; if (dihedral) delete dihedral; @@ -266,7 +273,7 @@ void Force::create_dihedral(char *style) generate a dihedral class ------------------------------------------------------------------------- */ -Dihedral *Force::new_dihedral(char *style) +Dihedral *Force::new_dihedral(const char *style) { if (strcmp(style,"none") == 0) return NULL; @@ -284,7 +291,7 @@ Dihedral *Force::new_dihedral(char *style) create an improper style, called from input script or restart file ------------------------------------------------------------------------- */ -void Force::create_improper(char *style) +void Force::create_improper(const char *style) { delete [] improper_style; if (improper) delete improper; @@ -299,7 +306,7 @@ void Force::create_improper(char *style) generate a improper class ------------------------------------------------------------------------- */ -Improper *Force::new_improper(char *style) +Improper *Force::new_improper(const char *style) { if (strcmp(style,"none") == 0) return NULL; diff --git a/src/force.h b/src/force.h index a1ae61ddd1..7bf52ac7c5 100644 --- a/src/force.h +++ b/src/force.h @@ -56,22 +56,22 @@ class Force : protected Pointers { ~Force(); void init(); - void create_pair(char *); - class Pair *new_pair(char *); - class Pair *pair_match(char *); + void create_pair(const char *); + class Pair *new_pair(const char *); + class Pair *pair_match(const char *); - void create_bond(char *); - class Bond *new_bond(char *); - class Bond *bond_match(char *); + void create_bond(const char *); + class Bond *new_bond(const char *); + class Bond *bond_match(const char *); - void create_angle(char *); - class Angle *new_angle(char *); + void create_angle(const char *); + class Angle *new_angle(const char *); - void create_dihedral(char *); - class Dihedral *new_dihedral(char *); + void create_dihedral(const char *); + class Dihedral *new_dihedral(const char *); - void create_improper(char *); - class Improper *new_improper(char *); + void create_improper(const char *); + class Improper *new_improper(const char *); void create_kspace(int, char **); diff --git a/src/group.cpp b/src/group.cpp index 9b21a54f75..9ea1cf2b07 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -52,7 +52,7 @@ Group::Group(LAMMPS *lmp) : Pointers(lmp) // create "all" group - char *str = "all"; + char *str = (char *) "all"; int n = strlen(str) + 1; names[0] = (char *) memory->smalloc(n*sizeof(char),"group:names[]"); strcpy(names[0],str); @@ -352,7 +352,7 @@ void Group::create(char *name, int *flag) return group index if name matches existing group, -1 if no such group ------------------------------------------------------------------------- */ -int Group::find(char *name) +int Group::find(const char *name) { for (int igroup = 0; igroup < ngroup; igroup++) if (strcmp(name,names[igroup]) == 0) return igroup; diff --git a/src/group.h b/src/group.h index 34789e5c75..fc855ad5a1 100644 --- a/src/group.h +++ b/src/group.h @@ -31,7 +31,7 @@ class Group : protected Pointers { ~Group(); void assign(int, char **); // assign atoms to a group void create(char *, int *); // add flagged atoms to a group - int find(char *); // lookup name in list of groups + int find(const char *); // lookup name in list of groups void write_restart(FILE *); void read_restart(FILE *); diff --git a/src/memory.cpp b/src/memory.cpp index 430f7d8165..caf553120a 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -28,7 +28,7 @@ Memory::Memory(LAMMPS *lmp) : Pointers(lmp) {} safe malloc ------------------------------------------------------------------------- */ -void *Memory::smalloc(int n, char *name) +void *Memory::smalloc(int n, const char *name) { if (n == 0) return NULL; void *ptr = malloc(n); @@ -54,7 +54,7 @@ void Memory::sfree(void *ptr) safe realloc ------------------------------------------------------------------------- */ -void *Memory::srealloc(void *ptr, int n, char *name) +void *Memory::srealloc(void *ptr, int n, const char *name) { if (n == 0) return NULL; ptr = realloc(ptr,n); @@ -70,7 +70,7 @@ void *Memory::srealloc(void *ptr, int n, char *name) create a 1d double array with index from nlo to nhi inclusive ------------------------------------------------------------------------- */ -double *Memory::create_1d_double_array(int nlo, int nhi, char *name) +double *Memory::create_1d_double_array(int nlo, int nhi, const char *name) { int n = nhi - nlo + 1; double *array = (double *) smalloc(n*sizeof(double),name); @@ -91,7 +91,7 @@ void Memory::destroy_1d_double_array(double *array, int offset) create a 2d double array ------------------------------------------------------------------------- */ -double **Memory::create_2d_double_array(int n1, int n2, char *name) +double **Memory::create_2d_double_array(int n1, int n2, const char *name) { double *data = (double *) smalloc(n1*n2*sizeof(double),name); @@ -125,7 +125,7 @@ void Memory::destroy_2d_double_array(double **array) ------------------------------------------------------------------------- */ double **Memory::grow_2d_double_array(double **array, - int n1, int n2, char *name) + int n1, int n2, const char *name) { if (array == NULL) return create_2d_double_array(n1,n2,name); @@ -147,7 +147,7 @@ double **Memory::grow_2d_double_array(double **array, if either dim is 0, return NULL ------------------------------------------------------------------------- */ -int **Memory::create_2d_int_array(int n1, int n2, char *name) +int **Memory::create_2d_int_array(int n1, int n2, const char *name) { if (n1 == 0 || n2 == 0) return NULL; @@ -182,7 +182,7 @@ void Memory::destroy_2d_int_array(int **array) if either dim is 0, return NULL ------------------------------------------------------------------------- */ -int **Memory::grow_2d_int_array(int **array, int n1, int n2, char *name) +int **Memory::grow_2d_int_array(int **array, int n1, int n2, const char *name) { if (n1 == 0 || n2 == 0) { @@ -208,7 +208,8 @@ int **Memory::grow_2d_int_array(int **array, int n1, int n2, char *name) create a 2d double array with 2nd index from n2lo to n2hi inclusive ------------------------------------------------------------------------- */ -double **Memory::create_2d_double_array(int n1, int n2lo, int n2hi, char *name) +double **Memory::create_2d_double_array(int n1, int n2lo, int n2hi, + const char *name) { int n2 = n2hi - n2lo + 1; double **array = create_2d_double_array(n1,n2,name); @@ -232,7 +233,8 @@ void Memory::destroy_2d_double_array(double **array, int offset) create a 3d double array ------------------------------------------------------------------------- */ -double ***Memory::create_3d_double_array(int n1, int n2, int n3, char *name) +double ***Memory::create_3d_double_array(int n1, int n2, int n3, + const char *name) { int i,j; @@ -271,7 +273,8 @@ void Memory::destroy_3d_double_array(double ***array) ------------------------------------------------------------------------- */ double ***Memory::grow_3d_double_array(double ***array, - int n1, int n2, int n3, char *name) + int n1, int n2, int n3, + const char *name) { int i,j; @@ -303,7 +306,7 @@ double ***Memory::grow_3d_double_array(double ***array, ------------------------------------------------------------------------- */ double ***Memory::create_3d_double_array(int n1lo, int n1hi, - int n2, int n3, char *name) + int n2, int n3, const char *name) { int n1 = n1hi - n1lo + 1; double ***array = create_3d_double_array(n1,n2,n3,name); @@ -328,7 +331,7 @@ void Memory::destroy_3d_double_array(double ***array, int offset) double ***Memory::create_3d_double_array(int n1lo, int n1hi, int n2lo, int n2hi, - int n3lo, int n3hi, char *name) + int n3lo, int n3hi, const char *name) { int n1 = n1hi - n1lo + 1; int n2 = n2hi - n2lo + 1; @@ -358,7 +361,7 @@ void Memory::destroy_3d_double_array(double ***array, int n1_offset, create a 3d int array ------------------------------------------------------------------------- */ -int ***Memory::create_3d_int_array(int n1, int n2, int n3, char *name) +int ***Memory::create_3d_int_array(int n1, int n2, int n3, const char *name) { int i,j; @@ -394,7 +397,8 @@ void Memory::destroy_3d_int_array(int ***array) create a 4d double array ------------------------------------------------------------------------- */ -double ****Memory::create_4d_double_array(int n1, int n2, int n3, int n4, char *name) +double ****Memory::create_4d_double_array(int n1, int n2, int n3, int n4, + const char *name) { int i,j,k; diff --git a/src/memory.h b/src/memory.h index e5f2cf73da..39b79f7060 100644 --- a/src/memory.h +++ b/src/memory.h @@ -22,38 +22,38 @@ class Memory : protected Pointers { public: Memory(class LAMMPS *); - void *smalloc(int n, char *); + void *smalloc(int n, const char *); void sfree(void *); - void *srealloc(void *, int n, char *name); + void *srealloc(void *, int n, const char *name); - double *create_1d_double_array(int, int, char *); + double *create_1d_double_array(int, int, const char *); void destroy_1d_double_array(double *, int); - double **create_2d_double_array(int, int, char *); + double **create_2d_double_array(int, int, const char *); void destroy_2d_double_array(double **); - double **grow_2d_double_array(double **, int, int, char *); + double **grow_2d_double_array(double **, int, int, const char *); - int **create_2d_int_array(int, int, char *); + int **create_2d_int_array(int, int, const char *); void destroy_2d_int_array(int **); - int **grow_2d_int_array(int **, int, int, char *); + int **grow_2d_int_array(int **, int, int, const char *); - double **create_2d_double_array(int, int, int, char *); + double **create_2d_double_array(int, int, int, const char *); void destroy_2d_double_array(double **, int); - double ***create_3d_double_array(int, int, int, char *); + double ***create_3d_double_array(int, int, int, const char *); void destroy_3d_double_array(double ***); - double ***grow_3d_double_array(double ***, int, int, int, char *); + double ***grow_3d_double_array(double ***, int, int, int, const char *); - double ***create_3d_double_array(int, int, int, int, char *); + double ***create_3d_double_array(int, int, int, int, const char *); void destroy_3d_double_array(double ***, int); - double ***create_3d_double_array(int, int, int, int, int, int, char *); + double ***create_3d_double_array(int, int, int, int, int, int, const char *); void destroy_3d_double_array(double ***, int, int, int); - int ***create_3d_int_array(int, int, int, char *); + int ***create_3d_int_array(int, int, int, const char *); void destroy_3d_int_array(int ***); - double ****create_4d_double_array(int, int, int, int, char *); + double ****create_4d_double_array(int, int, int, int, const char *); void destroy_4d_double_array(double ****); }; diff --git a/src/min_cg.cpp b/src/min_cg.cpp index 4390e27e5c..ad0a74740e 100644 --- a/src/min_cg.cpp +++ b/src/min_cg.cpp @@ -65,9 +65,9 @@ void MinCG::init() // will delete it at end of run char **fixarg = new char*[3]; - fixarg[0] = "MINIMIZE"; - fixarg[1] = "all"; - fixarg[2] = "MINIMIZE"; + fixarg[0] = (char *) "MINIMIZE"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "MINIMIZE"; modify->add_fix(3,fixarg); delete [] fixarg; fix_minimize = (FixMinimize *) modify->fix[modify->nfix-1]; @@ -85,12 +85,9 @@ void MinCG::init() // set flags for what arrays to clear in force_clear() // need to clear torques if array exists - // don't need to clear f_pair if atom_style is only granular (no virial) torqueflag = 0; if (atom->torque) torqueflag = 1; - pairflag = 1; - if (strcmp(atom->atom_style,"granular") == 0) pairflag = 0; // orthogonal vs triclinic simulation box @@ -115,11 +112,6 @@ void MinCG::init() if (linestyle == SCAN) linemin = &MinCG::linemin_scan; else if (linestyle == SECANT) linemin = &MinCG::linemin_secant; - - // local versions of Update quantities - - maxpair = update->maxpair; - f_pair = update->f_pair; } /* ---------------------------------------------------------------------- @@ -233,6 +225,8 @@ void MinCG::setup() int vflag = virial_thermo; force_clear(vflag); + if (force->pair) force->pair->compute(eflag,vflag); + if (atom->molecular) { if (force->bond) force->bond->compute(eflag,vflag); if (force->angle) force->angle->compute(eflag,vflag); @@ -240,8 +234,6 @@ void MinCG::setup() if (force->improper) force->improper->compute(eflag,vflag); } - if (force->pair) force->pair->compute(eflag,vflag); - if (force->kspace) { force->kspace->setup(); force->kspace->compute(eflag,vflag); @@ -391,6 +383,12 @@ void MinCG::eng_force(int *pndof, double **px, double **ph, double *peng) force_clear(vflag); timer->stamp(); + + if (force->pair) { + force->pair->compute(eflag,vflag); + timer->stamp(TIME_PAIR); + } + if (atom->molecular) { if (force->bond) force->bond->compute(eflag,vflag); if (force->angle) force->angle->compute(eflag,vflag); @@ -399,11 +397,6 @@ void MinCG::eng_force(int *pndof, double **px, double **ph, double *peng) timer->stamp(TIME_BOND); } - if (force->pair) { - force->pair->compute(eflag,vflag); - timer->stamp(TIME_PAIR); - } - if (force->kspace) { force->kspace->compute(eflag,vflag); timer->stamp(TIME_KSPACE); @@ -462,23 +455,6 @@ void MinCG::force_clear(int vflag) torque[i][2] = 0.0; } } - - // clear f_pair array if using it this timestep to compute virial - - if (vflag == 2 && pairflag) { - if (atom->nmax > maxpair) { - maxpair = atom->nmax; - memory->destroy_2d_double_array(f_pair); - f_pair = memory->create_2d_double_array(maxpair,3,"min:f_pair"); - update->maxpair = maxpair; - update->f_pair = f_pair; - } - for (i = 0; i < nall; i++) { - f_pair[i][0] = 0.0; - f_pair[i][1] = 0.0; - f_pair[i][2] = 0.0; - } - } } /* ---------------------------------------------------------------------- diff --git a/src/modify.cpp b/src/modify.cpp index 6d6c85da56..7a53ea7541 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -406,8 +406,8 @@ void Modify::add_fix(int narg, char **arg) strcmp(style_restart_global[i],fix[ifix]->style) == 0) { fix[ifix]->restart(state_restart_global[i]); if (comm->me == 0) { - char *str = "Resetting global state of Fix %s Style %s " - "from restart file info\n"; + char *str = (char *) ("Resetting global state of Fix %s Style %s " + "from restart file info\n"); if (screen) fprintf(screen,str,fix[ifix]->id,fix[ifix]->style); if (logfile) fprintf(logfile,str,fix[ifix]->id,fix[ifix]->style); } @@ -422,8 +422,8 @@ void Modify::add_fix(int narg, char **arg) for (int j = 0; j < atom->nlocal; j++) fix[ifix]->unpack_restart(j,index_restart_peratom[i]); if (comm->me == 0) { - char *str = "Resetting per-atom state of Fix %s Style %s " - "from restart file info\n"; + char *str = (char *) ("Resetting per-atom state of Fix %s Style %s " + "from restart file info\n"); if (screen) fprintf(screen,str,fix[ifix]->id,fix[ifix]->style); if (logfile) fprintf(logfile,str,fix[ifix]->id,fix[ifix]->style); } @@ -453,7 +453,7 @@ void Modify::modify_fix(int narg, char **arg) Atom class must update indices in its list of callbacks to fixes ------------------------------------------------------------------------- */ -void Modify::delete_fix(char *id) +void Modify::delete_fix(const char *id) { int ifix = find_fix(id); if (ifix < 0) error->all("Could not find fix ID to delete"); @@ -472,7 +472,7 @@ void Modify::delete_fix(char *id) return index of fix or -1 if not found ------------------------------------------------------------------------- */ -int Modify::find_fix(char *id) +int Modify::find_fix(const char *id) { int ifix; for (ifix = 0; ifix < nfix; ifix++) diff --git a/src/modify.h b/src/modify.h index e49bef7f74..88411fe11c 100644 --- a/src/modify.h +++ b/src/modify.h @@ -58,8 +58,8 @@ class Modify : protected Pointers { void add_fix(int, char **); void modify_fix(int, char **); - void delete_fix(char *); - int find_fix(char *); + void delete_fix(const char *); + int find_fix(const char *); void add_compute(int, char **); void modify_compute(int, char **); diff --git a/src/neigh_full.cpp b/src/neigh_full.cpp index f5385e11e0..878ab0819c 100644 --- a/src/neigh_full.cpp +++ b/src/neigh_full.cpp @@ -12,6 +12,7 @@ ------------------------------------------------------------------------- */ #include "neighbor.h" +#include "neigh_list.h" #include "atom.h" #include "error.h" @@ -22,7 +23,7 @@ using namespace LAMMPS_NS; every neighbor pair appears in list of both atoms i and j ------------------------------------------------------------------------- */ -void Neighbor::full_nsq() +void Neighbor::full_nsq(NeighList *list) { int i,j,n,itype,jtype,which; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -36,6 +37,12 @@ void Neighbor::full_nsq() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + + int inum = 0; int npage = 0; int npnt = 0; @@ -44,10 +51,10 @@ void Neighbor::full_nsq() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage_full) add_pages_full(npage); + if (npage == list->maxpage) pages = list->add_pages(); } - neighptr = &pages_full[npage][npnt]; + neighptr = &pages[npage][npnt]; n = 0; itype = type[i]; @@ -60,9 +67,10 @@ void Neighbor::full_nsq() for (j = 0; j < nall; j++) { if (i == j) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -75,12 +83,16 @@ void Neighbor::full_nsq() } } - firstneigh_full[i] = neighptr; - numneigh_full[i] = n; + ilist[inum] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -88,7 +100,7 @@ void Neighbor::full_nsq() every neighbor pair appears in list of both atoms i and j ------------------------------------------------------------------------- */ -void Neighbor::full_bin() +void Neighbor::full_bin(NeighList *list) { int i,j,k,n,itype,jtype,ibin,which; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -108,6 +120,14 @@ void Neighbor::full_bin() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + int inum = 0; int npage = 0; int npnt = 0; @@ -116,10 +136,10 @@ void Neighbor::full_bin() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage_full) add_pages_full(npage); + if (npage == list->maxpage) pages = list->add_pages(); } - neighptr = &pages_full[npage][npnt]; + neighptr = &pages[npage][npnt]; n = 0; itype = type[i]; @@ -132,12 +152,13 @@ void Neighbor::full_bin() ibin = coord2bin(x[i]); - for (k = 0; k < nstencil_full; k++) { - for (j = binhead[ibin+stencil_full[k]]; j >= 0; j = bins[j]) { + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { if (i == j) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -152,12 +173,16 @@ void Neighbor::full_bin() } } - firstneigh_full[i] = neighptr; - numneigh_full[i] = n; + ilist[inum] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -166,7 +191,7 @@ void Neighbor::full_bin() every neighbor pair appears in list of both atoms i and j ------------------------------------------------------------------------- */ -void Neighbor::full_bin_multi() +void Neighbor::full_multi(NeighList *list) { int i,j,k,n,itype,jtype,ibin,which,ns; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -187,6 +212,15 @@ void Neighbor::full_bin_multi() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + + int inum = 0; int npage = 0; int npnt = 0; @@ -195,10 +229,10 @@ void Neighbor::full_bin_multi() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage_full) add_pages_full(npage); + if (npage == list->maxpage) pages = list->add_pages(); } - neighptr = &pages_full[npage][npnt]; + neighptr = &pages[npage][npnt]; n = 0; itype = type[i]; @@ -211,16 +245,17 @@ void Neighbor::full_bin_multi() // skip i = j ibin = coord2bin(x[i]); - s = stencil_full_multi[itype]; - distsq = distsq_full_multi[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; cutsq = cutneighsq[itype]; - ns = nstencil_full_multi[itype]; + ns = nstencil_multi[itype]; for (k = 0; k < ns; k++) { for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { jtype = type[j]; if (cutsq[jtype] < distsq[k]) continue; if (i == j) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; @@ -236,10 +271,14 @@ void Neighbor::full_bin_multi() } } - firstneigh_full[i] = neighptr; - numneigh_full[i] = n; + ilist[inum] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } diff --git a/src/neigh_gran.cpp b/src/neigh_gran.cpp index ef12943b40..17c35fdb66 100644 --- a/src/neigh_gran.cpp +++ b/src/neigh_gran.cpp @@ -12,8 +12,8 @@ ------------------------------------------------------------------------- */ #include "neighbor.h" +#include "neigh_list.h" #include "atom.h" -#include "modify.h" #include "fix_shear_history.h" #include "error.h" @@ -27,22 +27,21 @@ using namespace LAMMPS_NS; pair added if j is ghost (also stored by proc owning j) ------------------------------------------------------------------------- */ -void Neighbor::granular_nsq_no_newton() +void Neighbor::granular_nsq_no_newton(NeighList *list) { int i,j,m,n,nn; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr,*touchptr; double *shearptr; - int *npartner; - int **partner; - double ***shearpartner; - if (fix_history) { - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - } + NeighList *listgranhistory; + int *npartner,**partner; + double ***shearpartner; + int **firsttouch; + double **firstshear; + int **pages_touch; + double **pages_shear; double **x = atom->x; double *radius = atom->radius; @@ -53,6 +52,26 @@ void Neighbor::granular_nsq_no_newton() int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + pages_touch = listgranhistory->pages; + pages_shear = listgranhistory->dpages; + } + + int inum = 0; int npage = 0; int npnt = 0; @@ -61,9 +80,12 @@ void Neighbor::granular_nsq_no_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) { - add_pages(npage); - if (fix_history) add_pages_history(npage); + if (npage == list->maxpage) { + pages = list->add_pages(); + if (fix_history) { + pages_touch = listgranhistory->add_pages(); + pages_shear = listgranhistory->dpages; + } } } @@ -83,7 +105,7 @@ void Neighbor::granular_nsq_no_newton() // loop over remaining atoms, owned and ghost for (j = i+1; j < nall; j++) { - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; @@ -122,16 +144,21 @@ void Neighbor::granular_nsq_no_newton() } } + ilist[inum] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; if (fix_history) { firsttouch[i] = touchptr; firstshear[i] = shearptr; } - firstneigh[i] = neighptr; - numneigh[i] = n; + + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -143,7 +170,7 @@ void Neighbor::granular_nsq_no_newton() decision based on itag,jtag tests ------------------------------------------------------------------------- */ -void Neighbor::granular_nsq_newton() +void Neighbor::granular_nsq_newton(NeighList *list) { int i,j,n,itag,jtag; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -159,6 +186,14 @@ void Neighbor::granular_nsq_newton() int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + int inum = 0; int npage = 0; int npnt = 0; @@ -167,7 +202,7 @@ void Neighbor::granular_nsq_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } n = 0; @@ -196,7 +231,7 @@ void Neighbor::granular_nsq_newton() } } - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; @@ -208,12 +243,16 @@ void Neighbor::granular_nsq_newton() if (rsq <= cutsq) neighptr[n++] = j; } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -225,22 +264,21 @@ void Neighbor::granular_nsq_newton() pair stored by me if j is ghost (also stored by proc owning j) ------------------------------------------------------------------------- */ -void Neighbor::granular_bin_no_newton() +void Neighbor::granular_bin_no_newton(NeighList *list) { int i,j,k,m,n,nn,ibin; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutsq; int *neighptr,*touchptr; double *shearptr; - int *npartner; - int **partner; - double ***shearpartner; - if (fix_history) { - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - } + NeighList *listgranhistory; + int *npartner,**partner; + double ***shearpartner; + int **firsttouch; + double **firstshear; + int **pages_touch; + double **pages_shear; // bin local & ghost atoms @@ -256,6 +294,26 @@ void Neighbor::granular_bin_no_newton() int *molecule = atom->molecule; int nlocal = atom->nlocal; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + pages_touch = listgranhistory->pages; + pages_shear = listgranhistory->dpages; + } + + int inum = 0; int npage = 0; int npnt = 0; @@ -264,9 +322,12 @@ void Neighbor::granular_bin_no_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) { - add_pages(npage); - if (fix_history) add_pages_history(npage); + if (npage == list->maxpage) { + pages = list->add_pages(); + if (fix_history) { + pages_touch = listgranhistory->add_pages(); + pages_shear = listgranhistory->dpages; + } } } @@ -292,7 +353,7 @@ void Neighbor::granular_bin_no_newton() for (k = 0; k < nstencil; k++) { for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { if (j <= i) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; @@ -332,16 +393,21 @@ void Neighbor::granular_bin_no_newton() } } + ilist[inum] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; if (fix_history) { firsttouch[i] = touchptr; firstshear[i] = shearptr; } - firstneigh[i] = neighptr; - numneigh[i] = n; + + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -352,7 +418,7 @@ void Neighbor::granular_bin_no_newton() every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -void Neighbor::granular_bin_newton() +void Neighbor::granular_bin_newton(NeighList *list) { int i,j,k,n,ibin; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -372,6 +438,14 @@ void Neighbor::granular_bin_newton() int *molecule = atom->molecule; int nlocal = atom->nlocal; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + int inum = 0; int npage = 0; int npnt = 0; @@ -380,7 +454,7 @@ void Neighbor::granular_bin_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } n = 0; @@ -400,7 +474,7 @@ void Neighbor::granular_bin_newton() if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; } delx = xtmp - x[j][0]; @@ -418,7 +492,7 @@ void Neighbor::granular_bin_newton() ibin = coord2bin(x[i]); for (k = 0; k < nstencil; k++) { for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; @@ -431,12 +505,16 @@ void Neighbor::granular_bin_newton() } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -447,7 +525,7 @@ void Neighbor::granular_bin_newton() every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -void Neighbor::granular_bin_newton_tri() +void Neighbor::granular_bin_newton_tri(NeighList *list) { int i,j,k,n,ibin; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -467,6 +545,14 @@ void Neighbor::granular_bin_newton_tri() int *molecule = atom->molecule; int nlocal = atom->nlocal; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + int inum = 0; int npage = 0; int npnt = 0; @@ -475,7 +561,7 @@ void Neighbor::granular_bin_newton_tri() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } n = 0; @@ -497,7 +583,7 @@ void Neighbor::granular_bin_newton_tri() if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] <= xtmp) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; @@ -510,10 +596,14 @@ void Neighbor::granular_bin_newton_tri() } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); } + + list->inum = inum; } diff --git a/src/neigh_half.cpp b/src/neigh_half.cpp deleted file mode 100644 index 63f1edff7e..0000000000 --- a/src/neigh_half.cpp +++ /dev/null @@ -1,820 +0,0 @@ -/* ---------------------------------------------------------------------- - 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 - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "atom.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void Neighbor::half_nsq_no_newton() -{ - int i,j,n,itype,jtype,which; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over remaining atoms, owned and ghost - - for (j = i+1; j < nall; j++) { - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - every pair stored exactly once by some processor - decision on ghost atoms based on itag,jtag tests -------------------------------------------------------------------------- */ - -void Neighbor::half_nsq_newton() -{ - int i,j,n,itype,jtype,itag,jtag,which; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - double **x = atom->x; - int *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over remaining atoms, owned and ghost - // itag = jtag is possible for long cutoffs that include images of self - - for (j = i+1; j < nall; j++) { - if (j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) continue; - } else { - if (x[j][2] < ztmp) continue; - else if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - else if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) - continue; - } - } - - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void Neighbor::half_bin_no_newton() -{ - int i,j,k,n,itype,jtype,ibin,which; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = coord2bin(x[i]); - - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with partial Newton's 3rd law - each owned atom i checks own bin and other bins in stencil - multi-type stencil is itype dependent and is distance checked - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void Neighbor::half_bin_no_newton_multi() -{ - int i,j,k,n,itype,jtype,ibin,which,ns; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // skip if i,j neighbor cutoff is less than bin distance - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - if (j <= i) continue; - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::half_bin_newton() -{ - int i,j,k,n,itype,jtype,ibin,which; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with full Newton's 3rd law - each owned atom i checks its own bin and other bins in Newton stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::half_bin_newton_multi() -{ - int i,j,k,n,itype,jtype,ibin,which,ns; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - - // loop over all atoms in other bins in stencil, store every pair - // skip if i,j neighbor cutoff is less than bin distance - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::half_bin_newton_tri() -{ - int i,j,k,n,itype,jtype,ibin,which; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over all atoms in bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and <= x) - // this excludes self-self interaction - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] <= xtmp) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - jtype = type[j]; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction with Newton's 3rd law for triclinic - each owned atom i checks its own bin and other bins in triclinic stencil - multi-type stencil is itype dependent and is distance checked - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::half_bin_newton_multi_tri() -{ - int i,j,k,n,itype,jtype,ibin,which,ns; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - int *type = atom->type; - int *mask = atom->mask; - int *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - int molecular = atom->molecular; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over all atoms in bins, including self, in stencil - // skip if i,j neighbor cutoff is less than bin distance - // bins below self are excluded from stencil - // pairs for atoms j below i are excluded - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[itype]; - for (k = 0; k < ns; k++) { - for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (cutsq[jtype] < distsq[k]) continue; - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] <= xtmp) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) which = find_special(i,j); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (which > 0) neighptr[n++] = which*nall + j; - } - } - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void Neighbor::half_full_no_newton() -{ - int i,j,k,n,nfull; - int *neighptr,*neighs; - - int nlocal = atom->nlocal; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - // loop over full neighbor list - - neighs = firstneigh_full[i]; - nfull = numneigh_full[i]; - - for (k = 0; k < nfull; k++) { - j = neighs[k]; - if (j > i) neighptr[n++] = j; - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} - -/* ---------------------------------------------------------------------- - build half list from full list - pair stored once if i,j are both owned and i < j - pair stored by me if j is ghost (also stored by proc owning j) -------------------------------------------------------------------------- */ - -void Neighbor::half_full_newton() -{ - int i,j,k,n,nfull; - int *neighptr,*neighs; - double xtmp,ytmp,ztmp; - - double **x = atom->x; - int nlocal = atom->nlocal; - - int npage = 0; - int npnt = 0; - - for (i = 0; i < nlocal; i++) { - - if (pgsize - npnt < oneatom) { - npnt = 0; - npage++; - if (npage == maxpage) add_pages(npage); - } - - neighptr = &pages[npage][npnt]; - n = 0; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over full neighbor list - - neighs = firstneigh_full[i]; - nfull = numneigh_full[i]; - - for (k = 0; k < nfull; k++) { - j = neighs[k]; - if (j < nlocal) { - if (i > j) continue; - } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp && x[j][1] < ytmp) continue; - if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - neighptr[n++] = j; - } - - firstneigh[i] = neighptr; - numneigh[i] = n; - npnt += n; - if (npnt >= pgsize) - error->one("Neighbor list overflow, boost neigh_modify one or page"); - } -} diff --git a/src/neigh_respa.cpp b/src/neigh_respa.cpp index a37275f37b..38bb3232e7 100644 --- a/src/neigh_respa.cpp +++ b/src/neigh_respa.cpp @@ -12,6 +12,7 @@ ------------------------------------------------------------------------- */ #include "neighbor.h" +#include "neigh_list.h" #include "atom.h" #include "error.h" @@ -24,14 +25,11 @@ using namespace LAMMPS_NS; pair added if j is ghost (also stored by proc owning j) ------------------------------------------------------------------------- */ -void Neighbor::respa_nsq_no_newton() +void Neighbor::respa_nsq_no_newton(NeighList *list) { - int i,j,itype,jtype,which; - int n_inner,n_middle,n; + int i,j,n,itype,jtype,which,n_inner,n_middle; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr_inner; - int *neighptr_middle; - int *neighptr; + int *neighptr,*neighptr_inner,*neighptr_middle; double **x = atom->x; int *type = atom->type; @@ -41,6 +39,27 @@ void Neighbor::respa_nsq_no_newton() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + + NeighList *listinner = list->listinner; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + int **pages_inner = listinner->pages; + + NeighList *listmiddle; + int *numneigh_middle,**firstneigh_middle,**pages_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + pages_middle = listmiddle->pages; + } + + int inum = 0; int npage = 0; int npnt = 0; int npage_inner = 0; @@ -53,7 +72,7 @@ void Neighbor::respa_nsq_no_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } neighptr = &pages[npage][npnt]; n = 0; @@ -61,16 +80,18 @@ void Neighbor::respa_nsq_no_newton() if (pgsize - npnt_inner < oneatom) { npnt_inner = 0; npage_inner++; - if (npage_inner == maxpage_inner) add_pages_inner(npage_inner); + if (npage_inner == listinner->maxpage) + pages_inner = listinner->add_pages(); } neighptr_inner = &pages_inner[npage_inner][npnt_inner]; n_inner = 0; - if (respa == 2) { + if (respamiddle) { if (pgsize - npnt_middle < oneatom) { npnt_middle = 0; npage_middle++; - if (npage_middle == maxpage_middle) add_pages_middle(npage_middle); + if (npage_middle == listmiddle->maxpage) + pages_middle = listmiddle->add_pages(); } neighptr_middle = &pages_middle[npage_middle][npnt_middle]; n_middle = 0; @@ -84,9 +105,9 @@ void Neighbor::respa_nsq_no_newton() // loop over remaining atoms, owned and ghost for (j = i+1; j < nall; j++) { - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -103,15 +124,17 @@ void Neighbor::respa_nsq_no_newton() else if (which > 0) neighptr_inner[n_inner++] = which*nall + j; } - if (respa == 2 && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { if (which == 0) neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = which*nall + j; } } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); @@ -122,7 +145,7 @@ void Neighbor::respa_nsq_no_newton() if (npnt_inner >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); - if (respa == 2) { + if (respamiddle) { firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; npnt_middle += n_middle; @@ -130,6 +153,8 @@ void Neighbor::respa_nsq_no_newton() error->one("Neighbor list overflow, boost neigh_modify one or page"); } } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -140,14 +165,11 @@ void Neighbor::respa_nsq_no_newton() decision based on itag,jtag tests ------------------------------------------------------------------------- */ -void Neighbor::respa_nsq_newton() +void Neighbor::respa_nsq_newton(NeighList *list) { - int i,j,itype,jtype,itag,jtag,which; - int n_inner,n_middle,n; + int i,j,n,itype,jtype,itag,jtag,which,n_inner,n_middle; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr_inner; - int *neighptr_middle; - int *neighptr; + int *neighptr,*neighptr_inner,*neighptr_middle; double **x = atom->x; int *tag = atom->tag; @@ -158,6 +180,27 @@ void Neighbor::respa_nsq_newton() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + + NeighList *listinner = list->listinner; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + int **pages_inner = listinner->pages; + + NeighList *listmiddle; + int *numneigh_middle,**firstneigh_middle,**pages_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + pages_middle = listmiddle->pages; + } + + int inum = 0; int npage = 0; int npnt = 0; int npage_inner = 0; @@ -170,7 +213,7 @@ void Neighbor::respa_nsq_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } neighptr = &pages[npage][npnt]; n = 0; @@ -178,16 +221,18 @@ void Neighbor::respa_nsq_newton() if (pgsize - npnt_inner < oneatom) { npnt_inner = 0; npage_inner++; - if (npage_inner == maxpage_inner) add_pages_inner(npage_inner); + if (npage_inner == listinner->maxpage) + pages_inner = listinner->add_pages(); } neighptr_inner = &pages_inner[npage_inner][npnt_inner]; n_inner = 0; - if (respa == 2) { + if (respamiddle) { if (pgsize - npnt_middle < oneatom) { npnt_middle = 0; npage_middle++; - if (npage_middle == maxpage_middle) add_pages_middle(npage_middle); + if (npage_middle == listmiddle->maxpage) + pages_middle = listmiddle->add_pages(); } neighptr_middle = &pages_middle[npage_middle][npnt_middle]; n_middle = 0; @@ -216,9 +261,9 @@ void Neighbor::respa_nsq_newton() } } - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -235,15 +280,18 @@ void Neighbor::respa_nsq_newton() else if (which > 0) neighptr_inner[n_inner++] = which*nall + j; } - if (respa == 2 && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { if (which == 0) neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = which*nall + j; } } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); @@ -254,7 +302,7 @@ void Neighbor::respa_nsq_newton() if (npnt_inner >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); - if (respa == 2) { + if (respamiddle) { firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; npnt_middle += n_middle; @@ -262,6 +310,8 @@ void Neighbor::respa_nsq_newton() error->one("Neighbor list overflow, boost neigh_modify one or page"); } } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -272,14 +322,11 @@ void Neighbor::respa_nsq_newton() pair stored by me if j is ghost (also stored by proc owning j) ------------------------------------------------------------------------- */ -void Neighbor::respa_bin_no_newton() +void Neighbor::respa_bin_no_newton(NeighList *list) { - int i,j,k,itype,jtype,ibin,which; - int n_inner,n_middle,n; + int i,j,k,n,itype,jtype,ibin,which,n_inner,n_middle; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr_inner; - int *neighptr_middle; - int *neighptr; + int *neighptr,*neighptr_inner,*neighptr_middle; // bin local & ghost atoms @@ -295,6 +342,29 @@ void Neighbor::respa_bin_no_newton() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + NeighList *listinner = list->listinner; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + int **pages_inner = listinner->pages; + + NeighList *listmiddle; + int *numneigh_middle,**firstneigh_middle,**pages_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + pages_middle = listmiddle->pages; + } + + int inum = 0; int npage = 0; int npnt = 0; int npage_inner = 0; @@ -307,7 +377,7 @@ void Neighbor::respa_bin_no_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } neighptr = &pages[npage][npnt]; n = 0; @@ -315,16 +385,18 @@ void Neighbor::respa_bin_no_newton() if (pgsize - npnt_inner < oneatom) { npnt_inner = 0; npage_inner++; - if (npage_inner == maxpage_inner) add_pages_inner(npage_inner); + if (npage_inner == listinner->maxpage) + pages_inner = listinner->add_pages(); } neighptr_inner = &pages_inner[npage_inner][npnt_inner]; n_inner = 0; - if (respa == 2) { + if (respamiddle) { if (pgsize - npnt_middle < oneatom) { npnt_middle = 0; npage_middle++; - if (npage_middle == maxpage_middle) add_pages_middle(npage_middle); + if (npage_middle == listmiddle->maxpage) + pages_middle = listmiddle->add_pages(); } neighptr_middle = &pages_middle[npage_middle][npnt_middle]; n_middle = 0; @@ -344,9 +416,10 @@ void Neighbor::respa_bin_no_newton() for (k = 0; k < nstencil; k++) { for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { if (j <= i) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -363,7 +436,8 @@ void Neighbor::respa_bin_no_newton() else if (which > 0) neighptr_inner[n_inner++] = which*nall + j; } - if (respa == 2 && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { if (which == 0) neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = which*nall + j; } @@ -371,8 +445,10 @@ void Neighbor::respa_bin_no_newton() } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); @@ -383,7 +459,7 @@ void Neighbor::respa_bin_no_newton() if (npnt_inner >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); - if (respa == 2) { + if (respamiddle) { firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; npnt_middle += n_middle; @@ -391,6 +467,8 @@ void Neighbor::respa_bin_no_newton() error->one("Neighbor list overflow, boost neigh_modify one or page"); } } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -400,14 +478,11 @@ void Neighbor::respa_bin_no_newton() every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -void Neighbor::respa_bin_newton() +void Neighbor::respa_bin_newton(NeighList *list) { - int i,j,k,itype,jtype,ibin,which; - int n_inner,n_middle,n; + int i,j,k,n,itype,jtype,ibin,which,n_inner,n_middle; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr_inner; - int *neighptr_middle; - int *neighptr; + int *neighptr,*neighptr_inner,*neighptr_middle; // bin local & ghost atoms @@ -423,6 +498,29 @@ void Neighbor::respa_bin_newton() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + NeighList *listinner = list->listinner; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + int **pages_inner = listinner->pages; + + NeighList *listmiddle; + int *numneigh_middle,**firstneigh_middle,**pages_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + pages_middle = listmiddle->pages; + } + + int inum = 0; int npage = 0; int npnt = 0; int npage_inner = 0; @@ -435,7 +533,7 @@ void Neighbor::respa_bin_newton() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } neighptr = &pages[npage][npnt]; n = 0; @@ -443,16 +541,18 @@ void Neighbor::respa_bin_newton() if (pgsize - npnt_inner < oneatom) { npnt_inner = 0; npage_inner++; - if (npage_inner == maxpage_inner) add_pages_inner(npage_inner); + if (npage_inner == listinner->maxpage) + pages_inner = listinner->add_pages(); } neighptr_inner = &pages_inner[npage_inner][npnt_inner]; n_inner = 0; - if (respa == 2) { + if (respamiddle) { if (pgsize - npnt_middle < oneatom) { npnt_middle = 0; npage_middle++; - if (npage_middle == maxpage_middle) add_pages_middle(npage_middle); + if (npage_middle == listmiddle->maxpage) + pages_middle = listmiddle->add_pages(); } neighptr_middle = &pages_middle[npage_middle][npnt_middle]; n_middle = 0; @@ -472,10 +572,11 @@ void Neighbor::respa_bin_newton() if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; } jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -492,7 +593,8 @@ void Neighbor::respa_bin_newton() else if (which > 0) neighptr_inner[n_inner++] = which*nall + j; } - if (respa == 2 && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { if (which == 0) neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = which*nall + j; } @@ -504,9 +606,9 @@ void Neighbor::respa_bin_newton() ibin = coord2bin(x[i]); for (k = 0; k < nstencil; k++) { for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type,mask,molecule)) continue; - jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -523,7 +625,8 @@ void Neighbor::respa_bin_newton() else if (which > 0) neighptr_inner[n_inner++] = which*nall + j; } - if (respa == 2 && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { if (which == 0) neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = which*nall + j; } @@ -531,8 +634,10 @@ void Neighbor::respa_bin_newton() } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); @@ -543,7 +648,7 @@ void Neighbor::respa_bin_newton() if (npnt_inner >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); - if (respa == 2) { + if (respamiddle) { firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; npnt_middle += n_middle; @@ -551,6 +656,8 @@ void Neighbor::respa_bin_newton() error->one("Neighbor list overflow, boost neigh_modify one or page"); } } + + list->inum = inum; } /* ---------------------------------------------------------------------- @@ -560,14 +667,11 @@ void Neighbor::respa_bin_newton() every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -void Neighbor::respa_bin_newton_tri() +void Neighbor::respa_bin_newton_tri(NeighList *list) { - int i,j,k,itype,jtype,ibin,which; - int n_inner,n_middle,n; + int i,j,k,n,itype,jtype,ibin,which,n_inner,n_middle; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr_inner; - int *neighptr_middle; - int *neighptr; + int *neighptr,*neighptr_inner,*neighptr_middle; // bin local & ghost atoms @@ -583,6 +687,29 @@ void Neighbor::respa_bin_newton_tri() int nall = atom->nlocal + atom->nghost; int molecular = atom->molecular; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int **pages = list->pages; + int nstencil = list->nstencil; + int *stencil = list->stencil; + + NeighList *listinner = list->listinner; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + int **pages_inner = listinner->pages; + + NeighList *listmiddle; + int *numneigh_middle,**firstneigh_middle,**pages_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + pages_middle = listmiddle->pages; + } + + int inum = 0; int npage = 0; int npnt = 0; int npage_inner = 0; @@ -595,7 +722,7 @@ void Neighbor::respa_bin_newton_tri() if (pgsize - npnt < oneatom) { npnt = 0; npage++; - if (npage == maxpage) add_pages(npage); + if (npage == list->maxpage) pages = list->add_pages(); } neighptr = &pages[npage][npnt]; n = 0; @@ -603,16 +730,18 @@ void Neighbor::respa_bin_newton_tri() if (pgsize - npnt_inner < oneatom) { npnt_inner = 0; npage_inner++; - if (npage_inner == maxpage_inner) add_pages_inner(npage_inner); + if (npage_inner == listinner->maxpage) + pages_inner = listinner->add_pages(); } neighptr_inner = &pages_inner[npage_inner][npnt_inner]; n_inner = 0; - if (respa == 2) { + if (respamiddle) { if (pgsize - npnt_middle < oneatom) { npnt_middle = 0; npage_middle++; - if (npage_middle == maxpage_middle) add_pages_middle(npage_middle); + if (npage_middle == listmiddle->maxpage) + pages_middle = listmiddle->add_pages(); } neighptr_middle = &pages_middle[npage_middle][npnt_middle]; n_middle = 0; @@ -634,9 +763,10 @@ void Neighbor::respa_bin_newton_tri() if (x[j][2] < ztmp) continue; if (x[j][2] == ztmp && x[j][1] < ytmp) continue; if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] <= xtmp) continue; - if (exclude && exclusion(i,j,type,mask,molecule)) continue; jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; @@ -653,7 +783,8 @@ void Neighbor::respa_bin_newton_tri() else if (which > 0) neighptr_inner[n_inner++] = which*nall + j; } - if (respa == 2 && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { if (which == 0) neighptr_middle[n_middle++] = j; else if (which > 0) neighptr_middle[n_middle++] = which*nall + j; } @@ -661,8 +792,10 @@ void Neighbor::respa_bin_newton_tri() } } + ilist[inum] = i; firstneigh[i] = neighptr; numneigh[i] = n; + inum++; npnt += n; if (npnt >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); @@ -673,7 +806,7 @@ void Neighbor::respa_bin_newton_tri() if (npnt_inner >= pgsize) error->one("Neighbor list overflow, boost neigh_modify one or page"); - if (respa == 2) { + if (respamiddle) { firstneigh_middle[i] = neighptr_middle; numneigh_middle[i] = n_middle; npnt_middle += n_middle; @@ -681,4 +814,6 @@ void Neighbor::respa_bin_newton_tri() error->one("Neighbor list overflow, boost neigh_modify one or page"); } } + + list->inum = inum; } diff --git a/src/neigh_stencil.cpp b/src/neigh_stencil.cpp index 89f8895c27..7f2170a022 100644 --- a/src/neigh_stencil.cpp +++ b/src/neigh_stencil.cpp @@ -12,29 +12,29 @@ ------------------------------------------------------------------------- */ #include "neighbor.h" +#include "neigh_list.h" #include "atom.h" #include "memory.h" using namespace LAMMPS_NS; -enum{NSQ,BIN,MULTI}; // also in neighbor.cpp - /* ---------------------------------------------------------------------- routines to create a stencil = list of bin offsets stencil = bins whose closest corner to central bin is within cutoff sx,sy,sz = bin bounds = furthest the stencil could possibly extend 3d creates xyz stencil, 2d creates xy stencil - for half neigh list with partial Newton: + for half list with newton off: stencil is all surrounding bins stencil includes self - for half neigh list with full Newton: + regardless of triclinic + for half list with newton on: stencil is bins to the "upper right" of central bin stencil does not include self - for half neigh list with triclinic: + for half list with triclinic: stencil is all bins in z-plane of self and above, but not below in 2d is all bins in y-plane of self and above, but not below stencil includes self - for full neigh list: + for full list: stencil is all surrounding bins including self regardless of newton on/off or triclinic for multi: @@ -45,114 +45,157 @@ enum{NSQ,BIN,MULTI}; // also in neighbor.cpp /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_allocate(int sx, int sy, int sz) +void Neighbor::stencil_half_bin_2d_no_newton(NeighList *list, + int sx, int sy, int sz) { - int i; + int i,j; + int *stencil = list->stencil; + int nstencil = 0; - // for 2d, sz = 0 + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; - int nmax = (2*sz+1) * (2*sy+1) * (2*sx+1); - - if (half) { - if (style == BIN) { - if (nmax > maxstencil) { - maxstencil = nmax; - memory->sfree(stencil); - stencil = (int *) memory->smalloc(nmax*sizeof(int),"neigh:stencil"); - } - - } else { - int n = atom->ntypes; - if (nstencil_multi == NULL) { - 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++) { - nstencil_multi[i] = 0; - stencil_multi[i] = NULL; - distsq_multi[i] = NULL; - } - } - if (nmax > maxstencil_multi) { - maxstencil_multi = nmax; - for (int i = 1; i <= n; i++) { - memory->sfree(stencil_multi[i]); - memory->sfree(distsq_multi[i]); - stencil_multi[i] = (int *) - memory->smalloc(nmax*sizeof(int),"neigh:stencil_multi"); - distsq_multi[i] = (double *) memory->smalloc(nmax*sizeof(double), - "neigh:distsq_multi"); - } - } - } - } - - if (full) { - if (style == BIN) { - if (nmax > maxstencil_full) { - maxstencil_full = nmax; - memory->sfree(stencil_full); - stencil_full = (int *) memory->smalloc(nmax*sizeof(int), - "neigh:stencil_full"); - } - - } else { - int n = atom->ntypes; - if (nstencil_full_multi == NULL) { - maxstencil_full_multi = 0; - nstencil_full_multi = new int[n+1]; - stencil_full_multi = new int*[n+1]; - distsq_full_multi = new double*[n+1]; - for (i = 1; i <= n; i++) { - nstencil_full_multi[i] = 0; - stencil_full_multi[i] = NULL; - distsq_full_multi[i] = NULL; - } - } - if (nmax > maxstencil_full_multi) { - maxstencil_full_multi = nmax; - for (int i = 1; i <= n; i++) { - memory->sfree(stencil_full_multi[i]); - memory->sfree(distsq_full_multi[i]); - stencil_full_multi[i] = (int *) - memory->smalloc(nmax*sizeof(int),"neigh:stencil_full_multi"); - distsq_full_multi[i] = - (double *) memory->smalloc(nmax*sizeof(double), - "neigh:distsq_full_multi"); - } - } - } - } + list->nstencil = nstencil; } /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_none(int sx, int sy, int sz) {} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_3d_no_newton(int sx, int sy, int sz) +void Neighbor::stencil_half_bin_3d_no_newton(NeighList *list, + int sx, int sy, int sz) { int i,j,k; - nstencil = 0; + int *stencil = list->stencil; + int nstencil = 0; for (k = -sz; k <= sz; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance(i,j,k) < cutneighmaxsq) stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + + list->nstencil = nstencil; } /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_3d_no_newton_multi(int sx, int sy, int sz) +void Neighbor::stencil_half_bin_2d_newton(NeighList *list, + int sx, int sy, int sz) +{ + int i,j; + int *stencil = list->stencil; + int nstencil = 0; + + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (j > 0 || (j == 0 && i > 0)) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; + + list->nstencil = nstencil; +} + +/* ---------------------------------------------------------------------- */ + +void Neighbor::stencil_half_bin_3d_newton(NeighList *list, + int sx, int sy, int sz) +{ + int i,j,k; + int *stencil = list->stencil; + int nstencil = 0; + + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (k > 0 || j > 0 || (j == 0 && i > 0)) + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + + list->nstencil = nstencil; +} + +/* ---------------------------------------------------------------------- */ + +void Neighbor::stencil_half_bin_2d_newton_tri(NeighList *list, + int sx, int sy, int sz) +{ + int i,j; + int *stencil = list->stencil; + int nstencil = 0; + + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; + + list->nstencil = nstencil; +} + +/* ---------------------------------------------------------------------- */ + +void Neighbor::stencil_half_bin_3d_newton_tri(NeighList *list, + int sx, int sy, int sz) +{ + int i,j,k; + int *stencil = list->stencil; + int nstencil = 0; + + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + + list->nstencil = nstencil; +} + +/* ---------------------------------------------------------------------- */ + +void Neighbor::stencil_half_multi_2d_no_newton(NeighList *list, + int sx, int sy, int sz) +{ + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; + + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} + +/* ---------------------------------------------------------------------- */ + +void Neighbor::stencil_half_multi_3d_no_newton(NeighList *list, + int sx, int sy, int sz) { int i,j,k,n; double rsq,typesq; int *s; double *distsq; + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + int ntypes = atom->ntypes; for (int itype = 1; itype <= ntypes; itype++) { typesq = cuttypesq[itype]; @@ -174,28 +217,51 @@ void Neighbor::stencil_half_3d_no_newton_multi(int sx, int sy, int sz) /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_3d_newton(int sx, int sy, int sz) +void Neighbor::stencil_half_multi_2d_newton(NeighList *list, + int sx, int sy, int sz) { - int i,j,k; - nstencil = 0; + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = 0; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + if (j > 0 || (j == 0 && i > 0)) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } } /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_3d_newton_multi(int sx, int sy, int sz) +void Neighbor::stencil_half_multi_3d_newton(NeighList *list, + int sx, int sy, int sz) { int i,j,k,n; double rsq,typesq; int *s; double *distsq; + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + int ntypes = atom->ntypes; for (int itype = 1; itype <= ntypes; itype++) { typesq = cuttypesq[itype]; @@ -218,27 +284,51 @@ void Neighbor::stencil_half_3d_newton_multi(int sx, int sy, int sz) /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_3d_newton_tri(int sx, int sy, int sz) +void Neighbor::stencil_half_multi_2d_newton_tri(NeighList *list, + int sx, int sy, int sz) { - int i,j,k; - nstencil = 0; + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } } + /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_3d_newton_multi_tri(int sx, int sy, int sz) +void Neighbor::stencil_half_multi_3d_newton_tri(NeighList *list, + int sx, int sy, int sz) { int i,j,k,n; double rsq,typesq; int *s; double *distsq; + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + int ntypes = atom->ntypes; for (int itype = 1; itype <= ntypes; itype++) { typesq = cuttypesq[itype]; @@ -260,154 +350,91 @@ void Neighbor::stencil_half_3d_newton_multi_tri(int sx, int sy, int sz) /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_2d_no_newton(int sx, int sy, int sz) +void Neighbor::stencil_full_bin_2d(NeighList *list, + int sx, int sy, int sz) { int i,j; - nstencil = 0; + int *stencil = list->stencil; + int nstencil = 0; for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance(i,j,0) < cutneighmaxsq) stencil[nstencil++] = j*mbinx + i; + + list->nstencil = nstencil; } /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_half_2d_no_newton_multi(int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_2d_newton(int sx, int sy, int sz) -{ - int i,j; - nstencil = 0; - - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_2d_newton_multi(int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_2d_newton_tri(int sx, int sy, int sz) -{ - int i,j; - nstencil = 0; - - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_2d_newton_multi_tri(int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_3d(int sx, int sy, int sz) +void Neighbor::stencil_full_bin_3d(NeighList *list, + int sx, int sy, int sz) { int i,j,k; - nstencil_full = 0; + int *stencil = list->stencil; + int nstencil = 0; for (k = -sz; k <= sz; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (bin_distance(i,j,k) < cutneighmaxsq) - stencil_full[nstencil_full++] = k*mbiny*mbinx + j*mbinx + i; + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + + list->nstencil = nstencil; +} + + +/* ---------------------------------------------------------------------- */ + +void Neighbor::stencil_full_multi_2d(NeighList *list, + int sx, int sy, int sz) +{ + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; + + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } } /* ---------------------------------------------------------------------- */ -void Neighbor::stencil_full_3d_multi(int sx, int sy, int sz) +void Neighbor::stencil_full_multi_3d(NeighList *list, + int sx, int sy, int sz) { int i,j,k,n; double rsq,typesq; int *s; double *distsq; + int *nstencil_multi = list->nstencil_multi; + int **stencil_multi = list->stencil_multi; + double **distsq_multi = list->distsq_multi; + int ntypes = atom->ntypes; for (int itype = 1; itype <= ntypes; itype++) { typesq = cuttypesq[itype]; - s = stencil_full_multi[itype]; - distsq = distsq_full_multi[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; n = 0; for (k = -sz; k <= sz; k++) for (j = -sy; j <= sy; j++) @@ -418,46 +445,6 @@ void Neighbor::stencil_full_3d_multi(int sx, int sy, int sz) s[n++] = k*mbiny*mbinx + j*mbinx + i; } } - nstencil_full_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_2d(int sx, int sy, int sz) -{ - int i,j; - nstencil_full = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil_full[nstencil_full++] = j*mbinx + i; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_2d_multi(int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_full_multi[itype]; - distsq = distsq_full_multi[itype]; - n = 0; - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_full_multi[itype] = n; + nstencil_multi[itype] = n; } } diff --git a/src/neighbor.cpp b/src/neighbor.cpp index dc42db9d52..4e562b7aff 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -21,6 +21,8 @@ #include "string.h" #include "limits.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "atom.h" #include "atom_vec.h" #include "comm.h" @@ -39,17 +41,18 @@ using namespace LAMMPS_NS; -#define PGDELTA 1 +#define RQDELTA 1 +#define EXDELTA 1 + #define LB_FACTOR 1.5 #define SMALL 1.0e-6 -#define EXDELTA 1 #define BIG 1.0e20 #define CUT2BIN_RATIO 100 #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) -enum{NSQ,BIN,MULTI}; // also in neigh_stencil.cpp +enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp /* ---------------------------------------------------------------------- */ @@ -65,18 +68,23 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) pgsize = 10000; oneatom = 2000; - maxlocal = 0; - cutneighsq = NULL; cuttype = NULL; cuttypesq = NULL; fixchecklist = NULL; - // last neighbor info + // coords at last neighboring maxhold = 0; xhold = NULL; + // binning + + maxhead = 0; + binhead = NULL; + maxbin = 0; + bins = NULL; + // pair exclusion list info nex_type = maxex_type = 0; @@ -89,66 +97,24 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) nex_mol = maxex_mol = 0; ex_mol_group = ex_mol_bit = NULL; - // bin info + // pair lists - maxhead = 0; - binhead = NULL; - maxbin = 0; - bins = NULL; + maxlocal = 0; - nstencil = maxstencil = 0; - stencil = NULL; - nstencil_full = maxstencil_full = 0; - stencil_full = NULL; + nlist = 0; + lists = NULL; + pair_build = NULL; + stencil_create = NULL; + blist = glist = slist = NULL; - maxstencil_multi = 0; - nstencil_multi = NULL; - stencil_multi = NULL; - distsq_multi = NULL; + nrequest = maxrequest = 0; + requests = NULL; - maxstencil_full_multi = 0; - nstencil_full_multi = NULL; - stencil_full_multi = NULL; - distsq_full_multi = NULL; + old_style = BIN; + old_nrequest = 0; + old_requests = NULL; - // half neighbor list info - - half = half_command = 0; - numneigh = NULL; - firstneigh = NULL; - maxpage = 0; - pages = NULL; - - // full neighbor list info - - full = 0; - numneigh_full = NULL; - firstneigh_full = NULL; - maxpage_full = 0; - pages_full = NULL; - - // shear history neighbor list info - - fix_history = NULL; - firsttouch = NULL; - firstshear = NULL; - maxpage_history = 0; - pages_touch = NULL; - pages_shear = NULL; - - // multiple respa neighbor list info - - respa = 0; - numneigh_inner = NULL; - firstneigh_inner = NULL; - numneigh_middle = NULL; - firstneigh_middle = NULL; - maxpage_inner = 0; - maxpage_middle = 0; - pages_inner = NULL; - pages_middle = NULL; - - // bond list info + // bond lists maxbond = 0; bondlist = NULL; @@ -167,10 +133,13 @@ Neighbor::~Neighbor() memory->destroy_2d_double_array(cutneighsq); delete [] cuttype; delete [] cuttypesq; - delete [] fixchecklist; + memory->destroy_2d_double_array(xhold); + memory->sfree(binhead); + memory->sfree(bins); + memory->sfree(ex1_type); memory->sfree(ex2_type); memory->destroy_2d_int_array(ex_type); @@ -183,54 +152,23 @@ Neighbor::~Neighbor() memory->sfree(ex_mol_group); delete [] ex_mol_bit; - memory->sfree(binhead); - memory->sfree(bins); + for (int i = 0; i < nlist; i++) delete lists[i]; + delete [] lists; + delete [] pair_build; + delete [] stencil_create; + delete [] blist; + delete [] glist; + delete [] slist; - memory->sfree(stencil); - memory->sfree(stencil_full); - - if (nstencil_multi) { - for (int i = 1; i <= atom->ntypes; i++) { - memory->sfree(stencil_multi[i]); - memory->sfree(distsq_multi[i]); - } - delete [] nstencil_multi; - delete [] stencil_multi; - delete [] distsq_multi; - } - if (nstencil_full_multi) { - for (int i = 1; i <= atom->ntypes; i++) { - memory->sfree(stencil_full_multi[i]); - memory->sfree(distsq_full_multi[i]); - } - delete [] nstencil_full_multi; - delete [] stencil_full_multi; - delete [] distsq_full_multi; - } + for (int i = 0; i < nrequest; i++) delete requests[i]; + memory->sfree(requests); + for (int i = 0; i < old_nrequest; i++) delete old_requests[i]; + memory->sfree(old_requests); memory->destroy_2d_int_array(bondlist); memory->destroy_2d_int_array(anglelist); memory->destroy_2d_int_array(dihedrallist); memory->destroy_2d_int_array(improperlist); - - memory->sfree(numneigh); - memory->sfree(firstneigh); - clear_pages(); - - memory->sfree(numneigh_full); - memory->sfree(firstneigh_full); - clear_pages_full(); - - memory->sfree(firsttouch); - memory->sfree(firstshear); - clear_pages_history(); - - memory->sfree(numneigh_inner); - memory->sfree(firstneigh_inner); - memory->sfree(numneigh_middle); - memory->sfree(firstneigh_middle); - clear_pages_inner(); - clear_pages_middle(); } /* ---------------------------------------------------------------------- */ @@ -242,6 +180,7 @@ void Neighbor::init() ncalls = ndanger = 0; dimension = domain->dimension; triclinic = domain->triclinic; + newton_pair = force->newton_pair; // error check @@ -335,8 +274,23 @@ void Neighbor::init() if (force->kspace) special_flag[1] = special_flag[2] = special_flag[3] = 2; + // rRESPA cutoffs + + int respa = 0; + if (update->whichflag == 0 && strcmp(update->integrate_style,"respa") == 0) { + if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; + if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; + } + + if (respa) { + double *cut_respa = ((Respa *) update->integrate)->cutoff; + cut_inner_sq = (cut_respa[1] + skin) * (cut_respa[1] + skin); + cut_middle_sq = (cut_respa[3] + skin) * (cut_respa[3] + skin); + cut_middle_inside_sq = (cut_respa[0] - skin) * (cut_respa[0] - skin); + } + // ------------------------------------------------------------------ - // memory management + // xhold, bins, exclusion lists // free xhold and bins if not needed for this run @@ -349,9 +303,7 @@ void Neighbor::init() if (style == NSQ) { memory->sfree(bins); memory->sfree(binhead); - memory->sfree(stencil); - memory->sfree(stencil_full); - maxbin = maxhead = maxstencil = maxstencil_full = 0; + maxbin = maxhead = 0; binhead = NULL; bins = NULL; } @@ -417,252 +369,275 @@ void Neighbor::init() } // ------------------------------------------------------------------ - // neighbor list flags and memory allocation/deallocation + // pairwise lists - // determine whether to build half and full lists - // query pair,fix,compute for their requirements + // test if pairwise lists need to be re-created + // no need to re-create if: + // neigh style has not changed and current requests = old requests - half_once = full_once = 0; - half_every = full_every = 0; - if (force->pair) half_every = force->pair->neigh_half_every; - if (force->pair) full_every = force->pair->neigh_full_every; + int same = 1; + if (style != old_style) same = 0; + if (nrequest != old_nrequest) same = 0; + else + for (i = 0; i < nrequest; i++) + if (requests[i]->identical(old_requests[i]) == 0) same = 0; - for (i = 0; i < modify->nfix; i++) { - if (modify->fix[i]->neigh_half_every) half_every = 1; - if (modify->fix[i]->neigh_full_every) full_every = 1; - if (modify->fix[i]->neigh_half_once) half_once = 1; - if (modify->fix[i]->neigh_full_once) full_once = 1; - } + printf("SAME %d\n",same); - for (i = 0; i < modify->ncompute; i++) { - if (modify->compute[i]->neigh_half_once) half_once = 1; - if (modify->compute[i]->neigh_full_once) full_once = 1; - } + // if old and new are not the same, create new pairwise lists - half = full = 0; - if (half_every || half_once || half_command) half = 1; - if (full_every || full_once) full = 1; + if (!same) { - // determine whether to build granular history lists - // fix_history = granular shear history fix - - fix_history = NULL; - if (force->pair_match("gran/history") || force->pair_match("gran/hertzian")) - for (i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"SHEAR_HISTORY") == 0) - fix_history = (FixShearHistory *) modify->fix[i]; + // delete old lists and create new ones - // determine whether to build extra rRESPA lists - // respa = 1,2 if rRESPA requires inner,middle neighbor lists - // set neighbor cutoffs for multiple lists + for (i = 0; i < nlist; i++) delete lists[i]; + delete [] lists; + delete [] pair_build; + delete [] stencil_create; - respa = 0; - if (update->whichflag == 0 && strcmp(update->integrate_style,"respa") == 0) { - if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; - if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; - } + nlist = nrequest; + lists = new NeighList*[nlist]; + pair_build = new PairPtr[nlist]; + stencil_create = new StencilPtr[nlist]; - if (respa && half_every == 0) - error->all("Cannot use rRESPA with full neighbor lists"); + // create individual lists, one per request + // copy dnum setting from request to list + // pass list ptr back to requestor (except for Command class) - if (respa) { - double *cut_respa = ((Respa *) update->integrate)->cutoff; - cut_inner_sq = (cut_respa[1] + skin) * (cut_respa[1] + skin); - cut_middle_sq = (cut_respa[3] + skin) * (cut_respa[3] + skin); - cut_middle_inside_sq = (cut_respa[0] - skin) * (cut_respa[0] - skin); - } + for (i = 0; i < nlist; i++) { + lists[i] = new NeighList(lmp,pgsize); + lists[i]->index = i; + lists[i]->dnum = requests[i]->dnum; - // zero atom-length numneigh and firstneigh arrays - // will be (re)allocated on first build() + if (requests[i]->pair) { + Pair *pair = (Pair *) requests[i]->requestor; + pair->init_list(requests[i]->id,lists[i]); + } else if (requests[i]->fix) { + Fix *fix = (Fix *) requests[i]->requestor; + fix->init_list(requests[i]->id,lists[i]); + } else if (requests[i]->compute) { + Compute *compute = (Compute *) requests[i]->requestor; + compute->init_list(requests[i]->id,lists[i]); + } + } - maxlocal = 0; + // detect lists that are connected to other lists + // skip: point this list at request->otherlist, copy skip ptrs from request + // copy: point this list at request->otherlist + // half_from_full: point this list at preceeding full list + // granhistory: set preceeding list's listgranhistory to this list + // also set precedding list's ptr to FixShearHistory + // respaouter: point this list at preceeding 1/2 inner/middle lists + // pair and half and non-skip: if there is a pair full non-skip list, + // change this list to half_from_full and point at the full list + // fix/compute requests: + // kind of request = half or full + // occasional or not doesn't matter + // if non-skip pair list of same kind exists, become copy of that list + // else if request is half and non-skip pair full exists, + // become half_from_full of that list + // else do nothing and the fix/compute list will be built directly - memory->sfree(numneigh); - memory->sfree(firstneigh); - memory->sfree(numneigh_full); - memory->sfree(firstneigh_full); - memory->sfree(firsttouch); - memory->sfree(firstshear); - memory->sfree(numneigh_inner); - memory->sfree(firstneigh_inner); - memory->sfree(numneigh_middle); - memory->sfree(firstneigh_middle); + for (i = 0; i < nlist; i++) { + if (requests[i]->skip) { + lists[i]->listskip = lists[requests[i]->otherlist]; + lists[i]->iskip = requests[i]->iskip; + lists[i]->ijskip = requests[i]->ijskip; + } - numneigh = numneigh_full = numneigh_inner = numneigh_middle = NULL; - firstneigh = firstneigh_full = NULL; - firsttouch = NULL; - firstshear = NULL; - firstneigh_inner = firstneigh_middle = NULL; + if (requests[i]->copy) + lists[i]->listcopy = lists[requests[i]->otherlist]; - // clear old neighbor lists if no longer needed (whether exist or not) + if (requests[i]->half_from_full) lists[i]->listfull = lists[i-1]; - if (half == 0) clear_pages(); - if (full == 0) clear_pages_full(); - if (fix_history == NULL) clear_pages_history(); - if (respa == 0) clear_pages_inner(); - if (respa == 0 || respa == 1) clear_pages_middle(); + if (requests[i]->granhistory) { + lists[i-1]->listgranhistory = lists[i]; + for (int ifix = 0; ifix < modify->nfix; ifix++) + if (strcmp(modify->fix[ifix]->style,"SHEAR_HISTORY") == 0) + lists[i-1]->fix_history = (FixShearHistory *) modify->fix[ifix]; + } - // setup new neighbor lists - // only if they don't exist so memory will persist from run to run - - if (half && pages == NULL) add_pages(0); - if (full && pages_full == NULL) add_pages_full(0); - if (fix_history && pages_touch == NULL) add_pages_history(0); - if (respa >= 1 && pages_inner == NULL) add_pages_inner(0); - if (respa == 2 && pages_middle == NULL) add_pages_middle(0); - - // set ptrs to half/full/multi/triclinic build & stencil functions - - if (half) { - if (fix_history) { - if (style == NSQ) { - if (force->newton_pair == 0) - half_build = &Neighbor::granular_nsq_no_newton; - else half_build = &Neighbor::granular_nsq_newton; - } else if (style == BIN) { - if (force->newton_pair == 0) { - half_build = &Neighbor::granular_bin_no_newton; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_no_newton; - else - half_stencil = &Neighbor::stencil_half_2d_no_newton; - } else if (triclinic) { - half_build = &Neighbor::granular_bin_newton_tri; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton_tri; - else - half_stencil = &Neighbor::stencil_half_2d_newton_tri; + if (requests[i]->respaouter) { + if (requests[i-1]->respainner) { + lists[i]->respamiddle = 0; + lists[i]->listinner = lists[i-1]; } else { - half_build = &Neighbor::granular_bin_newton; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton; - else - half_stencil = &Neighbor::stencil_half_2d_newton; + lists[i]->respamiddle = 1; + lists[i]->listmiddle = lists[i-1]; + lists[i]->listinner = lists[i-2]; } - } else error->all("Neighbor multi not allowed with granular"); + } - } else if (respa) { - if (style == NSQ) { - if (force->newton_pair == 0) - half_build = &Neighbor::respa_nsq_no_newton; - else half_build = &Neighbor::respa_nsq_newton; - } else if (style == BIN) { - if (force->newton_pair == 0) { - half_build = &Neighbor::respa_bin_no_newton; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_no_newton; - else - half_stencil = &Neighbor::stencil_half_2d_no_newton; - } else if (triclinic) { - half_build = &Neighbor::respa_bin_newton_tri; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton_tri; - else - half_stencil = &Neighbor::stencil_half_2d_newton_tri; - } else { - half_build = &Neighbor::respa_bin_newton; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton; - else - half_stencil = &Neighbor::stencil_half_2d_newton; + if (requests[i]->pair && requests[i]->half && requests[i]->skip == 0) { + for (j = 0; j < nlist; j++) + if (requests[i]->pair && requests[j]->full && + requests[j]->skip == 0) break; + if (j < nlist) { + requests[i]->half = 0; + requests[i]->half_from_full = 1; + lists[i]->listfull = lists[j]; } - } else error->all("Neighbor multi not allowed with rRESPA"); + } - } else { - if (style == NSQ) { - if (force->newton_pair == 0) { - if (full_every) half_build = &Neighbor::half_full_no_newton; - else half_build = &Neighbor::half_nsq_no_newton; - } else { - if (full_every) half_build = &Neighbor::half_full_newton; - else half_build = &Neighbor::half_nsq_newton; + if (requests[i]->fix || requests[i]->compute) { + for (j = 0; j < nlist; j++) { + if (requests[j]->pair && requests[j]->skip == 0 && + requests[j]->half && requests[i]->half) break; + if (requests[j]->pair && requests[j]->skip == 0 && + requests[j]->full && requests[i]->full) break; } - } else if (style == BIN) { - if (force->newton_pair == 0) { - if (full_every) { - half_build = &Neighbor::half_full_no_newton; - half_stencil = &Neighbor::stencil_none; - } else { - half_build = &Neighbor::half_bin_no_newton; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_no_newton; - else - half_stencil = &Neighbor::stencil_half_2d_no_newton; + if (j < nlist) { + requests[i]->copy = 1; + lists[i]->listcopy = lists[j]; + } else { + for (j = 0; j < nlist; j++) { + if (requests[j]->pair && requests[j]->skip == 0 && + requests[j]->full && requests[i]->half) break; } - } else { - if (full_every) { - half_build = &Neighbor::half_full_newton; - half_stencil = &Neighbor::stencil_none; - } else if (triclinic) { - half_build = &Neighbor::half_bin_newton_tri; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton_tri; - else - half_stencil = &Neighbor::stencil_half_2d_newton_tri; - } else { - half_build = &Neighbor::half_bin_newton; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton; - else - half_stencil = &Neighbor::stencil_half_2d_newton; - } - } - } else if (style == MULTI) { - if (force->newton_pair == 0) { - if (full_every) { - half_build = &Neighbor::half_full_no_newton; - half_stencil = &Neighbor::stencil_none; - } else { - half_build = &Neighbor::half_bin_no_newton_multi; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_no_newton_multi; - else - half_stencil = &Neighbor::stencil_half_2d_no_newton_multi; - } - } else { - if (full_every) { - half_build = &Neighbor::half_full_newton; - half_stencil = &Neighbor::stencil_none; - } else if (triclinic) { - half_build = &Neighbor::half_bin_newton_multi_tri; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton_multi_tri; - else - half_stencil = &Neighbor::stencil_half_2d_newton_multi_tri; - } else { - half_build = &Neighbor::half_bin_newton_multi; - if (dimension == 3) - half_stencil = &Neighbor::stencil_half_3d_newton_multi; - else - half_stencil = &Neighbor::stencil_half_2d_newton_multi; + if (j < nlist) { + requests[i]->half = 0; + requests[i]->half_from_full = 1; + lists[i]->listfull = lists[j]; } } } } - } else half_build = NULL; + // set ptrs to pair_build and stencil_create functions for each list + // ptrs set to NULL if not set explicitly - if (full) { - if (style == NSQ) full_build = &Neighbor::full_nsq; - else if (style == BIN) { - full_build = &Neighbor::full_bin; - if (dimension == 3) - full_stencil = &Neighbor::stencil_full_3d; - else - full_stencil = &Neighbor::stencil_full_2d; - } else { - full_build = &Neighbor::full_bin_multi; - if (dimension == 3) - full_stencil = &Neighbor::stencil_full_3d_multi; - else - full_stencil = &Neighbor::stencil_full_2d_multi; + for (i = 0; i < nlist; i++) { + choose_build(i,requests[i]); + if (style != NSQ) choose_stencil(i,requests[i]); + else stencil_create[i] = NULL; } - } else full_build = NULL; + + // set each list's build/grow/stencil flags based on neigh request + // buildflag = 1 if its pair_build() invoked every reneighbor + // growflag = 1 if it stores atom-based arrays and pages + // stencilflag = 1 if it stores stencil arrays + + for (i = 0; i < nlist; i++) { + lists[i]->buildflag = 1; + if (pair_build[i] == NULL) lists[i]->buildflag = 0; + if (requests[i]->occasional) lists[i]->buildflag = 0; + + lists[i]->growflag = 1; + if (requests[i]->copy) lists[i]->growflag = 0; + + lists[i]->stencilflag = 1; + if (style == NSQ) lists[i]->stencilflag = 0; + if (stencil_create[i] == NULL) lists[i]->stencilflag = 0; + } + + // DEBUG: print list attributes + + for (i = 0; i < nlist; i++) lists[i]->print_attributes(); + + // allocate atom arrays and 1st pages of lists that store them + + for (i = 0; i < nlist; i++) + if (lists[i]->growflag) { + lists[i]->grow(maxlocal); + lists[i]->add_pages(); + } + + // setup 3 vectors of pairwise neighbor lists + // blist = lists whose pair_build() is invoked every reneighbor + // glist = lists who store atom arrays which are used every reneighbor + // slist = lists who store stencil arrays which are used every reneighbor + // blist and glist vectors are used by neighbor::build() + // slist vector is used by neighbor::setup_bins() + + nblist = nglist = nslist = 0; + delete [] blist; + delete [] glist; + delete [] slist; + blist = new int[nlist]; + glist = new int[nlist]; + slist = new int[nlist]; + + for (i = 0; i < nlist; i++) { + if (lists[i]->buildflag) blist[nblist++] = i; + if (lists[i]->growflag && requests[i]->occasional == 0) + glist[nglist++] = i; + if (lists[i]->stencilflag && requests[i]->occasional == 0) + slist[nslist++] = i; + } + + // DEBUG: print lists of lists + + if (comm->me == 0) { + printf("Build lists = %d: ",nblist); + for (i = 0; i < nblist; i++) printf("%d ",blist[i]); + printf("\n"); + printf("Grow lists = %d: ",nglist); + for (i = 0; i < nglist; i++) printf("%d ",glist[i]); + printf("\n"); + printf("Stencil lists = %d: ",nslist); + for (i = 0; i < nslist; i++) printf("%d ",slist[i]); + printf("\n"); + } + + // reorder build vector if necessary + // relevant for lists that copy/skip/half-full from parent + // the derived lst must appear in blist after the parent list + // no occasional lists are in build vector + // swap two lists within blist when dependency is mis-ordered + // done when entire pass thru blist results in no swaps + + int done = 0; + while (!done) { + done = 1; + for (i = 0; i < nblist; i++) { + NeighList *ptr = NULL; + if (lists[blist[i]]->listfull) ptr = lists[blist[i]]->listfull; + if (lists[blist[i]]->listcopy) ptr = lists[blist[i]]->listcopy; + if (lists[blist[i]]->listskip) ptr = lists[blist[i]]->listskip; + if (ptr == NULL) continue; + for (m = 0; m < nlist; m++) + if (ptr == lists[m]) break; + for (j = 0; j < nblist; j++) + if (m == blist[j]) break; + if (j < i) continue; + int tmp = blist[i]; + blist[i] = blist[j]; + blist[j] = tmp; + done = 0; + break; + } + } + + // DEBUG: print lists of lists + + if (comm->me == 0) { + printf("Build lists = %d: ",nblist); + for (i = 0; i < nblist; i++) printf("%d ",blist[i]); + printf("\n"); + printf("Grow lists = %d: ",nglist); + for (i = 0; i < nglist; i++) printf("%d ",glist[i]); + printf("\n"); + printf("Stencil lists = %d: ",nslist); + for (i = 0; i < nslist; i++) printf("%d ",slist[i]); + printf("\n"); + } + } + + // delete old requests + // copy current requests and style to old for next run + + for (i = 0; i < old_nrequest; i++) delete old_requests[i]; + memory->sfree(old_requests); + old_nrequest = nrequest; + old_requests = requests; + nrequest = maxrequest = 0; + requests = NULL; + old_style = style; // ------------------------------------------------------------------ - // bond neighbor lists + // topology lists - // 1st time allocation of bond lists + // 1st time allocation of topology lists if (atom->molecular && atom->nbonds && maxbond == 0) { if (nprocs == 1) maxbond = atom->nbonds; @@ -692,7 +667,7 @@ void Neighbor::init() memory->create_2d_int_array(maximproper,5,"neigh:improperlist"); } - // set flags that determine which bond neighboring routines to use + // set flags that determine which topology neighboring routines to use // SHAKE sets bonds and angles negative // bond_quartic sets bonds to 0 // delete_bonds sets all interactions negative @@ -738,7 +713,7 @@ void Neighbor::init() } } - // set ptrs to intra-molecular build functions + // set ptrs to topology build functions if (bond_off) bond_build = &Neighbor::bond_partial; else bond_build = &Neighbor::bond_all; @@ -752,7 +727,7 @@ void Neighbor::init() if (improper_off) improper_build = &Neighbor::improper_partial; else improper_build = &Neighbor::improper_all; - // set intra-molecular neighbor list counts to 0 + // set topology neighbor list counts to 0 // in case all are turned off but potential is still defined nbondlist = nanglelist = ndihedrallist = nimproperlist = 0; @@ -760,6 +735,149 @@ void Neighbor::init() /* ---------------------------------------------------------------------- */ +int Neighbor::request(void *requestor) +{ + if (nrequest == maxrequest) { + maxrequest += RQDELTA; + requests = (NeighRequest **) + memory->srealloc(requests,maxrequest*sizeof(NeighRequest *), + "neighbor:requests"); + } + + requests[nrequest] = new NeighRequest(lmp); + requests[nrequest]->requestor = requestor; + nrequest++; + return nrequest-1; +} + + +/* ---------------------------------------------------------------------- + determine which pair_build function each neigh list needs + based on settings of neigh request + skip or copy -> single function + half_from_full, half, full, gran, respaouter -> choose by newton and tri + style NSQ options = newton off, newton on + style BIN options = newton off, newton on and not tri, newton on and tri + stlye MULTI options = same options as BIN + if none of these, ptr = NULL since pair_build is not invoked for this list + use "else if" b/c skip,copy can be set in addition to half,full,etc +------------------------------------------------------------------------- */ + +void Neighbor::choose_build(int index, NeighRequest *rq) +{ + PairPtr pb = NULL; + + if (rq->skip) pb = &Neighbor::skip_from; + + else if (rq->copy) pb = &Neighbor::copy_from; + + else if (rq->half_from_full) { + if (newton_pair == 0) pb = &Neighbor::half_full_no_newton; + else if (newton_pair == 1) pb = &Neighbor::half_full_newton; + + } else if (rq->half) { + if (style == NSQ) { + if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton; + else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton; + } else if (style == BIN) { + 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 (style == MULTI) { + 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->full) { + if (style == NSQ) pb = &Neighbor::full_nsq; + else if (style == BIN) pb = &Neighbor::full_bin; + else if (style == MULTI) pb = &Neighbor::full_multi; + + } 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("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("Neighbor multi not yet enabled for rRESPA"); + } + + pair_build[index] = pb; +} + +/* ---------------------------------------------------------------------- + determine which stencil_create function each neigh list needs + based on settings of neigh request, only called if style != NSQ + skip or copy or half_from_full -> no stencil + half, gran, respaouter, full -> choose by newton and tri and dimension + if none of these, ptr = NULL since this list needs no stencils + use "else if" b/c skip,copy can be set in addition to half,full,etc +------------------------------------------------------------------------- */ + +void Neighbor::choose_stencil(int index, NeighRequest *rq) +{ + StencilPtr sc = NULL; + + if (rq->skip || rq->copy || rq->half_from_full) sc = NULL; + + else if (rq->half || rq->gran || rq->respaouter) { + if (style == BIN) { + if (newton_pair == 0) { + if (dimension == 2) sc = &Neighbor::stencil_half_bin_2d_no_newton; + else if (dimension == 3) sc = &Neighbor::stencil_half_bin_3d_no_newton; + } else if (triclinic == 0) { + if (dimension == 2) sc = &Neighbor::stencil_half_bin_2d_newton; + else if (dimension == 3) sc = &Neighbor::stencil_half_bin_3d_newton; + } else if (triclinic == 1) { + if (dimension == 2) sc = &Neighbor::stencil_half_bin_2d_newton_tri; + else if (dimension == 3) + sc = &Neighbor::stencil_half_bin_3d_newton_tri; + } + } else if (style == MULTI) { + if (newton_pair == 0) { + if (dimension == 2) sc = &Neighbor::stencil_half_multi_2d_no_newton; + else if (dimension == 3) + sc = &Neighbor::stencil_half_multi_3d_no_newton; + } else if (triclinic == 0) { + if (dimension == 2) sc = &Neighbor::stencil_half_multi_2d_newton; + else if (dimension == 3) sc = &Neighbor::stencil_half_multi_3d_newton; + } else if (triclinic == 1) { + if (dimension == 2) sc = &Neighbor::stencil_half_multi_2d_newton_tri; + else if (dimension == 3) + sc = &Neighbor::stencil_half_multi_3d_newton_tri; + } + } + + } else if (rq->full) { + if (style == BIN) { + if (dimension == 2) sc = &Neighbor::stencil_full_bin_2d; + else if (dimension == 3) sc = &Neighbor::stencil_full_bin_3d; + } else if (style == MULTI) { + if (dimension == 2) sc = &Neighbor::stencil_full_multi_2d; + else if (dimension == 3) sc = &Neighbor::stencil_full_multi_3d; + } + } + + stencil_create[index] = sc; +} + +/* ---------------------------------------------------------------------- */ + int Neighbor::decide() { if (must_check) { @@ -800,19 +918,17 @@ int Neighbor::check_distance() } /* ---------------------------------------------------------------------- - build all needed neighbor lists every few timesteps - half, full, bond lists are created as needed + build all perpetual neighbor lists every few timesteps + pairwise & topology lists are created as needed ------------------------------------------------------------------------- */ void Neighbor::build() { + int i; + ago = 0; ncalls++; - // store current nlocal used on this build (used by fix shear/history) - - nlocal_neighbor = atom->nlocal; - // store current atom positions if needed if (dist_check) { @@ -823,66 +939,22 @@ void Neighbor::build() memory->destroy_2d_double_array(xhold); xhold = memory->create_2d_double_array(maxhold,3,"neigh:xhold"); } - for (int i = 0; i < nlocal; i++) { + for (i = 0; i < nlocal; i++) { xhold[i][0] = x[i][0]; xhold[i][1] = x[i][1]; xhold[i][2] = x[i][2]; } } - // extend atom arrays if necessary - // check half/full instead of half_every/full_every so memory will be - // allocated correctly whenever build_half() and build_full() are called + // if necessary, extend atom arrays in pairwise lists + // only done for lists with growflag set which are used every reneighbor if (atom->nlocal > maxlocal) { maxlocal = atom->nmax; - - if (half) { - memory->sfree(numneigh); - memory->sfree(firstneigh); - numneigh = (int *) - memory->smalloc(maxlocal*sizeof(int),"neigh:numneigh"); - firstneigh = (int **) - memory->smalloc(maxlocal*sizeof(int *),"neigh:firstneigh"); - } - - if (full) { - memory->sfree(numneigh_full); - memory->sfree(firstneigh_full); - numneigh_full = (int *) - memory->smalloc(maxlocal*sizeof(int),"neigh:numneigh_full"); - firstneigh_full = (int **) - memory->smalloc(maxlocal*sizeof(int *),"neigh:firstneigh_full"); - } - - if (fix_history) { - memory->sfree(firsttouch); - memory->sfree(firstshear); - firsttouch = (int **) - memory->smalloc(maxlocal*sizeof(int *),"neigh:firsttouch"); - firstshear = (double **) - memory->smalloc(maxlocal*sizeof(double *),"neigh:firstshear"); - } - - if (respa) { - memory->sfree(numneigh_inner); - memory->sfree(firstneigh_inner); - numneigh_inner = (int *) - memory->smalloc(maxlocal*sizeof(int),"neigh:numneigh_inner"); - firstneigh_inner = (int **) - memory->smalloc(maxlocal*sizeof(int *),"neigh:firstneigh_inner"); - if (respa == 2) { - memory->sfree(numneigh_middle); - memory->sfree(firstneigh_middle); - numneigh_middle = (int *) - memory->smalloc(maxlocal*sizeof(int),"neigh:numneigh_middle"); - firstneigh_middle = (int **) - memory->smalloc(maxlocal*sizeof(int *),"neigh:firstneigh_middle"); - } - } + for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxlocal); } - // extend bin list if necessary + // extend atom bin list if necessary if (style != NSQ && atom->nmax > maxbin) { maxbin = atom->nmax; @@ -890,11 +962,22 @@ void Neighbor::build() bins = (int *) memory->smalloc(maxbin*sizeof(int),"bins"); } - // list construction for pairs and bonds - // full comes first in case half is built from full + // invoke building of pair and molecular neighbor lists + // only done for pairwise lists with buildflag set - if (full_every) (this->*full_build)(); - if (half_every) (this->*half_build)(); + for (i = 0; i < nblist; i++) + (this->*pair_build[blist[i]])(lists[blist[i]]); + + /* + if (comm->me == 0) { + for (int m = 0; m < nlist; m++) { + int num = 0; + for (i = 0; i < lists[m]->inum; i++) + num += lists[m]->numneigh[lists[m]->ilist[i]]; + printf("List %d length = %d\n",m,num); + } + } + */ if (atom->molecular) { if (atom->nbonds) (this->*bond_build)(); @@ -905,21 +988,21 @@ void Neighbor::build() } /* ---------------------------------------------------------------------- - one-time call to build a half neighbor list made by other classes + build a single non-active pairwise neighbor list indexed by I + called by other classes when needed occasionally ------------------------------------------------------------------------- */ -void Neighbor::build_half() +void Neighbor::build_one(int i) { - (this->*half_build)(); -} + // grow atom arrays and update stencils depending on growflag & stencilflag -/* ---------------------------------------------------------------------- - one-time call to build a full neighbor list made by other classes -------------------------------------------------------------------------- */ + if (lists[i]->growflag) lists[i]->grow(maxlocal); + if (lists[i]->stencilflag) { + lists[i]->stencil_allocate(smax,style); + (this->*stencil_create[i])(lists[i],sx,sy,sz); + } -void Neighbor::build_full() -{ - (this->*full_build)(); + (this->*pair_build[i])(lists[i]); } /* ---------------------------------------------------------------------- @@ -941,8 +1024,6 @@ void Neighbor::build_full() mbinlo = lowest global bin any of my ghost atoms could fall into mbinhi = highest global bin any of my ghost atoms could fall into mbin = number of bins I need in a dimension - stencil() = bin offsets in 1d sense for stencil of surrounding bins - stencil_full() = bin offsets in 1d sense for stencil for full neighbor list ------------------------------------------------------------------------- */ void Neighbor::setup_bins() @@ -1089,23 +1170,25 @@ void Neighbor::setup_bins() // create stencil of bins to search over in neighbor list construction // sx,sy,sz = max range of stencil extent + // smax = // stencil is empty if cutneighmax = 0.0 - int sx = static_cast (cutneighmax*bininvx); + sx = static_cast (cutneighmax*bininvx); if (sx*binsizex < cutneighmax) sx++; - int sy = static_cast (cutneighmax*bininvy); + sy = static_cast (cutneighmax*bininvy); if (sy*binsizey < cutneighmax) sy++; - int sz = static_cast (cutneighmax*bininvz); + sz = static_cast (cutneighmax*bininvz); if (sz*binsizez < cutneighmax) sz++; if (dimension == 2) sz = 0; + smax = (2*sx+1) * (2*sy+1) * (2*sz+1); - // allocate stencil memory and create stencil(s) - // check half/full instead of half_every/full_every so stencils will be - // allocated correctly whenever build_half() and build_full() are called + // create stencils for pairwise neighbor lists + // only done for lists with stencilflag and buildflag set - stencil_allocate(sx,sy,sz); - if (half) (this->*half_stencil)(sx,sy,sz); - if (full) (this->*full_stencil)(sx,sy,sz); + for (int i = 0; i < nslist; i++) { + lists[slist[i]]->stencil_allocate(smax,style); + (this->*stencil_create[slist[i]])(lists[slist[i]],sx,sy,sz); + } } /* ---------------------------------------------------------------------- @@ -1218,7 +1301,7 @@ void Neighbor::modify_params(int narg, char **arg) } else if (strcmp(arg[iarg+1],"molecule") == 0) { if (iarg+3 > narg) error->all("Illegal neigh_modify command"); if (atom->molecular == 0) { - char *str = + char *str = (char *) "Must use molecular atom style with neigh_modify exclude molecule"; error->all(str); } @@ -1243,170 +1326,6 @@ void Neighbor::modify_params(int narg, char **arg) } } -/* ---------------------------------------------------------------------- - return # of bytes of allocated memory -------------------------------------------------------------------------- */ - -int Neighbor::memory_usage() -{ - int bytes = 0; - - bytes += maxhold*3 * sizeof(double); - - if (style == NSQ) { - bytes += maxbin * sizeof(int); - bytes += maxhead * sizeof(int); - bytes += maxstencil * sizeof(int); - bytes += maxstencil_full * sizeof(int); - } - - if (half) { - bytes += maxlocal * sizeof(int); - bytes += maxlocal * sizeof(int *); - bytes += maxpage*pgsize * sizeof(int); - } - - if (full) { - bytes += maxlocal * sizeof(int); - bytes += maxlocal * sizeof(int *); - bytes += maxpage_full*pgsize * sizeof(int); - } - - if (fix_history) { - bytes += maxlocal * sizeof(int *); - bytes += maxlocal * sizeof(double *); - bytes += maxpage_history*pgsize * sizeof(int); - bytes += maxpage_history*pgsize*3 * sizeof(double); - } - - if (respa) { - bytes += maxlocal * sizeof(int); - bytes += maxlocal * sizeof(int *); - bytes += maxpage_inner*pgsize * sizeof(int); - if (respa == 2) { - bytes += maxlocal * sizeof(int); - bytes += maxlocal * sizeof(int *); - bytes += maxpage_middle*pgsize * sizeof(int); - } - } - - bytes += maxbond*3 * sizeof(int); - bytes += maxangle*4 * sizeof(int); - bytes += maxdihedral*5 * sizeof(int); - bytes += maximproper*5 * sizeof(int); - - return bytes; -} - -/* ---------------------------------------------------------------------- - add pages to half/full/granular/rRESPA neighbor lists, starting at npage -------------------------------------------------------------------------- */ - -void Neighbor::add_pages(int npage) -{ - maxpage += PGDELTA; - pages = (int **) - memory->srealloc(pages,maxpage*sizeof(int *),"neigh:pages"); - for (int i = npage; i < maxpage; i++) - pages[i] = (int *) memory->smalloc(pgsize*sizeof(int),"neigh:pages[i]"); -} - -void Neighbor::add_pages_full(int npage) -{ - maxpage_full += PGDELTA; - pages_full = (int **) - memory->srealloc(pages_full,maxpage_full*sizeof(int *),"neigh:pages_full"); - for (int i = npage; i < maxpage_full; i++) - pages_full[i] = - (int *) memory->smalloc(pgsize*sizeof(int),"neigh:pages_full[i]"); -} - -void Neighbor::add_pages_history(int npage) -{ - maxpage_history += PGDELTA; - pages_touch = (int **) - memory->srealloc(pages_touch,maxpage_history*sizeof(int *), - "neigh:pages_touch"); - pages_shear = (double **) - memory->srealloc(pages_shear,maxpage_history*sizeof(double *), - "neigh:pages_shear"); - for (int i = npage; i < maxpage_history; i++) { - pages_touch[i] = (int *) - memory->smalloc(pgsize*sizeof(int),"neigh:pages_touch[i]"); - pages_shear[i] = (double *) - memory->smalloc(3*pgsize*sizeof(double),"neigh:pages_shear[i]"); - } -} - -void Neighbor::add_pages_inner(int npage_inner) -{ - maxpage_inner += PGDELTA; - pages_inner = (int **) - memory->srealloc(pages_inner,maxpage_inner*sizeof(int *), - "neigh:pages_inner"); - for (int i = npage_inner; i < maxpage_inner; i++) - pages_inner[i] = - (int *) memory->smalloc(pgsize*sizeof(int),"neigh:pages_inner[i]"); -} - -void Neighbor::add_pages_middle(int npage_middle) -{ - maxpage_middle += PGDELTA; - pages_middle = (int **) - memory->srealloc(pages_middle,maxpage_middle*sizeof(int *), - "neigh:pages_middle"); - for (int i = npage_middle; i < maxpage_middle; i++) - pages_middle[i] = - (int *) memory->smalloc(pgsize*sizeof(int),"neigh:pages_middle[i]"); -} - -/* ---------------------------------------------------------------------- - clear half/full/granular/rRESPA neighbor lists -------------------------------------------------------------------------- */ - -void Neighbor::clear_pages() -{ - for (int i = 0; i < maxpage; i++) memory->sfree(pages[i]); - memory->sfree(pages); - pages = NULL; - maxpage = 0; -} - -void Neighbor::clear_pages_full() -{ - for (int i = 0; i < maxpage_full; i++) memory->sfree(pages_full[i]); - memory->sfree(pages_full); - pages_full = NULL; - maxpage_full = 0; -} - -void Neighbor::clear_pages_history() -{ - for (int i = 0; i < maxpage_history; i++) memory->sfree(pages_touch[i]); - for (int i = 0; i < maxpage_history; i++) memory->sfree(pages_shear[i]); - memory->sfree(pages_touch); - memory->sfree(pages_shear); - pages_touch = NULL; - pages_shear = NULL; - maxpage_history = 0; -} - -void Neighbor::clear_pages_inner() -{ - for (int i = 0; i < maxpage_inner; i++) memory->sfree(pages_inner[i]); - memory->sfree(pages_inner); - pages_inner = NULL; - maxpage_inner = 0; -} - -void Neighbor::clear_pages_middle() -{ - for (int i = 0; i < maxpage_middle; i++) memory->sfree(pages_middle[i]); - memory->sfree(pages_middle); - pages_middle = NULL; - maxpage_middle = 0; -} - /* ---------------------------------------------------------------------- determine if atom j is in special list of atom i if it is not, return 0 @@ -1526,11 +1445,12 @@ int Neighbor::coord2bin(double *x) return 1 if should be excluded, 0 if included ------------------------------------------------------------------------- */ -int Neighbor::exclusion(int i, int j, int *type, int *mask, int *molecule) +int Neighbor::exclusion(int i, int j, int itype, int jtype, + int *mask, int *molecule) { int m; - if (nex_type && ex_type[type[i]][type[j]]) return 1; + if (nex_type && ex_type[itype][jtype]) return 1; if (nex_group) { for (m = 0; m < nex_group; m++) { @@ -1547,3 +1467,28 @@ int Neighbor::exclusion(int i, int j, int *type, int *mask, int *molecule) return 0; } + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +int Neighbor::memory_usage() +{ + int bytes = 0; + + bytes += maxhold*3 * sizeof(double); + + if (style != NSQ) { + bytes += maxbin * sizeof(int); + bytes += maxhead * sizeof(int); + } + + for (int i = 0; i < nlist; i++) bytes += lists[i]->memory_usage(); + + bytes += maxbond*3 * sizeof(int); + bytes += maxangle*4 * sizeof(int); + bytes += maxdihedral*5 * sizeof(int); + bytes += maximproper*5 * sizeof(int); + + return bytes; +} diff --git a/src/neighbor.h b/src/neighbor.h index 4766f5cb2c..a4b8d2b8b7 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -20,7 +20,7 @@ namespace LAMMPS_NS { class Neighbor : protected Pointers { public: - int style; // 0 = nsq, 1 = binned + int style; // 0,1,2 = nsq, bin, multi int every; // build every this many steps int delay; // delay build for this many steps int dist_check; // 0 = always build, 1 = only if 1/2 dist @@ -34,54 +34,38 @@ class Neighbor : protected Pointers { int ncalls; // # of times build has been called int ndanger; // # of dangerous builds - int nlocal_neighbor; // nlocal at last build - int half; // 0/1 if half pair list ever built - int full; // 0/1 if full pair list ever built - int half_every; // 0/1 if half list built every step - int full_every; // 0/1 if full list built every step - int half_once; // 0/1 if half pair list built occasionally - int full_once; // 0/1 if full pair list built occasionally - int half_command; // 0/1 if command requires half list + int nrequest; // requests for pairwise neighbor lists + class NeighRequest **requests; // from Pair, Fix, Compute, Command classes + int maxrequest; - int *numneigh; // # of half neighbors for each atom - int **firstneigh; // ptr to 1st half neighbor of each atom - - int *numneigh_full; // # of full neighbors for each atom - int **firstneigh_full; // ptr to 1st full neighbor of each atom + int old_style; // previous run info to avoid + int old_nrequest; // re-creation of pairwise neighbor lists + class NeighRequest **old_requests; + + int nlist; // pairwise neighbor lists + class NeighList **lists; int nbondlist; // list of bonds to compute int **bondlist; - int nanglelist; // list of angles to compute int **anglelist; - int ndihedrallist; // list of dihedrals to compute int **dihedrallist; - int nimproperlist; // list of impropers to compute int **improperlist; - // granular neighbor list - int **firsttouch; // ptr to first touch flag for each atom - double **firstshear; // ptr to first shear values for each atom - - // rRESPA neighbor lists - int *numneigh_inner; // # of inner pair neighbors for each atom - int **firstneigh_inner; // ptr to inner 1st neigh of each atom - int *numneigh_middle; // # of middle pair neighbors for each atom - int **firstneigh_middle; // ptr to middle 1st neigh of each atom Neighbor(class LAMMPS *); ~Neighbor(); void init(); + int request(void *); // another class requests a neighbor list int decide(); // decide whether to build or not int check_distance(); // check max distance moved since last build void setup_bins(); // setup bins based on box and cutoff - void build(); // create all neighbor lists (half,full,bond) - void build_half(); // one-time creation of half neighbor list - void build_full(); // one-time creation of full neighbor list + void build(); // create all neighbor lists (pair,bond) + void build_one(int); // create a single neighbor list void set(int, char **); // set neighbor style and skin distance - void modify_params(int, char**); // modify parameters of neighbor build + void modify_params(int, char**); // modify parameters that control builds int memory_usage(); // tally memory usage private: @@ -120,55 +104,19 @@ class Neighbor : protected Pointers { double binsizex,binsizey,binsizez; // bin sizes and inverse sizes double bininvx,bininvy,bininvz; + int sx,sy,sz,smax; // bin stencil extents + int dimension; // 2/3 for 2d/3d int triclinic; // 0 if domain is orthog, 1 if triclinic + int newton_pair; // 0 if newton off, 1 if on for pairwise + double *bboxlo,*bboxhi; // copy of full domain bounding box - int nstencil; // # of bins in half neighbor stencil - int *stencil; // list of bin offsets - int maxstencil; // max size of stencil - - int nstencil_full; // # of bins in full neighbor stencil - int *stencil_full; // list of bin offsets - int maxstencil_full; // max size of stencil - - int *nstencil_multi; // # bins in each type-based multi stencil - int **stencil_multi; // list of bin offsets in each stencil - double **distsq_multi; // sq distances to bins in each stencil - int maxstencil_multi; // max sizes of stencils - - int *nstencil_full_multi; // # bins in full type-based multi stencil - int **stencil_full_multi; // list of bin offsets in each stencil - double **distsq_full_multi; // sq distances to bins in each stencil - int maxstencil_full_multi; // max sizes of stencils - - int **pages; // half neighbor list pages - int maxpage; // # of half pages currently allocated - - int **pages_full; // full neighbor list pages - int maxpage_full; // # of full pages currently allocated - - // granular neighbor list - class FixShearHistory *fix_history; // NULL if history not needed - // else is ptr to fix shear history - int **pages_touch; // pages of touch flags - double **pages_shear; // pages of shear values - int maxpage_history; // # of history pages currently allocated - - // rRESPA neighbor lists - int respa; // 0 = single neighbor list - // 1 = additional inner list - // 2 = additional inner and middle list double inner[2],middle[2]; // rRESPA cutoffs for extra lists double cut_inner_sq; // outer cutoff for inner neighbor list double cut_middle_sq; // outer cutoff for middle neighbor list double cut_middle_inside_sq; // inner cutoff for middle neighbor list - int **pages_inner; // inner neighbor list pages - int maxpage_inner; // # of inner pages currently allocated - int **pages_middle; // middle neighbor list pages - int maxpage_middle; // # of middle pages currently allocated - int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors int exclude; // 0 if no type/group exclusions, 1 if yes @@ -188,100 +136,100 @@ class Neighbor : protected Pointers { int *ex_mol_group; // molecule group #'s to exclude int *ex_mol_bit; // molecule group bits to exclude - typedef void (Neighbor::*FnPtr)(); - FnPtr half_build; // ptr to half pair list functions - FnPtr full_build; // ptr to full pair list functions - - void half_nsq_no_newton(); // fns for half neighbor lists - void half_nsq_newton(); - - void half_bin_no_newton(); - void half_bin_no_newton_multi(); - void half_bin_newton(); - void half_bin_newton_multi(); - void half_bin_newton_tri(); - void half_bin_newton_multi_tri(); - - void half_full_no_newton(); - void half_full_newton(); - - void full_nsq(); // fns for full neighbor lists - void full_bin(); - void full_bin_multi(); - - void granular_nsq_no_newton(); // fns for granular neighbor lists - void granular_nsq_newton(); - void granular_bin_no_newton(); - void granular_bin_newton(); - void granular_bin_newton_tri(); - - void respa_nsq_no_newton(); // fns for respa neighbor lists - void respa_nsq_newton(); - void respa_bin_no_newton(); - void respa_bin_newton(); - void respa_bin_newton_tri(); - - FnPtr bond_build; // ptr to bond list functions - void bond_all(); // bond list with all bonds - void bond_partial(); // exclude certain bonds - - FnPtr angle_build; // ptr to angle list functions - void angle_all(); // angle list with all angles - void angle_partial(); // exclude certain angles - - FnPtr dihedral_build; // ptr to dihedral list functions - void dihedral_all(); // dihedral list with all dihedrals - void dihedral_partial(); // exclude certain dihedrals - - FnPtr improper_build; // ptr to improper list functions - void improper_all(); // improper list with all impropers - void improper_partial(); // exclude certain impropers - - void add_pages(int); // add neigh list pages - void add_pages_full(int); - void add_pages_history(int); - void add_pages_inner(int); - void add_pages_middle(int); - - void clear_pages(); // clear all neigh list pages - void clear_pages_full(); - void clear_pages_history(); - void clear_pages_inner(); - void clear_pages_middle(); + int nblist,nglist,nslist; // # of pairwise neigh lists of various kinds + int *blist; // lists to build every reneighboring + int *glist; // lists to grow atom arrays every reneigh + int *slist; // lists to grow stencil arrays every reneigh void bin_atoms(); // bin all atoms double bin_distance(int, int, int); // distance between binx int coord2bin(double *); // mapping atom coord to a bin int find_special(int, int); // look for special neighbor - int exclusion(int, int, int *, int *, int *); // test for pair exclusion + int exclusion(int, int, int, int, int *, int *); // test for pair exclusion + void choose_build(int, class NeighRequest *); + void choose_stencil(int, class NeighRequest *); - typedef void (Neighbor::*SFnPtr)(int, int, int); - SFnPtr half_stencil; // ptr to half stencil functions - SFnPtr full_stencil; // ptr to full stencil functions + // pairwise build functions - void stencil_allocate(int, int, int); + typedef void (Neighbor::*PairPtr)(class NeighList *); + PairPtr *pair_build; - void stencil_none(int, int, int); // fns for stencil creation + void half_nsq_no_newton(class NeighList *); + void half_nsq_newton(class NeighList *); - void stencil_half_3d_no_newton(int, int, int); - void stencil_half_3d_no_newton_multi(int, int, int); - void stencil_half_3d_newton(int, int, int); - void stencil_half_3d_newton_multi(int, int, int); - void stencil_half_3d_newton_tri(int, int, int); - void stencil_half_3d_newton_multi_tri(int, int, int); + void half_bin_no_newton(class NeighList *); + void half_bin_newton(class NeighList *); + void half_bin_newton_tri(class NeighList *); - void stencil_half_2d_no_newton(int, int, int); - void stencil_half_2d_no_newton_multi(int, int, int); - void stencil_half_2d_newton(int, int, int); - void stencil_half_2d_newton_multi(int, int, int); - void stencil_half_2d_newton_tri(int, int, int); - void stencil_half_2d_newton_multi_tri(int, int, int); + void half_multi_no_newton(class NeighList *); + void half_multi_newton(class NeighList *); + void half_multi_newton_tri(class NeighList *); - void stencil_full_3d(int, int, int); - void stencil_full_3d_multi(int, int, int); + void full_nsq(class NeighList *); + void full_bin(class NeighList *); + void full_multi(class NeighList *); + + void half_full_no_newton(class NeighList *); + void half_full_newton(class NeighList *); + void skip_from(class NeighList *); + void copy_from(class NeighList *); + + void granular_nsq_no_newton(class NeighList *); + void granular_nsq_newton(class NeighList *); + void granular_bin_no_newton(class NeighList *); + void granular_bin_newton(class NeighList *); + void granular_bin_newton_tri(class NeighList *); + + void respa_nsq_no_newton(class NeighList *); + void respa_nsq_newton(class NeighList *); + void respa_bin_no_newton(class NeighList *); + void respa_bin_newton(class NeighList *); + void respa_bin_newton_tri(class NeighList *); + + // pairwise stencil creation functions + + typedef void (Neighbor::*StencilPtr)(class NeighList *, int, int, int); + StencilPtr *stencil_create; + + void stencil_half_bin_2d_no_newton(class NeighList *, int, int, int); + void stencil_half_bin_3d_no_newton(class NeighList *, int, int, int); + void stencil_half_bin_2d_newton(class NeighList *, int, int, int); + void stencil_half_bin_3d_newton(class NeighList *, int, int, int); + void stencil_half_bin_2d_newton_tri(class NeighList *, int, int, int); + void stencil_half_bin_3d_newton_tri(class NeighList *, int, int, int); + + void stencil_half_multi_2d_no_newton(class NeighList *, int, int, int); + void stencil_half_multi_3d_no_newton(class NeighList *, int, int, int); + void stencil_half_multi_2d_newton(class NeighList *, int, int, int); + void stencil_half_multi_3d_newton(class NeighList *, int, int, int); + void stencil_half_multi_2d_newton_tri(class NeighList *, int, int, int); + void stencil_half_multi_3d_newton_tri(class NeighList *, int, int, int); + + void stencil_full_bin_2d(class NeighList *, int, int, int); + void stencil_full_bin_3d(class NeighList *, int, int, int); + void stencil_full_multi_2d(class NeighList *, int, int, int); + void stencil_full_multi_3d(class NeighList *, int, int, int); + + // topology build functions + + typedef void (Neighbor::*BondPtr)(); // ptrs to topology build functions + + BondPtr bond_build; // ptr to bond list functions + void bond_all(); // bond list with all bonds + void bond_partial(); // exclude certain bonds + + BondPtr angle_build; // ptr to angle list functions + void angle_all(); // angle list with all angles + void angle_partial(); // exclude certain angles + + BondPtr dihedral_build; // ptr to dihedral list functions + void dihedral_all(); // dihedral list with all dihedrals + void dihedral_partial(); // exclude certain dihedrals + + BondPtr improper_build; // ptr to improper list functions + void improper_all(); // improper list with all impropers + void improper_partial(); // exclude certain impropers - void stencil_full_2d(int, int, int); - void stencil_full_2d_multi(int, int, int); }; } diff --git a/src/output.cpp b/src/output.cpp index fd5d765c11..4e850d903a 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -49,21 +49,21 @@ Output::Output(LAMMPS *lmp) : Pointers(lmp) // create 2 default computes for temp and pressure char **newarg = new char*[4]; - newarg[0] = "thermo_temp"; - newarg[1] = "all"; - newarg[2] = "temp"; + newarg[0] = (char *) "thermo_temp"; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "temp"; modify->add_compute(3,newarg); - newarg[0] = "thermo_pressure"; - newarg[1] = "all"; - newarg[2] = "pressure"; - newarg[3] = "thermo_temp"; + newarg[0] = (char *) "thermo_pressure"; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "pressure"; + newarg[3] = (char *) "thermo_temp"; modify->add_compute(4,newarg); delete [] newarg; // create default Thermo class newarg = new char*[1]; - newarg[0] = "one"; + newarg[0] = (char *) "one"; thermo = new Thermo(lmp,1,newarg); delete [] newarg; diff --git a/src/pair.cpp b/src/pair.cpp index b7278c634b..02a9ec5762 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -25,6 +25,8 @@ #include "pair.h" #include "pair_soft.h" #include "atom.h" +#include "neighbor.h" +#include "neigh_list.h" #include "domain.h" #include "comm.h" #include "force.h" @@ -46,8 +48,6 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp) eng_vdwl = eng_coul = 0.0; comm_forward = comm_reverse = 0; - neigh_half_every = 1; - neigh_full_every = 0; single_enable = 1; respa_enable = 0; @@ -123,11 +123,21 @@ void Pair::init() error->warning("Using pair tail corrections with nonperiodic system"); if (!allocated) error->all("All pair coeffs are not set"); + + // I,I coeffs must be set + // init_one() will check if I,J is set explicitly or inferred by mixing + for (i = 1; i <= atom->ntypes; i++) if (setflag[i][i] == 0) error->all("All pair coeffs are not set"); + // style-specific initialization + init_style(); + // call init_one() for each I,J + // set cutsq for each I,J, used to neighbor + // cutforce = max of all I,J cutoffs + double cut; cutforce = 0.0; etail = ptail = 0.0; @@ -147,6 +157,29 @@ void Pair::init() } } +/* ---------------------------------------------------------------------- + init specific to a pair style + specific pair style can override this function + if needs its own error checks + if needs another kind of neighbor list + request default neighbor list = half list +------------------------------------------------------------------------- */ + +void Pair::init_style() +{ + int irequest = neighbor->request(this); +} + +/* ---------------------------------------------------------------------- + neighbor callback to inform pair style of neighbor list to use + specific pair style can override this function +------------------------------------------------------------------------- */ + +void Pair::init_list(int which, NeighList *ptr) +{ + list = ptr; +} + /* ---------------------------------------------------------------------- mixing of pair potential prefactors (epsilon) ------------------------------------------------------------------------- */ @@ -181,34 +214,25 @@ double Pair::mix_distance(double sig1, double sig2) } /* ---------------------------------------------------------------------- - compute pair virial via pair own/ghost forces + compute pair virial via own/ghost forces + at this point, only pairwise forces have been accumulated in atom->f ------------------------------------------------------------------------- */ void Pair::virial_compute() { double **x = atom->x; - double **f_pair = update->f_pair; + double **f = atom->f; int nall = atom->nlocal + atom->nghost; // sum over own & ghost atoms for (int i = 0; i < nall; i++) { - virial[0] += f_pair[i][0]*x[i][0]; - virial[1] += f_pair[i][1]*x[i][1]; - virial[2] += f_pair[i][2]*x[i][2]; - virial[3] += f_pair[i][1]*x[i][0]; - virial[4] += f_pair[i][2]*x[i][0]; - virial[5] += f_pair[i][2]*x[i][1]; - } - - // add pair forces into total force - - double **f = atom->f; - - for (int i = 0; i < nall; i++) { - f[i][0] += f_pair[i][0]; - f[i][1] += f_pair[i][1]; - f[i][2] += f_pair[i][2]; + virial[0] += f[i][0]*x[i][0]; + virial[1] += f[i][1]*x[i][1]; + virial[2] += f[i][2]*x[i][2]; + virial[3] += f[i][1]*x[i][0]; + virial[4] += f[i][2]*x[i][0]; + virial[5] += f[i][2]*x[i][1]; } } diff --git a/src/pair.h b/src/pair.h index 00f10c0397..342c844e9b 100644 --- a/src/pair.h +++ b/src/pair.h @@ -29,8 +29,6 @@ class Pair : protected Pointers { int comm_forward; // size of forward communication (0 if none) int comm_reverse; // size of reverse communication (0 if none) - int neigh_half_every; // 0/1 = if needs half neighbor list - int neigh_full_every; // 0/1 = if needs full neighbor list int single_enable; // 1 if single() routine exists int respa_enable; // 1 if inner/middle/outer rRESPA routines @@ -40,11 +38,17 @@ class Pair : protected Pointers { double etail,ptail; // energy/pressure tail corrections double etail_ij,ptail_ij; + class NeighList *list; // standard neighbor list used by most pairs + class NeighList *listhalf; // half list used by some pairs + class NeighList *listfull; // full list used by some pairs + class NeighList *listgranhistory; // granular history list used by some + class NeighList *listinner; // rRESPA lists used by some pairs + class NeighList *listmiddle; + class NeighList *listouter; + struct One { // single interaction between 2 atoms double fforce; double eng_vdwl,eng_coul; - double fx,fy,fz; - double tix,tiy,tiz,tjx,tjy,tjz; }; Pair(class LAMMPS *); @@ -63,17 +67,20 @@ class Pair : protected Pointers { // general child-class methods virtual void compute(int, int) = 0; - virtual void settings(int, char **) = 0; - virtual void coeff(int, char **) = 0; - - virtual double init_one(int, int) {return 0.0;} - virtual void init_style() {} virtual void compute_inner() {} virtual void compute_middle() {} virtual void compute_outer(int, int) {} + virtual void single(int, int, int, int, double, double, double, int, One &) {} + virtual void settings(int, char **) = 0; + virtual void coeff(int, char **) = 0; + + virtual void init_style(); + virtual void init_list(int, class NeighList *); + virtual double init_one(int, int) {return 0.0;} + virtual void write_restart(FILE *) {} virtual void read_restart(FILE *) {} virtual void write_restart_settings(FILE *) {} @@ -88,6 +95,9 @@ class Pair : protected Pointers { // specific child-class methods for certain Pair styles virtual void single_embed(int, int, double &) {} + + virtual void *extract_ptr(char *) {return NULL;} + virtual void extract_charmm(double ***, double ***, double ***, double ***, int *) {} virtual void extract_dipole(double ***) {} diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp index 5fe48f4189..67d919177b 100644 --- a/src/pair_buck.cpp +++ b/src/pair_buck.cpp @@ -18,9 +18,8 @@ #include "atom.h" #include "comm.h" #include "force.h" -#include "update.h" +#include "neigh_list.h" #include "memory.h" -#include "neighbor.h" #include "error.h" using namespace LAMMPS_NS; @@ -55,37 +54,41 @@ PairBuck::~PairBuck() void PairBuck::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,forcebuck,fforce,factor_lj; double phibuck,r,rexp; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp index 9348c0f693..955b98c7cd 100644 --- a/src/pair_buck_coul_cut.cpp +++ b/src/pair_buck_coul_cut.cpp @@ -22,9 +22,9 @@ #include "atom.h" #include "comm.h" #include "force.h" -#include "update.h" -#include "memory.h" #include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" #include "error.h" using namespace LAMMPS_NS; @@ -62,19 +62,17 @@ PairBuckCoulCut::~PairBuckCoulCut() void PairBuckCoulCut::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,forcecoul,forcebuck,fforce,factor_coul,factor_lj; double factor,phicoul,phibuck,r,rexp; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = eng_coul = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; double *q = atom->q; int *type = atom->type; int nlocal = atom->nlocal; @@ -84,19 +82,25 @@ void PairBuckCoulCut::compute(int eflag, int vflag) int newton_pair = force->newton_pair; double qqrd2e = force->qqrd2e; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; qtmp = q[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_coul = factor_lj = 1.0; else { @@ -258,6 +262,18 @@ void PairBuckCoulCut::coeff(int narg, char **arg) if (count == 0) error->all("Incorrect args for pair coefficients"); } +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairBuckCoulCut::init_style() +{ + if (!atom->q_flag) + error->all("Pair style buck/coul/cut requires atom attribute q"); + + int irequest = neighbor->request(this); +} + /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -291,16 +307,6 @@ double PairBuckCoulCut::init_one(int i, int j) return cut; } -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairBuckCoulCut::init_style() -{ - if (!atom->q_flag) - error->all("Pair style buck/coul/cut requires atom attribute q"); -} - /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ diff --git a/src/pair_buck_coul_cut.h b/src/pair_buck_coul_cut.h index 6bf81731f7..06fd27c781 100644 --- a/src/pair_buck_coul_cut.h +++ b/src/pair_buck_coul_cut.h @@ -25,8 +25,8 @@ class PairBuckCoulCut : public Pair { void compute(int, int); void settings(int, char **); void coeff(int, char **); - double init_one(int, int); void init_style(); + double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); diff --git a/src/pair_coul_cut.cpp b/src/pair_coul_cut.cpp new file mode 100644 index 0000000000..ba5f6a44ef --- /dev/null +++ b/src/pair_coul_cut.cpp @@ -0,0 +1,313 @@ +/* ---------------------------------------------------------------------- + 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 + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_coul_cut.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +/* ---------------------------------------------------------------------- */ + +PairCoulCut::PairCoulCut(LAMMPS *lmp) : Pair(lmp) {} + +/* ---------------------------------------------------------------------- */ + +PairCoulCut::~PairCoulCut() +{ + if (allocated) { + memory->destroy_2d_int_array(setflag); + memory->destroy_2d_double_array(cutsq); + + memory->destroy_2d_double_array(cut); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulCut::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; + double rsq,r2inv,rinv,forcecoul,fforce,factor_coul,phicoul; + int *ilist,*jlist,*numneigh,**firstneigh; + + eng_coul = 0.0; + if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; + + double **x = atom->x; + double **f = atom->f; + double *q = atom->q; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = atom->nlocal + atom->nghost; + double *special_coul = force->special_coul; + int newton_pair = force->newton_pair; + double qqrd2e = force->qqrd2e; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + qtmp = q[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + + if (j < nall) factor_coul = 1.0; + else { + factor_coul = special_coul[j/nall]; + j %= nall; + } + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + forcecoul = qqrd2e * qtmp*q[j]*rinv; + fforce = factor_coul*forcecoul * r2inv; + + f[i][0] += delx*fforce; + f[i][1] += dely*fforce; + f[i][2] += delz*fforce; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fforce; + f[j][1] -= dely*fforce; + f[j][2] -= delz*fforce; + } + + if (eflag) { + phicoul = qqrd2e * qtmp*q[j]*rinv; + if (newton_pair || j < nlocal) eng_coul += factor_coul*phicoul; + else eng_coul += 0.5*factor_coul*phicoul; + } + + if (vflag == 1) { + if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; + virial[0] += delx*delx*fforce; + virial[1] += dely*dely*fforce; + virial[2] += delz*delz*fforce; + virial[3] += delx*dely*fforce; + virial[4] += delx*delz*fforce; + virial[5] += dely*delz*fforce; + } + } + } + } + if (vflag == 2) virial_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairCoulCut::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + setflag = memory->create_2d_int_array(n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + cutsq = memory->create_2d_double_array(n+1,n+1,"pair:cutsq"); + + cut = memory->create_2d_double_array(n+1,n+1,"pair:cut"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairCoulCut::settings(int narg, char **arg) +{ + if (narg != 1) error->all("Illegal pair_style command"); + + cut_global = atof(arg[0]); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i+1; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairCoulCut::coeff(int narg, char **arg) +{ + if (narg < 2 || narg > 3) error->all("Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(arg[0],atom->ntypes,ilo,ihi); + force->bounds(arg[1],atom->ntypes,jlo,jhi); + + double cut_one = cut_global; + if (narg == 3) cut_one = atof(arg[2]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all("Incorrect args for pair coefficients"); +} + + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairCoulCut::init_style() +{ + if (!atom->q_flag) + error->all("Pair style coul/cut requires atom attribute q"); + + int irequest = neighbor->request(this); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairCoulCut::init_one(int i, int j) +{ + if (setflag[i][j] == 0) + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairCoulCut::write_restart(FILE *fp) +{ + write_restart_settings(fp); + + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j],sizeof(int),1,fp); + if (setflag[i][j]) fwrite(&cut[i][j],sizeof(double),1,fp); + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairCoulCut::read_restart(FILE *fp) +{ + read_restart_settings(fp); + allocate(); + + int i,j; + int me = comm->me; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) { + if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp); + MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + if (setflag[i][j]) { + if (me == 0) fread(&cut[i][j],sizeof(double),1,fp); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairCoulCut::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); + fwrite(&offset_flag,sizeof(int),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairCoulCut::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_global,sizeof(double),1,fp); + fread(&offset_flag,sizeof(int),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&offset_flag,1,MPI_INT,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); +} + +/* ---------------------------------------------------------------------- */ + +void PairCoulCut::single(int i, int j, int itype, int jtype, + double rsq, double factor_coul, double factor_lj, + int eflag, One &one) +{ + double r2inv,rinv,forcecoul,phicoul; + + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + forcecoul = force->qqrd2e * atom->q[i]*atom->q[j]*rinv; + one.fforce = factor_coul*forcecoul * r2inv; + + if (eflag) { + phicoul = force->qqrd2e * atom->q[i]*atom->q[j]*rinv; + one.eng_coul = factor_coul*phicoul; + one.eng_vdwl = 0.0; + } +} diff --git a/src/compute_etotal_atom.h b/src/pair_coul_cut.h similarity index 55% rename from src/compute_etotal_atom.h rename to src/pair_coul_cut.h index b5c171e2ac..9b6a0fca49 100644 --- a/src/compute_etotal_atom.h +++ b/src/pair_coul_cut.h @@ -11,25 +11,33 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifndef COMPUTE_ETOTAL_ATOM_H -#define COMPUTE_ETOTAL_ATOM_H +#ifndef PAIR_COUL_CUT_H +#define PAIR_COUL_CUT_H -#include "compute.h" +#include "pair.h" namespace LAMMPS_NS { -class ComputeEtotalAtom : public Compute { +class PairCoulCut : public Pair { public: - ComputeEtotalAtom(class LAMMPS *, int, char **); - ~ComputeEtotalAtom(); - void init(); - void compute_peratom(); - int memory_usage(); + PairCoulCut(class LAMMPS *); + ~PairCoulCut(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + void single(int, int, int, int, double, double, double, int, One &); private: - int nmax; - double *etotal; - Compute *compute_epair; + double cut_global; + double **cut; + + void allocate(); }; } diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 80f77a74de..df69770d77 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -11,13 +11,6 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing authors: - James Fischer (High Performance Technologies, Inc) - Vincent Natoli (Stone Ridge Technology) - David Richie (Stone Ridge Technology) -------------------------------------------------------------------------- */ - #include "math.h" #include "string.h" #include "ctype.h" @@ -26,6 +19,7 @@ #include "force.h" #include "pair.h" #include "neighbor.h" +#include "neigh_request.h" #include "update.h" #include "comm.h" #include "memory.h" @@ -33,8 +27,6 @@ using namespace LAMMPS_NS; -#define NEIGHEXTRA 10000 - #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) @@ -58,265 +50,32 @@ PairHybrid::~PairHybrid() if (allocated) { memory->destroy_2d_int_array(setflag); - memory->destroy_2d_int_array(map); memory->destroy_2d_double_array(cutsq); - - delete [] nnlist; - delete [] maxneigh; - for (int m = 0; m < nstyles; m++) memory->sfree(nlist[m]); - delete [] nlist; - - delete [] nnlist_full; - delete [] maxneigh_full; - for (int m = 0; m < nstyles; m++) memory->sfree(nlist_full[m]); - delete [] nlist_full; - - for (int m = 0; m < nstyles; m++) delete [] firstneigh[m]; - delete [] firstneigh; - for (int m = 0; m < nstyles; m++) delete [] numneigh[m]; - delete [] numneigh; - - for (int m = 0; m < nstyles; m++) delete [] firstneigh_full[m]; - delete [] firstneigh_full; - for (int m = 0; m < nstyles; m++) delete [] numneigh_full[m]; - delete [] numneigh_full; + memory->destroy_2d_int_array(nmap); + memory->destroy_3d_int_array(map); } } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + call each sub-style's compute function + accumulate sub-style energy/virial in hybrid's energy/virial + for vflag = 1: + each sub-style computes own virial[6] + sum sub-style virial[6] to hybrid's virial[6] + for vflag = 2: + call sub-style compute() with vflag % 2 + to prevent sub-style from calling virial_compute() + hybrid calls virial_compute() on final accumulated f +------------------------------------------------------------------------- */ void PairHybrid::compute(int eflag, int vflag) { - int i,j,k,m,n,jfull,nneigh; - int *neighs,*mapi; - double **f_original; - - // save ptrs to original neighbor lists - - int **firstneigh_original = neighbor->firstneigh; - int *numneigh_original = neighbor->numneigh; - int **firstneigh_full_original = neighbor->firstneigh_full; - int *numneigh_full_original = neighbor->numneigh_full; - - // if this is re-neighbor step, create sub-style lists - - if (neighbor->ago == 0) { - int *type = atom->type; - int nlocal = atom->nlocal; - int nall = atom->nlocal + atom->nghost; - - // realloc per-atom per-style firstneigh/numneigh half/full if necessary - - if (nlocal > maxlocal) { - maxlocal = nlocal; - if (neigh_half_every) { - for (m = 0; m < nstyles; m++) { - delete [] firstneigh[m]; - delete [] numneigh[m]; - } - for (m = 0; m < nstyles; m++) { - firstneigh[m] = new int*[maxlocal]; - numneigh[m] = new int[maxlocal]; - } - } - if (neigh_full_every) { - for (m = 0; m < nstyles; m++) { - delete [] firstneigh_full[m]; - delete [] numneigh_full[m]; - } - for (m = 0; m < nstyles; m++) { - firstneigh_full[m] = new int*[maxlocal]; - numneigh_full[m] = new int[maxlocal]; - } - } - } - - // nnlist[] = length of each sub-style half list - // nnlist_full[] = length of each sub-style full list - // count from half and/or full list depending on what sub-styles use - - for (m = 0; m < nstyles; m++) nnlist[m] = nnlist_full[m] = 0; - - if (neigh_half_every && neigh_full_every) { - for (i = 0; i < nlocal; i++) { - mapi = map[type[i]]; - neighs = firstneigh_original[i]; - nneigh = numneigh_original[i]; - for (k = 0; k < nneigh; k++) { - j = neighs[k]; - if (j >= nall) j %= nall; - m = mapi[type[j]]; - if (styles[m] && styles[m]->neigh_half_every) nnlist[m]++; - } - neighs = firstneigh_full_original[i]; - nneigh = numneigh_full_original[i]; - for (k = 0; k < nneigh; k++) { - j = neighs[k]; - if (j >= nall) j %= nall; - m = mapi[type[j]]; - if (styles[m] && styles[m]->neigh_full_every) nnlist_full[m]++; - } - } - - } else if (neigh_half_every) { - for (i = 0; i < nlocal; i++) { - mapi = map[type[i]]; - neighs = firstneigh_original[i]; - nneigh = numneigh_original[i]; - for (k = 0; k < nneigh; k++) { - j = neighs[k]; - if (j >= nall) j %= nall; - nnlist[mapi[type[j]]]++; - } - } - - } else if (neigh_full_every) { - for (i = 0; i < nlocal; i++) { - mapi = map[type[i]]; - neighs = firstneigh_full_original[i]; - nneigh = numneigh_full_original[i]; - for (k = 0; k < nneigh; k++) { - j = neighs[k]; - if (j >= nall) j %= nall; - nnlist_full[mapi[type[j]]]++; - } - } - } - - // realloc sub-style nlist and nlist_full if necessary - - if (neigh_half_every) { - for (m = 0; m < nstyles; m++) { - if (nnlist[m] > maxneigh[m]) { - memory->sfree(nlist[m]); - maxneigh[m] = nnlist[m] + NEIGHEXTRA; - nlist[m] = (int *) - memory->smalloc(maxneigh[m]*sizeof(int),"pair_hybrid:nlist"); - } - nnlist[m] = 0; - } - } - if (neigh_full_every) { - for (m = 0; m < nstyles; m++) { - if (nnlist_full[m] > maxneigh_full[m]) { - memory->sfree(nlist_full[m]); - maxneigh_full[m] = nnlist_full[m] + NEIGHEXTRA; - nlist_full[m] = (int *) - memory->smalloc(maxneigh_full[m]*sizeof(int), - "pair_hybrid:nlist_full"); - } - nnlist_full[m] = 0; - } - } - - // load sub-style half/full list with values from original lists - // load from half and/or full list depending on what sub-styles use - - if (neigh_half_every && neigh_full_every) { - for (i = 0; i < nlocal; i++) { - for (m = 0; m < nstyles; m++) { - firstneigh[m][i] = &nlist[m][nnlist[m]]; - numneigh[m][i] = nnlist[m]; - firstneigh_full[m][i] = &nlist_full[m][nnlist_full[m]]; - numneigh_full[m][i] = nnlist_full[m]; - } - mapi = map[type[i]]; - neighs = firstneigh_original[i]; - nneigh = numneigh_original[i]; - for (k = 0; k < nneigh; k++) { - j = jfull = neighs[k]; - if (j >= nall) j %= nall; - m = mapi[type[j]]; - if (styles[m] && styles[m]->neigh_half_every) - nlist[m][nnlist[m]++] = jfull; - } - neighs = firstneigh_full_original[i]; - nneigh = numneigh_full_original[i]; - for (k = 0; k < nneigh; k++) { - j = jfull = neighs[k]; - if (j >= nall) j %= nall; - m = mapi[type[j]]; - if (styles[m] && styles[m]->neigh_full_every) - nlist_full[m][nnlist_full[m]++] = jfull; - } - for (m = 0; m < nstyles; m++) { - numneigh[m][i] = nnlist[m] - numneigh[m][i]; - numneigh_full[m][i] = nnlist_full[m] - numneigh_full[m][i]; - } - } - - } else if (neigh_half_every) { - for (i = 0; i < nlocal; i++) { - for (m = 0; m < nstyles; m++) { - firstneigh[m][i] = &nlist[m][nnlist[m]]; - numneigh[m][i] = nnlist[m]; - } - mapi = map[type[i]]; - neighs = firstneigh_original[i]; - nneigh = numneigh_original[i]; - for (k = 0; k < nneigh; k++) { - j = jfull = neighs[k]; - if (j >= nall) j %= nall; - m = mapi[type[j]]; - nlist[m][nnlist[m]++] = jfull; - } - for (m = 0; m < nstyles; m++) - numneigh[m][i] = nnlist[m] - numneigh[m][i]; - } - - } else if (neigh_full_every) { - for (i = 0; i < nlocal; i++) { - for (m = 0; m < nstyles; m++) { - firstneigh_full[m][i] = &nlist_full[m][nnlist_full[m]]; - numneigh_full[m][i] = nnlist_full[m]; - } - mapi = map[type[i]]; - neighs = firstneigh_full_original[i]; - nneigh = numneigh_full_original[i]; - for (k = 0; k < nneigh; k++) { - j = jfull = neighs[k]; - if (j >= nall) j %= nall; - m = mapi[type[j]]; - nlist_full[m][nnlist_full[m]++] = jfull; - } - for (m = 0; m < nstyles; m++) - numneigh_full[m][i] = nnlist_full[m] - numneigh_full[m][i]; - } - } - } - - // call each sub-style's compute function - // set neighbor->firstneigh/numneigh to sub-style lists before call - // set half or full or both depending on what sub-style uses - // for vflag = 1: - // sub-style accumulates in its virial[6] - // sum sub-style virial[6] to hybrid's virial[6] - // for vflag = 2: - // set atom->f to update->f_pair so sub-style will sum its f to f_pair - // call sub-style compute() with vflag % 2 to prevent sub-style - // from calling virial_compute() - // reset atom->f to stored f_original - // call hybrid virial_compute() which will use update->f_pair - // accumulate sub-style energy,virial in hybrid's energy,virial + int m,n; eng_vdwl = eng_coul = 0.0; if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; - if (vflag == 2) { - f_original = atom->f; - atom->f = update->f_pair; - } - for (m = 0; m < nstyles; m++) { - if (styles[m] == NULL) continue; - if (styles[m]->neigh_half_every) { - neighbor->firstneigh = firstneigh[m]; - neighbor->numneigh = numneigh[m]; - } - if (styles[m]->neigh_full_every) { - neighbor->firstneigh_full = firstneigh_full[m]; - neighbor->numneigh_full = numneigh_full[m]; - } styles[m]->compute(eflag,vflag % 2); if (eflag) { eng_vdwl += styles[m]->eng_vdwl; @@ -325,17 +84,7 @@ void PairHybrid::compute(int eflag, int vflag) if (vflag == 1) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; } - if (vflag == 2) { - atom->f = f_original; - virial_compute(); - } - - // restore ptrs to original neighbor lists - - neighbor->firstneigh = firstneigh_original; - neighbor->numneigh = numneigh_original; - neighbor->firstneigh_full = firstneigh_full_original; - neighbor->numneigh_full = numneigh_full_original; + if (vflag == 2) virial_compute(); } /* ---------------------------------------------------------------------- @@ -347,11 +96,6 @@ void PairHybrid::allocate() allocated = 1; int n = atom->ntypes; - map = memory->create_2d_int_array(n+1,n+1,"pair:map"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) - map[i][j] = -1; - setflag = memory->create_2d_int_array(n+1,n+1,"pair:setflag"); for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) @@ -359,27 +103,11 @@ void PairHybrid::allocate() cutsq = memory->create_2d_double_array(n+1,n+1,"pair:cutsq"); - nnlist = new int[nstyles]; - maxneigh = new int[nstyles]; - nlist = new int*[nstyles]; - for (int m = 0; m < nstyles; m++) maxneigh[m] = 0; - for (int m = 0; m < nstyles; m++) nlist[m] = NULL; - - nnlist_full = new int[nstyles]; - maxneigh_full = new int[nstyles]; - nlist_full = new int*[nstyles]; - for (int m = 0; m < nstyles; m++) maxneigh_full[m] = 0; - for (int m = 0; m < nstyles; m++) nlist_full[m] = NULL; - - maxlocal = 0; - firstneigh = new int**[nstyles]; - numneigh = new int*[nstyles]; - for (int m = 0; m < nstyles; m++) firstneigh[m] = NULL; - for (int m = 0; m < nstyles; m++) numneigh[m] = NULL; - firstneigh_full = new int**[nstyles]; - numneigh_full = new int*[nstyles]; - for (int m = 0; m < nstyles; m++) firstneigh_full[m] = NULL; - for (int m = 0; m < nstyles; m++) numneigh_full[m] = NULL; + nmap = memory->create_2d_int_array(n+1,n+1,"pair:nmap"); + map = memory->create_3d_int_array(n+1,n+1,nstyles,"pair:map"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + nmap[i][j] = 0; } /* ---------------------------------------------------------------------- @@ -403,15 +131,17 @@ void PairHybrid::settings(int narg, char **arg) if (allocated) { memory->destroy_2d_int_array(setflag); - memory->destroy_2d_int_array(map); memory->destroy_2d_double_array(cutsq); + memory->destroy_2d_int_array(nmap); + memory->destroy_3d_int_array(map); } allocated = 0; // count sub-styles by skipping numeric args // one exception is 1st arg of style "table", which is non-numeric word - nstyles = i = 0; + nstyles = 0; + i = 0; while (i < narg) { if (strcmp(arg[i],"table") == 0) i++; i++; @@ -425,16 +155,19 @@ void PairHybrid::settings(int narg, char **arg) keywords = new char*[nstyles]; // allocate each sub-style and call its settings() with subset of args - // define subset of sub-styles by skipping numeric args + // define subset of args for a sub-style by skipping numeric args // one exception is 1st arg of style "table", which is non-numeric word - nstyles = i = 0; + nstyles = 0; + i = 0; while (i < narg) { for (m = 0; m < nstyles; m++) if (strcmp(arg[i],keywords[m]) == 0) error->all("Pair style hybrid cannot use same pair style twice"); if (strcmp(arg[i],"hybrid") == 0) error->all("Pair style hybrid cannot have hybrid as an argument"); + if (strcmp(arg[i],"none") == 0) + error->all("Pair style hybrid cannot have none as an argument"); styles[nstyles] = force->new_pair(arg[i]); keywords[nstyles] = new char[strlen(arg[i])+1]; strcpy(keywords[nstyles],arg[i]); @@ -442,7 +175,7 @@ void PairHybrid::settings(int narg, char **arg) if (strcmp(arg[i],"table") == 0) i++; i++; while (i < narg && !isalpha(arg[i][0])) i++; - if (styles[nstyles]) styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]); + styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]); nstyles++; } @@ -453,14 +186,6 @@ void PairHybrid::settings(int narg, char **arg) if (styles[m]) comm_reverse = MAX(comm_reverse,styles[m]->comm_reverse); } - // neigh_every = 1 if any sub-style = 1 - - neigh_half_every = neigh_full_every = 0; - for (m = 0; m < nstyles; m++) { - if (styles[m] && styles[m]->neigh_half_every) neigh_half_every = 1; - if (styles[m] && styles[m]->neigh_full_every) neigh_full_every = 1; - } - // single_enable = 0 if any sub-style = 0 for (m = 0; m < nstyles; m++) @@ -480,12 +205,18 @@ void PairHybrid::coeff(int narg, char **arg) force->bounds(arg[0],atom->ntypes,ilo,ihi); force->bounds(arg[1],atom->ntypes,jlo,jhi); - // 3rd arg = pair style name + // 3rd arg = pair sub-style name + // allow for "none" as valid sub-style name int m; for (m = 0; m < nstyles; m++) if (strcmp(arg[2],keywords[m]) == 0) break; - if (m == nstyles) error->all("Pair coeff for hybrid has invalid style"); + + int none = 0; + if (m == nstyles) { + if (strcmp(arg[2],"none") == 0) none = 1; + else error->all("Pair coeff for hybrid has invalid style"); + } // move 1st/2nd args to 2nd/3rd args @@ -494,29 +225,36 @@ void PairHybrid::coeff(int narg, char **arg) // invoke sub-style coeff() starting with 1st arg - if (styles[m]) styles[m]->coeff(narg-1,&arg[1]); + if (!none) styles[m]->coeff(narg-1,&arg[1]); - // if pair style only allows one pair coeff call (with * * and type mapping) - // then unset any old setflag/map assigned to that style first + // if sub-style only allows one pair coeff call (with * * and type mapping) + // then unset setflag/map assigned to that style before setting it below // in case pair coeff for this sub-style is being called for 2nd time - if (styles[m] && styles[m]->one_coeff) + if (!none && styles[m]->one_coeff) for (int i = 1; i <= atom->ntypes; i++) for (int j = i; j <= atom->ntypes; j++) - if (map[i][j] == m) { - map[i][j] = -1; + if (nmap[i][j] && map[i][j][0] == m) { setflag[i][j] = 0; + nmap[i][j] = 0; } - // set hybrid map & setflag only if substyle set its setflag - // if sub-style is NULL for "none", still set setflag + // set setflag and which type pairs map to which sub-style + // if sub-style is none: set hybrid subflag, wipe out map + // else: set hybrid setflag & map only if substyle setflag is set + // previous mappings are wiped out int count = 0; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - if (styles[m] == NULL || styles[m]->setflag[i][j]) { - map[i][j] = m; + if (none) { setflag[i][j] = 1; + nmap[i][j] = 0; + count++; + } else if (styles[m]->setflag[i][j]) { + setflag[i][j] = 1; + nmap[i][j] = 1; + map[i][j][0] = m; count++; } } @@ -525,55 +263,170 @@ void PairHybrid::coeff(int narg, char **arg) if (count == 0) error->all("Incorrect args for pair coefficients"); } -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairHybrid::init_one(int i, int j) -{ - // if i,j is set explicity, call its sub-style - // if i,j is not set and i,i sub-style = j,j sub-style - // then set map[i][j] to this sub-style and call sub-style for init/mixing - // else i,j has not been set by user - // check for special case = style none - - double cut = 0.0; - if (setflag[i][j]) { - if (styles[map[i][j]]) { - cut = styles[map[i][j]]->init_one(i,j); - styles[map[i][j]]->cutsq[i][j] = - styles[map[i][j]]->cutsq[j][i] = cut*cut; - if (tail_flag) { - etail_ij = styles[map[i][j]]->etail_ij; - ptail_ij = styles[map[i][j]]->ptail_ij; - } - } - } else if (map[i][i] == map[j][j]) { - map[i][j] = map[i][i]; - if (styles[map[i][j]]) { - cut = styles[map[i][j]]->init_one(i,j); - styles[map[i][j]]->cutsq[i][j] = - styles[map[i][j]]->cutsq[j][i] = cut*cut; - if (tail_flag) { - etail_ij = styles[map[i][j]]->etail_ij; - ptail_ij = styles[map[i][j]]->ptail_ij; - } - } - } else error->all("All pair coeffs are not set"); - - map[j][i] = map[i][j]; - - return cut; -} - /* ---------------------------------------------------------------------- init specific to this pair style ------------------------------------------------------------------------- */ void PairHybrid::init_style() { - for (int m = 0; m < nstyles; m++) - if (styles[m]) styles[m]->init_style(); + int i,m,itype,jtype,used,istyle,skip; + + // error if a sub-style is not used + + int ntypes = atom->ntypes; + + for (istyle = 0; istyle < nstyles; istyle++) { + used = 0; + for (itype = 1; itype <= ntypes; itype++) + for (jtype = itype; jtype <= ntypes; jtype++) + for (m = 0; m < nmap[itype][jtype]; m++) + if (map[itype][jtype][m] == istyle) used = 1; + if (used == 0) error->all("Pair hybrid sub-style is not used"); + } + + // each sub-style makes its neighbor list request(s) + + for (istyle = 0; istyle < nstyles; istyle++) styles[istyle]->init_style(); + + // create skip lists for each neigh request + + for (i = 0; i < neighbor->nrequest; i++) { + + // only relevant for half, full, gran, respaouter lists + + if (neighbor->requests[i]->granhistory) continue; + if (neighbor->requests[i]->respamiddle) continue; + if (neighbor->requests[i]->respainner) continue; + if (neighbor->requests[i]->half_from_full) continue; + + // find associated sub-style + + for (istyle = 0; istyle < nstyles; istyle++) + if (styles[istyle] == neighbor->requests[i]->requestor) break; + + // allocate iskip and ijskip + // initialize so as to skip all pair types + // set ijskip = 0 if type pair matches any entry in sub-style map + // set ijskip = 0 if mixing will assign type pair to this sub-style + // will occur if both I,I and J,J are assigned to single sub-style + // and sub-style for both I,I and J,J match istyle + // set iskip = 1 only if all ijskip for itype are 1 + + int *iskip = new int[ntypes+1]; + int **ijskip = memory->create_2d_int_array(ntypes+1,ntypes+1, + "pair_hybrid:ijskip"); + + for (itype = 1; itype <= ntypes; itype++) + for (jtype = 1; jtype <= ntypes; jtype++) + ijskip[itype][jtype] = 1; + + for (itype = 1; itype <= ntypes; itype++) + for (jtype = itype; jtype <= ntypes; jtype++) { + for (m = 0; m < nmap[itype][jtype]; m++) + if (map[itype][jtype][m] == istyle) + ijskip[itype][jtype] = ijskip[jtype][itype] = 0; + if (nmap[itype][itype] == 1 && map[itype][itype][0] == istyle && + nmap[jtype][jtype] == 1 && map[jtype][jtype][0] == istyle) + ijskip[itype][jtype] = ijskip[jtype][itype] = 0; + } + + for (itype = 1; itype <= ntypes; itype++) { + iskip[itype] = 1; + for (jtype = 1; jtype <= ntypes; jtype++) + if (ijskip[itype][jtype] == 0) iskip[itype] = 0; + } + + // if any skipping occurs + // set request->skip and copy iskip and ijskip into request + // else delete iskip and ijskip + + skip = 0; + for (itype = 1; itype <= ntypes; itype++) + for (jtype = 1; jtype <= ntypes; jtype++) + if (ijskip[itype][jtype] == 1) skip = 1; + + if (skip) { + neighbor->requests[i]->skip = 1; + neighbor->requests[i]->iskip = iskip; + neighbor->requests[i]->ijskip = ijskip; + } else { + delete [] iskip; + memory->destroy_2d_int_array(ijskip); + } + } + + // combine sub-style neigh list requests and create new ones if needed + + modify_requests(); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairHybrid::init_one(int i, int j) +{ + // if I,J is not set explicitly: + // perform mixing only if I,I sub-style = J,J sub-style + // also require I,I and J,J both are assigned to single sub-style + + if (setflag[i][j] == 0) { + if (nmap[i][i] != 1 || nmap[j][j] != 1 || map[i][i][0] != map[j][j][0]) + error->one("All pair coeffs are not set"); + nmap[i][j] = 1; + map[i][j][0] = map[i][i][0]; + } + + // call init/mixing for all sub-styles of I,J + // set cutsq in sub-style just as pair::init_one() does + // sum tail corrections for I,J + // compute max cutoff + // if sub-style = none, cutmax of 0.0 will be returned + + double cutmax = 0.0; + if (tail_flag) etail_ij = ptail_ij = 0.0; + + for (int k = 0; k < nmap[i][j]; k++) { + map[j][i][k] = map[i][j][k]; + double cut = styles[map[i][j][k]]->init_one(i,j); + styles[map[i][j][k]]->cutsq[i][j] = + styles[map[i][j][k]]->cutsq[j][i] = cut*cut; + if (tail_flag) { + etail_ij += styles[map[i][j][k]]->etail_ij; + ptail_ij += styles[map[i][j][k]]->ptail_ij; + } + cutmax = MAX(cutmax,cut); + } + + return cutmax; +} + +/* ---------------------------------------------------------------------- + combine sub-style neigh list requests and create new ones if needed +------------------------------------------------------------------------- */ + +void PairHybrid::modify_requests() +{ + int i,j; + + // if list is skip list, look for non-skip list of same kind + // if one exists, point at that one + // else make new non-skip request of same kind and point at that one + + for (i = 0; i < neighbor->nrequest; i++) { + if (neighbor->requests[i]->skip == 0) continue; + + for (j = 0; j < neighbor->nrequest; j++) + if (neighbor->requests[i]->same_kind(neighbor->requests[j]) && + neighbor->requests[j]->skip == 0) break; + + if (j < neighbor->nrequest) neighbor->requests[i]->otherlist = j; + else { + int irequest = neighbor->request(this); + neighbor->requests[irequest]->copy_kind(neighbor->requests[i]); + neighbor->requests[i]->otherlist = irequest; + } + } } /* ---------------------------------------------------------------------- @@ -584,14 +437,14 @@ void PairHybrid::write_restart(FILE *fp) { fwrite(&nstyles,sizeof(int),1,fp); - // each sub-style writes its settings + // each sub-style writes its settings, but no coeff info int n; for (int m = 0; m < nstyles; m++) { n = strlen(keywords[m]) + 1; fwrite(&n,sizeof(int),1,fp); fwrite(keywords[m],sizeof(char),n,fp); - if (styles[m]) styles[m]->write_restart_settings(fp); + styles[m]->write_restart_settings(fp); } } @@ -601,8 +454,6 @@ void PairHybrid::write_restart(FILE *fp) void PairHybrid::read_restart(FILE *fp) { - allocate(); - int me = comm->me; if (me == 0) fread(&nstyles,sizeof(int),1,fp); MPI_Bcast(&nstyles,1,MPI_INT,0,world); @@ -610,7 +461,8 @@ void PairHybrid::read_restart(FILE *fp) styles = new Pair*[nstyles]; keywords = new char*[nstyles]; - // each sub-style is created via new_pair() and reads its settings + // each sub-style is created via new_pair() + // each reads its settings, but no coeff info int n; for (int m = 0; m < nstyles; m++) { @@ -620,31 +472,56 @@ void PairHybrid::read_restart(FILE *fp) if (me == 0) fread(keywords[m],sizeof(char),n,fp); MPI_Bcast(keywords[m],n,MPI_CHAR,0,world); styles[m] = force->new_pair(keywords[m]); - if (styles[m]) styles[m]->read_restart_settings(fp); + styles[m]->read_restart_settings(fp); } } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + call sub-style to compute single interaction + since overlay could have multiple sub-styles, sum results explicitly +------------------------------------------------------------------------- */ void PairHybrid::single(int i, int j, int itype, int jtype, double rsq, double factor_coul, double factor_lj, int eflag, One &one) { - if (map[itype][jtype] == -1) + if (nmap[itype][jtype] == 0) error->one("Invoked pair single on pair style none"); - styles[map[itype][jtype]]-> - single(i,j,itype,jtype,rsq,factor_coul,factor_lj,eflag,one); + double fforce = 0.0; + double eng_vdwl = 0.0; + double eng_coul = 0.0; + + for (int m = 0; m < nmap[itype][jtype]; m++) { + styles[map[itype][jtype][m]]-> + single(i,j,itype,jtype,rsq,factor_coul,factor_lj,eflag,one); + fforce += one.fforce; + eng_vdwl += one.eng_vdwl; + eng_coul += one.eng_coul; + } + + one.fforce = fforce; + one.eng_vdwl = eng_vdwl; + one.eng_coul = eng_coul; } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + call sub-style to compute single embedding interaction + since overlay could have multiple sub-styles, sum results explicitly +------------------------------------------------------------------------- */ void PairHybrid::single_embed(int i, int itype, double &phi) { - if (map[itype][itype] == -1) + if (nmap[itype][itype] == 0) error->one("Invoked pair single on pair style none"); - styles[map[itype][itype]]->single_embed(i,itype,phi); + phi = 0.0; + double phi_single; + + for (int m = 0; m < nmap[itype][itype]; m++) { + styles[map[itype][itype][m]]->single_embed(i,itype,phi_single); + phi += phi_single; + } } /* ---------------------------------------------------------------------- @@ -656,20 +533,16 @@ void PairHybrid::single_embed(int i, int itype, double &phi) void PairHybrid::modify_params(int narg, char **arg) { Pair::modify_params(narg,arg); - for (int m = 0; m < nstyles; m++) - if (styles[m]) styles[m]->modify_params(narg,arg); + for (int m = 0; m < nstyles; m++) styles[m]->modify_params(narg,arg); } /* ---------------------------------------------------------------------- - memory usage of sub-style firstneigh, numneigh, neighbor list - add in memory usage of each sub-style itself + memory usage of each sub-style ------------------------------------------------------------------------- */ int PairHybrid::memory_usage() { - int bytes = nstyles*maxlocal * (sizeof(int *) + sizeof(int)); - for (int m = 0; m < nstyles; m++) bytes += maxneigh[m] * sizeof(int); - for (int m = 0; m < nstyles; m++) - if (styles[m]) bytes += styles[m]->memory_usage(); + int bytes = 0; + for (int m = 0; m < nstyles; m++) bytes += styles[m]->memory_usage(); return bytes; } diff --git a/src/pair_hybrid.h b/src/pair_hybrid.h index 2686e00730..ab828a1d72 100644 --- a/src/pair_hybrid.h +++ b/src/pair_hybrid.h @@ -21,17 +21,17 @@ namespace LAMMPS_NS { class PairHybrid : public Pair { public: - int nstyles; // # of different pair styles - Pair **styles; // class list for each Pair style - char **keywords; // sub-style name for each Pair style + int nstyles; // # of different sub-styles + Pair **styles; // list of Pair style classes + char **keywords; // style name of each Pair style PairHybrid(class LAMMPS *); ~PairHybrid(); void compute(int, int); void settings(int, char **); - void coeff(int, char **); - double init_one(int, int); + virtual void coeff(int, char **); void init_style(); + double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void single(int, int, int, int, double, double, double, int, One &); @@ -39,24 +39,12 @@ class PairHybrid : public Pair { void modify_params(int narg, char **arg); int memory_usage(); - private: - int **map; // which style each itype,jtype points to - - int *nnlist; // # of half neighs in sub-style neigh lists - int *maxneigh; // max # of neighs sub-style lists can store - int **nlist; // half neigh list for each sub-style - - int *nnlist_full; // # of full neighs in sub-style neigh lists - int *maxneigh_full; // max # of neighs sub-style lists can store - int **nlist_full; // full neigh list for each sub-style - - int ***firstneigh; // each sub-style's per-atom firstneigh - int **numneigh; // each sub-style's per-atom numneigh - int ***firstneigh_full; // each sub-style's per-atom firstneigh_full - int **numneigh_full; // each sub-style's per-atom numneigh_full - int maxlocal; // max length of each ss's firstneigh,numneigh + protected: + int **nmap; // # of sub-styles itype,jtype points to + int ***map; // list of sub-styles itype,jtype points to void allocate(); + virtual void modify_requests(); }; } diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp index dc342a13b7..af2743af5c 100644 --- a/src/pair_lj_cut.cpp +++ b/src/pair_lj_cut.cpp @@ -24,6 +24,8 @@ #include "comm.h" #include "force.h" #include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" #include "update.h" #include "integrate.h" #include "respa.h" @@ -65,36 +67,40 @@ PairLJCut::~PairLJCut() void PairLJCut::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,forcelj,fforce,factor_lj,philj; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { @@ -149,21 +155,24 @@ void PairLJCut::compute(int eflag, int vflag) void PairLJCut::compute_inner() { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcelj,fforce,factor_lj; - double rsw; - int *neighs; - double **f; + double rsq,r2inv,r6inv,forcelj,fforce,factor_lj,rsw; + int *ilist,*jlist,*numneigh,**firstneigh; - f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = listinner->inum; + ilist = listinner->ilist; + numneigh = listinner->numneigh; + firstneigh = listinner->firstneigh; + double cut_out_on = cut_respa[0]; double cut_out_off = cut_respa[1]; @@ -173,16 +182,17 @@ void PairLJCut::compute_inner() // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh_inner[i]; - numneigh = neighbor->numneigh_inner[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { @@ -223,21 +233,24 @@ void PairLJCut::compute_inner() void PairLJCut::compute_middle() { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcelj,fforce,factor_lj; - double rsw; - int *neighs; - double **f; + double rsq,r2inv,r6inv,forcelj,fforce,factor_lj,rsw; + int *ilist,*jlist,*numneigh,**firstneigh; - f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = listmiddle->inum; + ilist = listmiddle->ilist; + numneigh = listmiddle->numneigh; + firstneigh = listmiddle->firstneigh; + double cut_in_off = cut_respa[0]; double cut_in_on = cut_respa[1]; double cut_out_on = cut_respa[2]; @@ -252,16 +265,17 @@ void PairLJCut::compute_middle() // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh_middle[i]; - numneigh = neighbor->numneigh_middle[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { @@ -306,24 +320,27 @@ void PairLJCut::compute_middle() void PairLJCut::compute_outer(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq,r2inv,r6inv,forcelj,fforce,factor_lj,philj; - double rsw; - int *neighs; - double **f; + double rsq,r2inv,r6inv,forcelj,fforce,factor_lj,philj,rsw; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = listouter->inum; + ilist = listouter->ilist; + numneigh = listouter->numneigh; + firstneigh = listouter->firstneigh; + double cut_in_off = cut_respa[2]; double cut_in_on = cut_respa[3]; @@ -333,16 +350,17 @@ void PairLJCut::compute_outer(int eflag, int vflag) // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { @@ -487,6 +505,62 @@ void PairLJCut::coeff(int narg, char **arg) if (count == 0) error->all("Incorrect args for pair coefficients"); } +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairLJCut::init_style() +{ + // request regular or rRESPA neighbor lists + + int irequest; + + if (update->whichflag == 0 && strcmp(update->integrate_style,"respa") == 0) { + int respa = 0; + if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; + if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; + + if (respa == 0) irequest = neighbor->request(this); + else if (respa == 1) { + irequest = neighbor->request(this); + neighbor->requests[irequest]->id = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->respainner = 1; + irequest = neighbor->request(this); + neighbor->requests[irequest]->id = 3; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->respaouter = 1; + } else { + irequest = neighbor->request(this); + neighbor->requests[irequest]->id = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->respainner = 1; + irequest = neighbor->request(this); + neighbor->requests[irequest]->id = 2; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->respamiddle = 1; + irequest = neighbor->request(this); + neighbor->requests[irequest]->id = 3; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->respaouter = 1; + } + + } else irequest = neighbor->request(this); +} + +/* ---------------------------------------------------------------------- + neighbor callback to inform pair style of neighbor list to use + regular or rRESPA +------------------------------------------------------------------------- */ + +void PairLJCut::init_list(int id, NeighList *ptr) +{ + if (id == 0) list = ptr; + else if (id == 1) listinner = ptr; + else if (id == 2) listmiddle = ptr; + else if (id == 3) listouter = ptr; +} + /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ diff --git a/src/pair_lj_cut.h b/src/pair_lj_cut.h index e89a4d0bdd..a91dec05ab 100644 --- a/src/pair_lj_cut.h +++ b/src/pair_lj_cut.h @@ -25,6 +25,8 @@ class PairLJCut : public Pair { void compute(int, int); void settings(int, char **); void coeff(int, char **); + void init_style(); + void init_list(int, class NeighList *); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp index 9993f0edd7..5c0d08a4db 100644 --- a/src/pair_lj_cut_coul_cut.cpp +++ b/src/pair_lj_cut_coul_cut.cpp @@ -19,9 +19,9 @@ #include "atom.h" #include "comm.h" #include "force.h" -#include "update.h" -#include "memory.h" #include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" #include "error.h" using namespace LAMMPS_NS; @@ -59,19 +59,17 @@ PairLJCutCoulCut::~PairLJCutCoulCut() void PairLJCutCoulCut::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double factor,phicoul,philj; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = eng_coul = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; double *q = atom->q; int *type = atom->type; int nlocal = atom->nlocal; @@ -81,19 +79,25 @@ void PairLJCutCoulCut::compute(int eflag, int vflag) int newton_pair = force->newton_pair; double qqrd2e = force->qqrd2e; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; qtmp = q[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_coul = factor_lj = 1.0; else { @@ -250,6 +254,18 @@ void PairLJCutCoulCut::coeff(int narg, char **arg) if (count == 0) error->all("Incorrect args for pair coefficients"); } +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairLJCutCoulCut::init_style() +{ + if (!atom->q_flag) + error->all("Pair style lj/cut/coul/cut requires atom attribute q"); + + int irequest = neighbor->request(this); +} + /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -316,16 +332,6 @@ double PairLJCutCoulCut::init_one(int i, int j) return cut; } -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairLJCutCoulCut::init_style() -{ - if (!atom->q_flag) - error->all("Pair style lj/cut/coul/cut requires atom attribute q"); -} - /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ diff --git a/src/pair_lj_cut_coul_cut.h b/src/pair_lj_cut_coul_cut.h index 8e027e5ac9..8af68331cb 100644 --- a/src/pair_lj_cut_coul_cut.h +++ b/src/pair_lj_cut_coul_cut.h @@ -25,8 +25,8 @@ class PairLJCutCoulCut : public Pair { virtual void compute(int, int); virtual void settings(int, char **); void coeff(int, char **); - double init_one(int, int); void init_style(); + double init_one(int, int); virtual void write_restart(FILE *); virtual void read_restart(FILE *); virtual void write_restart_settings(FILE *); diff --git a/src/pair_lj_cut_coul_debye.cpp b/src/pair_lj_cut_coul_debye.cpp index 4331a11e61..f4c28e6dba 100644 --- a/src/pair_lj_cut_coul_debye.cpp +++ b/src/pair_lj_cut_coul_debye.cpp @@ -15,10 +15,9 @@ #include "stdlib.h" #include "pair_lj_cut_coul_debye.h" #include "atom.h" -#include "neighbor.h" +#include "neigh_list.h" #include "force.h" #include "comm.h" -#include "update.h" #include "error.h" using namespace LAMMPS_NS; @@ -31,20 +30,18 @@ PairLJCutCoulDebye::PairLJCutCoulDebye(LAMMPS *lmp) : PairLJCutCoulCut(lmp) {} void PairLJCutCoulDebye::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double factor,phicoul,philj; double r,rinv,screening; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = eng_coul = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; double *q = atom->q; int *type = atom->type; int nlocal = atom->nlocal; @@ -54,19 +51,25 @@ void PairLJCutCoulDebye::compute(int eflag, int vflag) int newton_pair = force->newton_pair; double qqrd2e = force->qqrd2e; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; qtmp = q[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_coul = factor_lj = 1.0; else { diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp index 3050307ead..f43d8d62bf 100644 --- a/src/pair_lj_expand.cpp +++ b/src/pair_lj_expand.cpp @@ -18,9 +18,8 @@ #include "atom.h" #include "comm.h" #include "force.h" -#include "update.h" +#include "neigh_list.h" #include "memory.h" -#include "neighbor.h" #include "error.h" using namespace LAMMPS_NS; @@ -56,37 +55,41 @@ PairLJExpand::~PairLJExpand() void PairLJExpand::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,forcelj,fforce,factor_lj,philj; double r,rshift,rshiftsq; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { diff --git a/src/pair_lj_smooth.cpp b/src/pair_lj_smooth.cpp index 0ee2c06649..5a70395d24 100644 --- a/src/pair_lj_smooth.cpp +++ b/src/pair_lj_smooth.cpp @@ -22,8 +22,7 @@ #include "atom.h" #include "comm.h" #include "force.h" -#include "neighbor.h" -#include "update.h" +#include "neigh_list.h" #include "memory.h" #include "error.h" @@ -66,38 +65,42 @@ PairLJSmooth::~PairLJSmooth() void PairLJSmooth::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r6inv,r,forcelj,fforce,factor_lj,philj; double t,tsq,fskin; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; - // loop over neighbors of my atoms + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; - for (i = 0; i < nlocal; i++) { + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; - - for (k = 0; k < numneigh; k++) { - j = neighs[k]; - + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + if (j < nall) factor_lj = 1.0; else { factor_lj = special_lj[j/nall]; diff --git a/src/pair_morse.cpp b/src/pair_morse.cpp index f09d29c509..66cc36ec01 100644 --- a/src/pair_morse.cpp +++ b/src/pair_morse.cpp @@ -18,9 +18,8 @@ #include "atom.h" #include "comm.h" #include "force.h" -#include "update.h" +#include "neigh_list.h" #include "memory.h" -#include "neighbor.h" #include "error.h" using namespace LAMMPS_NS; @@ -53,36 +52,40 @@ PairMorse::~PairMorse() void PairMorse::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r,dr,dexp,fforce,factor_lj,phi; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp index 744c777952..afd46c6dfd 100644 --- a/src/pair_soft.cpp +++ b/src/pair_soft.cpp @@ -19,8 +19,8 @@ #include "comm.h" #include "force.h" #include "update.h" +#include "neigh_list.h" #include "memory.h" -#include "neighbor.h" #include "error.h" using namespace LAMMPS_NS; @@ -54,11 +54,10 @@ PairSoft::~PairSoft() void PairSoft::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double r,rsq,arg,fforce,factor_lj,philj; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; // set current prefactor // for minimization, set to prestop @@ -78,27 +77,32 @@ void PairSoft::compute(int eflag, int vflag) eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { diff --git a/src/pair_table.cpp b/src/pair_table.cpp index 7972d42db5..f59a20d1ea 100644 --- a/src/pair_table.cpp +++ b/src/pair_table.cpp @@ -22,9 +22,8 @@ #include "pair_table.h" #include "atom.h" #include "force.h" -#include "update.h" #include "comm.h" -#include "neighbor.h" +#include "neigh_list.h" #include "memory.h" #include "error.h" @@ -70,11 +69,10 @@ PairTable::~PairTable() void PairTable::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype,itable; + int i,j,ii,jj,inum,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double fforce,factor_lj,phi,fraction,value,a,b; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; Table *tb; float rsq_single; int *int_rsq = (int *) &rsq_single; @@ -82,27 +80,32 @@ void PairTable::compute(int eflag, int vflag) eng_vdwl = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_lj = 1.0; else { diff --git a/src/pair_yukawa.cpp b/src/pair_yukawa.cpp index b6db7c04e2..f709917477 100644 --- a/src/pair_yukawa.cpp +++ b/src/pair_yukawa.cpp @@ -15,10 +15,9 @@ #include "stdlib.h" #include "pair_yukawa.h" #include "atom.h" -#include "neighbor.h" #include "force.h" #include "comm.h" -#include "update.h" +#include "neigh_list.h" #include "memory.h" #include "error.h" @@ -50,36 +49,40 @@ PairYukawa::~PairYukawa() void PairYukawa::compute(int eflag, int vflag) { - int i,j,k,numneigh,itype,jtype; + int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz; double rsq,r2inv,r,rinv,screening,forceyukawa,fforce,factor_coul,phi; - int *neighs; - double **f; + int *ilist,*jlist,*numneigh,**firstneigh; eng_coul = 0.0; if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; - if (vflag == 2) f = update->f_pair; - else f = atom->f; double **x = atom->x; + double **f = atom->f; int *type = atom->type; int nlocal = atom->nlocal; int nall = atom->nlocal + atom->nghost; double *special_coul = force->special_coul; int newton_pair = force->newton_pair; + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms - for (i = 0; i < nlocal; i++) { + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; - neighs = neighbor->firstneigh[i]; - numneigh = neighbor->numneigh[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; - for (k = 0; k < numneigh; k++) { - j = neighs[k]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; if (j < nall) factor_coul = 1.0; else { diff --git a/src/respa.cpp b/src/respa.cpp index 39a66cb941..3ba4a4f6de 100644 --- a/src/respa.cpp +++ b/src/respa.cpp @@ -255,9 +255,9 @@ void Respa::init() // will delete it at end of run char **fixarg = new char*[4]; - fixarg[0] = "RESPA"; - fixarg[1] = "all"; - fixarg[2] = "RESPA"; + fixarg[0] = (char *) "RESPA"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "RESPA"; fixarg[3] = new char[8]; sprintf(fixarg[3],"%d",nlevels); modify->add_fix(4,fixarg); diff --git a/src/style.h b/src/style.h index 43f44000ca..9cdf05bac7 100644 --- a/src/style.h +++ b/src/style.h @@ -76,16 +76,17 @@ CommandStyle(write_restart,WriteRestart) #endif #ifdef ComputeInclude +#include "compute_attribute_atom.h" #include "compute_centro_atom.h" #include "compute_coord_atom.h" #include "compute_ebond_atom.h" #include "compute_epair_atom.h" -#include "compute_etotal_atom.h" #include "compute_ke_atom.h" #include "compute_pressure.h" #include "compute_rotate_dipole.h" #include "compute_rotate_gran.h" #include "compute_stress_atom.h" +#include "compute_sum_atom.h" #include "compute_temp.h" #include "compute_temp_deform.h" #include "compute_temp_partial.h" @@ -96,16 +97,17 @@ CommandStyle(write_restart,WriteRestart) #endif #ifdef ComputeClass +ComputeStyle(attribute/atom,ComputeAttributeAtom) ComputeStyle(centro/atom,ComputeCentroAtom) ComputeStyle(coord/atom,ComputeCoordAtom) ComputeStyle(ebond/atom,ComputeEbondAtom) ComputeStyle(epair/atom,ComputeEpairAtom) -ComputeStyle(etotal/atom,ComputeEtotalAtom) ComputeStyle(ke/atom,ComputeKEAtom) ComputeStyle(pressure,ComputePressure) ComputeStyle(rotate/dipole,ComputeRotateDipole) ComputeStyle(rotate/gran,ComputeRotateGran) ComputeStyle(stress/atom,ComputeStressAtom) +ComputeStyle(sum/atom,ComputeSumAtom) ComputeStyle(temp,ComputeTemp) ComputeStyle(temp/deform,ComputeTempDeform) ComputeStyle(temp/partial,ComputeTempPartial) @@ -137,6 +139,7 @@ DumpStyle(xyz,DumpXYZ) #ifdef FixInclude #include "fix_add_force.h" +#include "fix_ave_atom.h" #include "fix_ave_force.h" #include "fix_ave_spatial.h" #include "fix_ave_time.h" @@ -186,6 +189,7 @@ DumpStyle(xyz,DumpXYZ) #ifdef FixClass FixStyle(addforce,FixAddForce) +FixStyle(ave/atom,FixAveAtom) FixStyle(aveforce,FixAveForce) FixStyle(ave/spatial,FixAveSpatial) FixStyle(ave/time,FixAveTime) @@ -270,7 +274,9 @@ MinimizeStyle(sd,MinSD) #ifdef PairInclude #include "pair_buck.h" #include "pair_buck_coul_cut.h" +#include "pair_coul_cut.h" #include "pair_hybrid.h" +#include "pair_hybrid_overlay.h" #include "pair_lj_cut.h" #include "pair_lj_cut_coul_cut.h" #include "pair_lj_cut_coul_debye.h" @@ -285,7 +291,9 @@ MinimizeStyle(sd,MinSD) #ifdef PairClass PairStyle(buck,PairBuck) PairStyle(buck/coul/cut,PairBuckCoulCut) +PairStyle(coul/cut,PairCoulCut) PairStyle(hybrid,PairHybrid) +PairStyle(hybrid/overlay,PairHybridOverlay) PairStyle(lj/cut,PairLJCut) PairStyle(lj/cut/coul/cut,PairLJCutCoulCut) PairStyle(lj/cut/coul/debye,PairLJCutCoulDebye) @@ -315,7 +323,7 @@ RegionStyle(sphere,RegSphere) RegionStyle(union,RegUnion) #endif -// style files for optional packages +// style files for standard packages #include "style_asphere.h" #include "style_class2.h" @@ -331,8 +339,7 @@ RegionStyle(union,RegUnion) #include "style_poems.h" #include "style_xtc.h" -//#include "style_extra.h" - -// user add-ons +// user add-ons: individual classes and packages #include "style_user.h" +#include "style_user_packages.h" diff --git a/src/style_kspace.h b/src/style_kspace.h index 52cae87bdb..8c7244afb9 100644 --- a/src/style_kspace.h +++ b/src/style_kspace.h @@ -25,6 +25,7 @@ KSpaceStyle(pppm/tip4p,PPPMTIP4P) #ifdef PairInclude #include "pair_buck_coul_long.h" +#include "pair_coul_long.h" #include "pair_lj_cut_coul_long.h" #include "pair_lj_cut_coul_long_tip4p.h" #include "pair_lj_charmm_coul_long.h" @@ -32,6 +33,7 @@ KSpaceStyle(pppm/tip4p,PPPMTIP4P) #ifdef PairClass PairStyle(buck/coul/long,PairBuckCoulLong) +PairStyle(coul/long,PairCoulLong) PairStyle(lj/cut/coul/long,PairLJCutCoulLong) PairStyle(lj/cut/coul/long/tip4p,PairLJCutCoulLongTIP4P) PairStyle(lj/charmm/coul/long,PairLJCharmmCoulLong) diff --git a/src/style_user.h b/src/style_user.h index b4eeb828b4..cb024f6ee9 100644 --- a/src/style_user.h +++ b/src/style_user.h @@ -11,6 +11,7 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +// add a style class to LAMMPS by adding 2 lines to this file // add new include files in appropriate Include ifdef // add new style keywords and class names in appropriate Class ifdef // see style.h for examples @@ -73,7 +74,7 @@ #endif #ifdef IntegrateClass -#endif +# endif #ifdef KSpaceInclude #endif @@ -85,7 +86,7 @@ #endif #ifdef MinimizeClass -# endif +#endif #ifdef PairInclude #endif diff --git a/src/thermo.cpp b/src/thermo.cpp index 9898059454..33f47619bc 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -120,10 +120,10 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) index_temp = index_press = index_drot = index_grot = -1; internal_drot = internal_grot = 0; - id_temp = "thermo_temp"; - id_press = "thermo_pressure"; - id_drot = "thermo_rotate_dipole"; - id_grot = "thermo_rotate_gran"; + id_temp = (char *) "thermo_temp"; + id_press = (char *) "thermo_pressure"; + id_drot = (char *) "thermo_rotate_dipole"; + id_grot = (char *) "thermo_rotate_gran"; // count fields in line // allocate per-field memory @@ -137,22 +137,22 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) // temperature and pressure always exist b/c Output class created them if (index_drot >= 0) { - create_compute(id_drot,"rotate/dipole",NULL); + create_compute(id_drot,(char *) "rotate/dipole",NULL); internal_drot = 1; } if (index_grot >= 0) { - create_compute(id_grot,"rotate/gran",NULL); + create_compute(id_grot,(char *) "rotate/gran",NULL); internal_grot = 1; } // format strings - format_multi = "---------------- Step %8d ----- " - "CPU = %11.4f (sec) ----------------"; - format_int_one_def = "%8d"; - format_int_multi_def = "%14d"; - format_g_def = "%12.8g"; - format_f_def = "%14.4f"; + format_multi = (char *) "---------------- Step %8d ----- " + "CPU = %11.4f (sec) ----------------"; + format_int_one_def = (char *) "%8d"; + format_int_multi_def = (char *) "%14d"; + format_g_def = (char *) "%12.8g"; + format_f_def = (char *) "%14.4f"; format_int_user = NULL; format_float_user = NULL; @@ -398,17 +398,17 @@ void Thermo::modify_params(int narg, char **arg) if (temperature->igroup != 0 && comm->me == 0) error->warning("Temperature for thermo pressure is not for group all"); - // reset id_pre of pressure to new temp ID + // reset id_pre[0] of pressure to new temp ID // either pressure currently being used by thermo or "thermo_pressure" if (index_press >= 0) { icompute = modify->find_compute(id_compute[index_press]); if (icompute < 0) error->all("Press ID for thermo does not exist"); - } else icompute = modify->find_compute("thermo_pressure"); + } else icompute = modify->find_compute((char *) "thermo_pressure"); - delete [] modify->compute[icompute]->id_pre; - modify->compute[icompute]->id_pre = new char[n]; - strcpy(modify->compute[icompute]->id_pre,arg[iarg+1]); + delete [] modify->compute[icompute]->id_pre[0]; + modify->compute[icompute]->id_pre[0] = new char[n]; + strcpy(modify->compute[icompute]->id_pre[0],arg[iarg+1]); iarg += 2; @@ -427,13 +427,13 @@ void Thermo::modify_params(int narg, char **arg) if (pressure->pressflag == 0) error->all("Thermo_modify press ID does not compute pressure"); - // if id_pre of new pressure is not being computed, add to compute list - // swap it with pressure in list so id_pre will be computed first + // if id_pre[0] of new pressure not being computed, add to compute list + // swap it with pressure in list so id_pre[0] will be computed first // OK to call add_compute with "which" acting as index int which = compute_which[index_press]; int ncompute_current = ncompute; - icompute = add_compute(pressure->id_pre,which); + icompute = add_compute(pressure->id_pre[0],which); if (icompute == ncompute_current) { int iswap = compute_which[index_press]; compute_which[index_press] = compute_which[icompute]; @@ -554,7 +554,6 @@ void Thermo::modify_params(int narg, char **arg) /* ---------------------------------------------------------------------- allocate all per-field memory - allow each c_ID to imply 2 Compute objects (if it has id_pre) ------------------------------------------------------------------------- */ void Thermo::allocate() @@ -577,9 +576,9 @@ void Thermo::allocate() arg_object = new int[n]; ncompute = 0; - id_compute = new char*[2*n]; - compute_which = new int[2*n]; - computes = new Compute*[2*n]; + id_compute = NULL; + compute_which = NULL; + computes = NULL; nfix = 0; id_fix = new char*[n]; @@ -611,9 +610,9 @@ void Thermo::deallocate() delete [] arg_object; for (int i = 0; i < ncompute; i++) delete [] id_compute[i]; - delete [] id_compute; - delete [] compute_which; - delete [] computes; + memory->sfree(id_compute); + memory->sfree(compute_which); + memory->sfree(computes); for (int i = 0; i < nfix; i++) delete [] id_fix[i]; delete [] id_fix; @@ -760,7 +759,7 @@ void Thermo::parse_fields(char *str) // compute value = c_ID, fix value = f_ID, variable value = v_ID // if no trailing [], then arg is set to 0, else arg is between [] // copy = at most 8 chars of ID to pass to addfield - // for compute, if has pre-compute object, first add it to list + // if Compute has pre-computes, first add them to list } else if ((strncmp(word,"c_",2) == 0) || (strncmp(word,"f_",2) == 0) || (strncmp(word,"v_",2) == 0)) { @@ -790,8 +789,10 @@ void Thermo::parse_fields(char *str) if (arg_object[nfield] > 0 && arg_object[nfield] > modify->compute[n]->size_vector) error->all("Thermo compute ID vector is not large enough"); - if (modify->compute[n]->id_pre) - int tmp = add_compute(modify->compute[n]->id_pre,arg_object[nfield]); + if (modify->compute[n]->npre) + for (int ic = 0; ic < modify->compute[n]->npre; ic++) + int tmp = add_compute(modify->compute[n]->id_pre[ic], + arg_object[nfield]); field2object[nfield] = add_compute(id,arg_object[nfield]); addfield(copy,&Thermo::compute_compute,FLOAT); @@ -820,7 +821,7 @@ void Thermo::parse_fields(char *str) add field to list of quantities to print ------------------------------------------------------------------------- */ -void Thermo::addfield(char *key, FnPtr func, int typeflag) +void Thermo::addfield(const char *key, FnPtr func, int typeflag) { strcpy(keyword[nfield],key); vfunc[nfield] = func; @@ -830,13 +831,15 @@ void Thermo::addfield(char *key, FnPtr func, int typeflag) /* ---------------------------------------------------------------------- add compute ID to list of Compute objects to call - if already in list, do not add, just return location, else add to list + return index of where this Compute is in list + if already in list, do not add, just return index, else add to list convert index into which param index = 0 -> scalar, index >= 1 -> vector which = 1 -> scalar only, which = 2 -> vector only, which = 3 -> both + change which param if Compute is in list with different which param ------------------------------------------------------------------------- */ -int Thermo::add_compute(char *id, int index) +int Thermo::add_compute(const char *id, int index) { int icompute; for (icompute = 0; icompute < ncompute; icompute++) @@ -849,6 +852,16 @@ int Thermo::add_compute(char *id, int index) } if (icompute < ncompute) return icompute; + id_compute = (char **) + memory->srealloc(id_compute,(ncompute+1)*sizeof(char *), + "thermo:id_compute"); + compute_which = (int *) + memory->srealloc(compute_which,(ncompute+1)*sizeof(int), + "thermo:compute_which"); + computes = (Compute **) + memory->srealloc(computes,(ncompute+1)*sizeof(Compute *), + "thermo:computes"); + int n = strlen(id) + 1; id_compute[ncompute] = new char[n]; strcpy(id_compute[ncompute],id); @@ -862,7 +875,7 @@ int Thermo::add_compute(char *id, int index) add fix ID to list of Fix objects to call ------------------------------------------------------------------------- */ -int Thermo::add_fix(char *id) +int Thermo::add_fix(const char *id) { int n = strlen(id) + 1; id_fix[nfix] = new char[n]; @@ -875,7 +888,7 @@ int Thermo::add_fix(char *id) add variable ID to list of Variables to evaluate ------------------------------------------------------------------------- */ -int Thermo::add_variable(char *id) +int Thermo::add_variable(const char *id) { int n = strlen(id) + 1; id_variable[nvariable] = new char[n]; @@ -892,7 +905,7 @@ void Thermo::create_compute(char *id, char *cstyle, char *extra) { char **newarg = new char*[4]; newarg[0] = id; - newarg[1] = "all"; + newarg[1] = (char *) "all"; newarg[2] = cstyle; if (extra) newarg[3] = extra; if (extra) modify->add_compute(4,newarg); diff --git a/src/thermo.h b/src/thermo.h index d5e00ae106..e1bf0f22d7 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -100,13 +100,13 @@ class Thermo : protected Pointers { void deallocate(); void parse_fields(char *); - int add_compute(char *, int); - int add_fix(char *); - int add_variable(char *); + int add_compute(const char *, int); + int add_fix(const char *); + int add_variable(const char *); void create_compute(char *, char *, char *); typedef void (Thermo::*FnPtr)(); - void addfield(char *, FnPtr, int); + void addfield(const char *, FnPtr, int); FnPtr *vfunc; // list of ptrs to functions void compute_compute(); // functions that compute a single value diff --git a/src/universe.cpp b/src/universe.cpp index baa1266ecf..6a9d9db0bb 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -26,7 +26,7 @@ using namespace LAMMPS_NS; Universe::Universe(LAMMPS *lmp, MPI_Comm communicator) : Pointers(lmp) { - version = "22 Jun 2007"; + version = (char *) "22 Jun 2007"; uworld = communicator; MPI_Comm_rank(uworld,&me); diff --git a/src/update.cpp b/src/update.cpp index d24d580c66..a3b7879483 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -41,19 +41,16 @@ Update::Update(LAMMPS *lmp) : Pointers(lmp) firststep = laststep = 0; beginstep = endstep = 0; - maxpair = 0; - f_pair = NULL; - unit_style = NULL; set_units("lj"); - str = "verlet"; + str = (char *) "verlet"; n = strlen(str) + 1; integrate_style = new char[n]; strcpy(integrate_style,str); integrate = new Verlet(lmp,0,NULL); - str = "cg"; + str = (char *) "cg"; n = strlen(str) + 1; minimize_style = new char[n]; strcpy(minimize_style,str); @@ -64,8 +61,6 @@ Update::Update(LAMMPS *lmp) : Pointers(lmp) Update::~Update() { - memory->destroy_2d_double_array(f_pair); - delete [] unit_style; delete [] integrate_style; @@ -93,7 +88,7 @@ void Update::init() /* ---------------------------------------------------------------------- */ -void Update::set_units(char *style) +void Update::set_units(const char *style) { // physical constants from: // http://physics.nist.gov/cuu/Constants/Table/allascii.txt @@ -190,7 +185,7 @@ void Update::create_minimize(int narg, char **arg) int Update::memory_usage() { - int bytes = maxpair*3 * sizeof(double); + int bytes = 0; if (whichflag == 0) bytes += integrate->memory_usage(); else if (whichflag == 1) bytes += minimize->memory_usage(); return bytes; diff --git a/src/update.h b/src/update.h index b28c35b279..0373bf6903 100644 --- a/src/update.h +++ b/src/update.h @@ -30,9 +30,6 @@ class Update : protected Pointers { int first_update; // 0 before initial update, 1 after int max_eval; // max force evaluations for minimizer - double **f_pair; // used by pair to compute force & virial - int maxpair; - char *unit_style; class Integrate *integrate; @@ -44,7 +41,7 @@ class Update : protected Pointers { Update(class LAMMPS *); ~Update(); void init(); - void set_units(char *); + void set_units(const char *); void create_integrate(int, char **); void create_minimize(int, char **); int memory_usage(); diff --git a/src/variable.cpp b/src/variable.cpp index e920ad4be1..cb7311647f 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -217,7 +217,7 @@ void Variable::set(char *name, char *value) { char **newarg = new char*[3]; newarg[0] = name; - newarg[1] = "index"; + newarg[1] = (char *) "index"; newarg[2] = value; set(3,newarg); delete [] newarg; @@ -697,28 +697,32 @@ double Variable::evaluate(char *str, Tree *tree) modify->compute[icompute]->init(); // call compute() if index = 0, else compute_vector() - // make pre-call to Compute object's id_pre if it is defined + // make pre-call to Compute object's pre-compute(s) if defined int index = atoi(arg); if (index == 0) { if (modify->compute[icompute]->scalar_flag == 0) error->all("Variable compute ID does not compute scalar info"); - if (modify->compute[icompute]->id_pre) { - int ipre = modify->find_compute(modify->compute[icompute]->id_pre); - if (ipre < 0) error->all("Could not pre-compute in variable"); - answer = modify->compute[ipre]->compute_scalar(); - } + if (modify->compute[icompute]->npre) + for (int ic = 0; ic < modify->compute[icompute]->npre; ic++) { + int ipre = + modify->find_compute(modify->compute[icompute]->id_pre[ic]); + if (ipre < 0) error->all("Could not pre-compute in variable"); + double tmp = modify->compute[ipre]->compute_scalar(); + } answer = modify->compute[icompute]->compute_scalar(); } else if (index > 0) { if (modify->compute[icompute]->vector_flag == 0) error->all("Variable compute ID does not compute scalar info"); if (index > modify->compute[icompute]->size_vector) error->all("Variable compute ID vector is not large enough"); - if (modify->compute[icompute]->id_pre) { - int ipre = modify->find_compute(modify->compute[icompute]->id_pre); - if (ipre < 0) error->all("Could not pre-compute in variable"); - modify->compute[ipre]->compute_vector(); - } + if (modify->compute[icompute]->npre) + for (int ic = 0; ic < modify->compute[icompute]->npre; ic++) { + int ipre = + modify->find_compute(modify->compute[icompute]->id_pre[ic]); + if (ipre < 0) error->all("Could not pre-compute in variable"); + modify->compute[ipre]->compute_vector(); + } modify->compute[icompute]->compute_vector(); answer = modify->compute[icompute]->vector[index-1]; } else error->all("Invalid compute ID index in variable"); diff --git a/src/velocity.cpp b/src/velocity.cpp index 7167c10b2a..138891fc30 100644 --- a/src/velocity.cpp +++ b/src/velocity.cpp @@ -131,9 +131,9 @@ void Velocity::create(int narg, char **arg) int tflag = 0; if (temperature == NULL) { char **arg = new char*[3]; - arg[0] = "velocity_temp"; + arg[0] = (char *) "velocity_temp"; arg[1] = group->names[igroup]; - arg[2] = "temp"; + arg[2] = (char *) "temp"; temperature = new ComputeTemp(lmp,3,arg); tflag = 1; delete [] arg; @@ -215,7 +215,7 @@ void Velocity::create(int narg, char **arg) MPI_Allreduce(&idmax,&idmaxall,1,MPI_INT,MPI_MAX,world); if (idminall != 1 || idmaxall != natoms) { - char *str = "Cannot use velocity create loop all with non-contiguous atom IDs"; + char *str = (char *) "Cannot use velocity create loop all with non-contiguous atom IDs"; error->all(str); } @@ -390,9 +390,9 @@ void Velocity::scale(int narg, char **arg) int tflag = 0; if (temperature == NULL) { char **arg = new char*[3]; - arg[0] = "velocity_temp"; + arg[0] = (char *) "velocity_temp"; arg[1] = group->names[igroup]; - arg[2] = "temp"; + arg[2] = (char *) "temp"; temperature = new ComputeTemp(lmp,3,arg); tflag = 1; delete [] arg; diff --git a/src/verlet.cpp b/src/verlet.cpp index 5d4ff28b87..fe48c8ccd8 100644 --- a/src/verlet.cpp +++ b/src/verlet.cpp @@ -93,21 +93,13 @@ void Verlet::init() // set flags for what arrays to clear in force_clear() // need to clear torques if array exists - // don't need to clear f_pair if atom_style is only granular (no virial) torqueflag = 0; if (atom->torque_flag) torqueflag = 1; - pairflag = 1; - if (strcmp(atom->atom_style,"granular") == 0) pairflag = 0; // orthogonal vs triclinic simulation box triclinic = domain->triclinic; - - // local copies of Update quantities - - maxpair = update->maxpair; - f_pair = update->f_pair; } /* ---------------------------------------------------------------------- @@ -139,6 +131,8 @@ void Verlet::setup() int vflag = virial_style; force_clear(vflag); + if (force->pair) force->pair->compute(eflag,vflag); + if (atom->molecular) { if (force->bond) force->bond->compute(eflag,vflag); if (force->angle) force->angle->compute(eflag,vflag); @@ -146,8 +140,6 @@ void Verlet::setup() if (force->improper) force->improper->compute(eflag,vflag); } - if (force->pair) force->pair->compute(eflag,vflag); - if (force->kspace) { force->kspace->setup(); force->kspace->compute(eflag,vflag); @@ -233,6 +225,12 @@ void Verlet::iterate(int n) force_clear(vflag); timer->stamp(); + + if (force->pair) { + force->pair->compute(eflag,vflag); + timer->stamp(TIME_PAIR); + } + if (atom->molecular) { if (force->bond) force->bond->compute(eflag,vflag); if (force->angle) force->angle->compute(eflag,vflag); @@ -241,11 +239,6 @@ void Verlet::iterate(int n) timer->stamp(TIME_BOND); } - if (force->pair) { - force->pair->compute(eflag,vflag); - timer->stamp(TIME_PAIR); - } - if (force->kspace) { force->kspace->compute(eflag,vflag); timer->stamp(TIME_KSPACE); @@ -305,23 +298,6 @@ void Verlet::force_clear(int vflag) torque[i][2] = 0.0; } } - - // clear f_pair array if using it this timestep to compute virial - - if (vflag == 2 && pairflag) { - if (atom->nmax > maxpair) { - maxpair = atom->nmax; - memory->destroy_2d_double_array(f_pair); - f_pair = memory->create_2d_double_array(maxpair,3,"verlet:f_pair"); - update->maxpair = maxpair; - update->f_pair = f_pair; - } - for (i = 0; i < nall; i++) { - f_pair[i][0] = 0.0; - f_pair[i][1] = 0.0; - f_pair[i][2] = 0.0; - } - } } /* ---------------------------------------------------------------------- diff --git a/src/verlet.h b/src/verlet.h index f63cf539f3..a0c31dbd7b 100644 --- a/src/verlet.h +++ b/src/verlet.h @@ -35,9 +35,7 @@ class Verlet : public Integrate { int *next_fix_virial; // next timestep they need it int triclinic; // 0 if domain is orthog, 1 if triclinic - int pairflag,torqueflag; // arrays to zero out every step - int maxpair; // local copies of Update quantities - double **f_pair; + int torqueflag; // arrays to zero out every step void force_clear(int); int fix_virial(int);